Protecting AI agent code execution

Coding agents now write code and run it in a loop. The dangerous part is rarely a subtle bug — it is a construct that should never execute: shell interpolation, eval, unsafe deserialization, hardcoded secrets, or an unvalidated file write. This guide lists the patterns the ScanPay engine flags, and how to gate execution with a deterministic check.

Why deterministic scanning

The 10 patterns that matter most

  1. Shell execution with interpolation — os.system(user_input), subprocess(..., shell=True). Fix: argument lists, no shell, allowlists.
  2. Dynamic evaluation — eval, exec, new Function. Fix: never evaluate untrusted text.
  3. Unsafe deserialization — pickle.loads, yaml.load without SafeLoader. Fix: safe formats and loaders.
  4. Hardcoded secrets — API keys or private keys committed in source. Fix: environment/secret stores, rotate.
  5. Path traversal — open(os.path.join(base, user)) without normalisation. Fix: resolve and confine paths.
  6. Command injection via templates — f-strings into shell strings. Fix: parameterisation.
  7. Insecure network calls — disabled TLS verification. Fix: verify certificates.
  8. Prototype pollution (JS/TS) — recursive merge of untrusted objects. Fix: null-prototype objects, key allowlists.
  9. Dangerous file permissions — world-writable files, chmod 777. Fix: least privilege.
  10. Unbounded resource use — unbounded loops/allocations on input. Fix: limits and timeouts.

ScanPay ships 45 engine rules across Python and JavaScript/TypeScript covering these and more — each with severity, category and remediation in the rule catalog.

Gating execution with ScanPay

curl -X POST https://scanpay-edge.alextaghiashvili.workers.dev/api/v1/quick \
  -H 'Content-Type: application/json' \
  -d '{{"source_code":"import os; os.system(input())","language":"python"}}'
# unpaid call returns the x402 payment-required challenge; retry with PAYMENT-SIGNATURE

ScanPay is pay-per-call only: $0.001 quick verdict, $0.05 full scan, $10 deep report, or a $5 prepaid pack of 200 scans. Paid over x402 in USDC on Base or Solana, or directly on-chain with the transaction hash. See llms.txt for the full API guide.

Integration pattern

# pseudo-code
findings = scanpay.scan(code, language)
if any(f.severity in ("critical", "high") for f in findings):
    block_execution(findings)
else:
    run_in_sandbox(code)

Scan before execution, block on critical/high, and keep the source hash for the audit trail.

← ScanPay service