Arbitrary Code Execution via `eval()` with Dynamic String Concatenation
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
Research direction
Start with skills/cloud/apigee-agent-gateway-governance/scripts/assess_integration.sh, especially the jqf() definition at lines 163–171 and its call at lines 479–480. Trace how CACHE_INDEX_ID reaches the Python expression and review ways to pass it as data instead of executable code. Done means the index name cannot inject Python through this path and the JSON lookup still returns the expected dimensions.
Written by the indexing model from the issue text.
Description
Arbitrary Code Execution via eval() with Dynamic String Concatenation
- Severity: High
- Vulnerability Type: Code Injection (CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code)
- Affected File:
skills/cloud/apigee-agent-gateway-governance/scripts/assess_integration.sh(Lines 163–171, 479–480)
Description
The shell utility function jqf() is designed to extract JSON properties without requiring a native jq binary by spawning a Python inline script that executes eval(sys.argv[1]):
jqf() { # jqf <json> <python-expr over d> -- no jq dependency
python3 -c '
import json,sys
try: d=json.loads(sys.stdin.read() or "{}")
except Exception: d={}
try: print(eval(sys.argv[1]))
except Exception: print("")
' "$1" 2>/dev/null || true
}
In lines 479–480 of the same script, the dynamically resolved shell variable CACHE_INDEX_ID is interpolated directly into the Python expression using string concatenation:
CACHE_DIMS="$(jqf 'next((str(i.get("metadata",{}).get("config",{}).get("dimensions","")) for i in d if i["name"].endswith("'"$CACHE_INDEX_ID"'")), "")' <<<"$IDX_JSON")"
Impact
Because $CACHE_INDEX_ID is concatenated directly into the Python code string without escaping or input validation, any single quote (') present in the index identifier breaks out of the string boundary. This allows arbitrary Python code execution under the privileges of the script runner when processing untrusted, malformed, or hostile index names.
Recommended Remediation
- Eliminate
eval(): Replace the dynamic evaluation with safe dictionary lookups passed via explicit arguments or environment variables. - Dedicated CLI JSON Parsing: If
jqis unavailable, write a dedicated, parameter-safe Python helper script that parses JSON paths without executing arbitrary Python statements:
jqf_safe() {
python3 -c '
import json, sys
try:
data = json.load(sys.stdin)
target_id = sys.argv[1]
for item in data:
if item.get("name", "").endswith(target_id):
print(item.get("metadata", {}).get("config", {}).get("dimensions", ""))
break
except Exception:
pass
' "$CACHE_INDEX_ID" <<<"$IDX_JSON"
}
- Dominant language
- Python
- Stars
- 23.1k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
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 google/skills
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 79/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Document registry default vs revision actually loaded by an agentMay be free again A pull request for this issue was closed without being merged. Openenhancement
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Similar issues
-
namespace
Difficulty 1/5 Under an hour Newbie friendliness 68/100
EclipseFdn/open-vsx.org#15604 ·
Maintainers usually reply within 1 day
-
app: scripts severity: low status: backlog type: bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
netbox-community/netbox-scripts#164 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Maintainers usually reply within 5 days
-
Public function to read participants.tsvPossibly taken @bruAristimunha claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 1/5 1-3 hours Newbie friendliness 85/100
huggingface/tau#799 ·
Maintainers usually reply within 2 days