aider/devin skills still build save-result/add commands from unescaped free text (RCE via $(...) in double quotes)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
Start with tools/skillgen/fragments/core/aider.md and tools/skillgen/fragments/core/devin.md, reviewing the three save-result blocks and the /graphify add ingest() call in each. Compare the existing file-based fixes and disk-platform add flow before designing quoted-heredoc and JSON-file handling. Done means all six call sites avoid shell or Python interpolation of free text, generated expected/ artifacts are updated, and the monolith-roundtrip predicates still pass.
Written by the indexing model from the issue text.
Description
Summary
PR #3439/#3442 fixed the disk-write-capable skill platforms so graphify save-result/graphify add build their arguments from a file instead of substituting free text (a question, an LLM-generated answer, a scraped page's author/contributor name) directly into a shell command or Python source string. The aider and devin monolith skills, which have no separate file-write tool and instead run everything through $(cat graphify-out/.graphify_python) -c "..." / inline shell commands, were not covered by that fix and still use the vulnerable pattern.
Evidence (current v8)
tools/skillgen/fragments/core/aider.md (and the byte-identical pattern in tools/skillgen/fragments/core/devin.md, lines shifted):
-
L1045, L1120, L1186 — three separate
save-resultinvocations built as a single shell command with the free-text answer substituted directly into a double-quoted argument:$(cat graphify-out/.graphify_python) -m graphify save-result --question "QUESTION" --answer "ANSWER" --type query --nodes NODE1 NODE2Bash still performs
$(...)and backtick command substitution inside double quotes. IfANSWER(an LLM-generated answer, which can echo content from an untrusted source such as a fetched webpage) is substituted verbatim and contains$(some command), that command executes when the agent runs the line. This is not a corruption risk like single-quote breakout, it is a direct RCE vector, and it defeats the exact protection--answer-file/--question-file/--nodes-file(already shipped for disk-capable platforms in #3439) exists to provide. -
L1202 (aider.md) / L1334 (devin.md) — the
/graphify addflow builds a Python source string with the URL/author/contributor substituted into single-quoted Python literals:out = ingest('URL', Path('./raw'), author='AUTHOR', contributor='CONTRIBUTOR')A value containing an embedded
'(or\) breaks out of the string literal, letting an attacker-controlled URL, author, or contributor field (again, free text that can originate from a fetched page) inject arbitrary Python that then runs inside the-cscript — the exact "building generated code from unsanitized free text" class of bug #3439 targeted, just via a Python string literal instead of a JSON payload.
Why this needs its own fix, not a quick patch
Closing this properly needs a mechanism that works for a platform with only raw shell/python execution (no dedicated file-write tool), across all six affected call sites (3 save-result blocks x 2 files, plus the ingest() call x 2 files). The shape that avoids re-introducing the same risk: a quoted heredoc (<<'EOF' ... EOF, whose body bash does not expand at all) to get the free text onto disk without any shell interpretation, then dispatch through the already-existing --question-file/--answer-file/--nodes-file flags for save-result, and a JSON payload file (mirroring the disk-platform add fix) read via stdin or a temp file for ingest(). That is a real design/rewrite across two ~1300+ line monolith fragments plus their generated expected/ artifacts and monolith-roundtrip predicates, not a one-line fix, so it deserves its own dedicated PR with careful review rather than being folded into #3442's narrower scope.
Suggested fix direction
- For
save-result: replace each inline--question "QUESTION" --answer "ANSWER"shell line with instructions to write QUESTION/ANSWER/NODES to temp files via a quoted heredoc (cat > "$f" <<'GRAPHIFY_EOF' ... GRAPHIFY_EOF, single-quoted delimiter so bash performs zero expansion on the body), then invokesave-result --question-file "$qf" --answer-file "$af" --nodes-file "$nf". - For
/graphify add: same heredoc technique to write a JSON payload file, then have the-cscript read andjson.load()it (mirroring the already-fixed disk-platformadd-watch.mdflow) instead of embedding values as Python literals.
Filed as a standalone issue per triage of PR #3442's review — the fix there addressed only the two comments actually flagged on that PR (cli.py file-read error handling, and the same-class doc wording gap in the disk-platform add-watch.md), not this pre-existing, broader gap discovered while investigating it.
- Dominant language
- Python
- Stars
- 124k
- Forks
- 11.9k
- PR merge metrics
- No merged PRs in 30d
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Graphify-Labs/graphify
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
Graphify-Labs/graphify#3763 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Graphify-Labs/graphify#3611 · 1 comment ·
Maintainers usually reply within 1 day
-
Nix supportOpen
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Graphify-Labs/graphify#3193 · 2 reactions ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
Graphify-Labs/graphify#2871 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Graphify-Labs/graphify#2865 ·
Maintainers usually reply within 1 day
All issues in Graphify-Labs/graphify
Similar issues
-
Agentic
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Imbad0202/academic-research-skills#979 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
reflex-dev/reflex#7561 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
prometheus-community/ansible#906 · 2 comments ·