fix: replace python3 with bun/jq in shared scripts (#1697) (#1701)

* fix: replace python3 with bun/jq in shared scripts (#1697)

Replace python3 -c inline scripting with jq (preferred) and bun -e
fallbacks per project policy. Python is not a declared dependency;
jq and bun are the project's scripting runtimes.

Changes:
- shared/common.sh: Replace all 9 python3 -c calls with jq/bun -e
- shared/key-request.sh: Replace all 4 python3 -c calls with jq/bun -e
- check_python_available: Now checks for jq or bun instead of python3
- Update test expectations for JS semantics (true/false vs True/False,
  bracket access vs .get(), null handling)

Fixes #1697
Agent: security-auditor
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: replace eval() with safe property access, rename check_python_available

Security: eliminate eval() from _extract_json_field() — use regex-based
bracket-notation parser to traverse JSON paths safely. The function now
extracts ['key'] and [N] segments from the expression string and
iterates through them, preventing arbitrary code execution.

Also rename check_python_available() → check_json_processor_available()
throughout the codebase (shared/common.sh, local/lib/common.sh, and
tests) since the function now checks for jq/bun, not python3.

Agent: security-auditor
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
A 2026-02-22 09:57:49 -08:00 committed by GitHub
parent 945b60317c
commit e28deca91b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 232 additions and 162 deletions

View file

@ -357,12 +357,12 @@ describe("_multi_creds_validate", () => {
});
// ============================================================================
// check_python_available
// check_json_processor_available
// ============================================================================
describe("check_python_available", () => {
describe("check_json_processor_available", () => {
it("should return 0 when python3 is available", () => {
const result = runBash("check_python_available");
const result = runBash("check_json_processor_available");
// python3 should be available in CI/test environment
expect(result.exitCode).toBe(0);
});
@ -371,20 +371,20 @@ describe("check_python_available", () => {
const result = runBash(`
PATH=/nonexistent
hash -r
check_python_available 2>/dev/null
check_json_processor_available 2>/dev/null
`);
expect(result.exitCode).toBe(1);
});
it("should show installation instructions when python3 is missing", () => {
it("should show installation instructions when jq and bun are missing", () => {
const result = runBash(`
PATH=/nonexistent
hash -r
check_python_available 2>&1
check_json_processor_available 2>&1
`);
expect(result.stdout).toContain("Python 3 is required");
expect(result.stdout).toContain("jq or bun is required");
expect(result.stdout).toContain("sudo apt-get");
expect(result.stdout).toContain("brew install python3");
expect(result.stdout).toContain("brew install jq");
});
});