agentic/code/frameworks/security-engineering/skills/banned-api-audit/SKILL.md
Scan source code for banned APIs/forbidden functions per project banlist; report violations with paths, line numbers, and recommended replacements
npx skillsauth add jmagly/aiwg banned-api-auditInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are the Banned API Auditor — scan source code for prohibited functions and APIs declared in the project banlist, report violations with full context, and exit with a CI-suitable status code.
"Eliminate CVE classes by construction." Banning a dangerous API is cheaper than vigilance. The audit makes the ban enforceable: every CI run rejects any new occurrence; existing violations are tracked until remediated or explicitly excepted.
--starter <language> (optional)Use a bundled starter banlist instead of (or in addition to) the project banlist. Useful for a first-time audit before the project has its own banned-apis.yaml. Valid: c, cpp, python, node, go, rust.
--fail-on-violation (optional)Exit non-zero when ANY violation is found. Default: exit 0 always (report-only mode for first runs and migration audits).
--paths <glob>... (optional)Limit the scan to these paths. Overrides paths: declarations in the banlist. Useful for scoped PR audits.
--format text|json|both|sarif (default both)text to stdout, json to .aiwg/security/banned-api-audit/, or both.
--sarif (optional)Also emit SARIF 2.1.0 to .aiwg/security/banned-api-audit/ for code-scanning ingest.
Look for .aiwg/security/banned-apis.yaml.
If --starter <lang> is set, merge the bundled starter into the active banlist (project banlist wins on pattern conflict).
If neither exists, emit a guided message:
No banlist found. Bootstrap with:
aiwg run skill banned-api-audit -- --starter c
Or seed your own at .aiwg/security/banned-apis.yaml
Default exclusions (always applied unless --paths overrides):
test/**, tests/**, **/*_test.*, **/*.test.*vendor/**, node_modules/**, target/**, dist/**, build/**.git/**, .aiwg/**, .claude/**, .codex/**, .factory/**Project banlist paths: declarations narrow further (e.g., src/** only).
For each (language, pattern) pair:
# Word-boundary literal pattern
rg -n --type <lang> -w '<pattern>' <paths>
# Regex pattern (when prefixed re:)
rg -n --type <lang> '<regex>' <paths>
Language → ripgrep --type mapping:
c → ccpp → cpppython → pynode → js,ts,tsx,jsxgo → gorust → rustFor each candidate violation, check the source line and the preceding 2 lines for:
AIWG-allow:banned-apis reason="..."
When present, classify as excepted (not a violation). Record the reason in the report so security reviewers can grep all exceptions periodically.
Text report format:
Banned API Audit — 2026-05-21T17:30:00Z
Banlist: .aiwg/security/banned-apis.yaml (24 patterns across 3 languages)
Paths: src/, lib/
Excluded: test/, tests/, vendor/, node_modules/
VIOLATIONS (3)
src/auth/token.c:42: strcpy(buf, user_input);
pattern: strcpy (language: c)
reason: Unbounded copy — buffer overflow vector
replacement: strncpy_s, strlcpy, or snprintf with bounds
src/parser/json.c:118: sprintf(out, "%s/%s", base, path);
pattern: sprintf (language: c)
reason: Unbounded format expansion — overflow + format-string risk
replacement: snprintf with explicit buffer size
src/util/legacy.py:7: user = pickle.loads(payload)
pattern: re:pickle\.loads?\b (language: python)
reason: Arbitrary code execution on untrusted input
replacement: json, msgpack, or signed pickle with integrity check
EXCEPTIONS (1)
src/compat/curses_wrapper.c:33: char *tok = strtok(buf, " ");
pattern: strtok
reason: curses interop requires strtok per legacy API contract
SUMMARY
Violations: 3
Exceptions: 1
Patterns: 24
Files scanned: 184
JSON report (machine-readable, suitable for SARIF conversion or CI dashboard ingest):
{
"schemaVersion": "1",
"auditedAt": "2026-05-21T17:30:00Z",
"banlistPath": ".aiwg/security/banned-apis.yaml",
"patterns": 24,
"filesScanned": 184,
"violations": [
{
"file": "src/auth/token.c",
"line": 42,
"column": 5,
"match": "strcpy(buf, user_input);",
"pattern": "strcpy",
"language": "c",
"reason": "Unbounded copy — buffer overflow vector",
"replacement": "strncpy_s, strlcpy, or snprintf with bounds",
"severity": "HIGH"
}
],
"exceptions": [ /* same shape, plus exceptionReason */ ]
}
0 — no violations, OR violations present but --fail-on-violation not set1 — banlist missing AND no --starter flag2 — violations present AND --fail-on-violation set3 — ripgrep not installed or other tooling failureGitea Actions:
- name: Banned-API audit
run: aiwg run skill banned-api-audit -- --fail-on-violation
GitHub Actions:
- name: Banned-API audit
run: aiwg run skill banned-api-audit -- --fail-on-violation
Bundled at banlists/:
c.yaml — C dangerous functions (strcpy, sprintf, gets, strtok, atoi)cpp.yaml — C++ overlay (auto_ptr, gets, strcpy)python.yaml — eval, exec, pickle.loads, subprocess shell=Truenode.yaml — eval, new Function, child_process.execgo.yaml — shell-string commands, weak hashes, HTML templating footgunsrust.yaml — unsafe/transmute/unwrap review gates, shell-string commandsUsers seed their project banlist via --starter <lang> and customize.
The CRITICAL applied-cryptography rules (no-unauthenticated-encryption, no-adhoc-kdf, no-key-reuse-across-purposes) are enforced separately by their own audit paths. This skill does not replace them; it complements them with HIGH-severity language-level policy.
Cycle 2 adds:
scripts/audit.sh / scripts/audit.mjs reference implementation.schema.json documenting the banlist YAML shape.0 clean/report-only, 1 banlist/schema problem, 2 violations with --fail-on-violation, 3 tooling failure..aiwg/security/curl-checklist-gap-analysis.md row 2 — Audit contextdata-ai
Report which research-corpus radar sidecars are overdue for refresh. Computes staleness (days since last refresh vs the cadence window) for every radar, sorted most-overdue-first. Runs via `aiwg corpus radar-status`.
data-ai
Aggregate research-corpus radar sidecars into a corpus or per-cluster freshness report — totals, overdue count, per-cluster / per-GRADE / per-trajectory breakdowns, an overdue table, and per-radar rationale snippets. Runs via `aiwg corpus radar-report`.
testing
Scaffold radar/freshness sidecars for research-corpus REFs. Pulls title/authors from the citation sidecar and GRADE from the analysis doc, defaults the refresh cadence from GRADE and the cluster from a corpus-local map, and stamps documentation/radar/REF-XXX-radar.md. Runs via `aiwg corpus radar-init`.
data-ai
Compute an entity's publication trajectory — per-year paper counts, topic drift, hot-streak detection (≥3 consecutive A-grade years), and career phase. Runs via `aiwg corpus profile-temporal`.