Security audit
ONLY when user explicitly requests: security audit, vulnerability scan, or penetration test review. NOT for regular feature work.From its SKILL.md
npx -y skills add event4u-app/agent-config --skill security-auditAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.2 KB, ~1.8k tokens by cl100k_base, as published. Nobody here has run it
security-audit
Mission
Find real security vulnerabilities in code before they are exploited. This skill is proactive — it audits code for security weaknesses, not just responds to incidents.
For writing secure code patterns (policies, auth, CSRF), use the security skill instead.
When to use
Use this skill when:
- Auditing a codebase or module for security risks
analysis-autonomous-moderoutes here after detecting risky patterns- Reviewing code that handles user input, authentication, or authorization
- Checking for vulnerabilities before a release or deployment
Do NOT use when:
- Writing new auth/policy code — route to
security - Hunting for functional bugs — route to
bug-analyzer(proactive mode) - Investigating performance — route to
performance-analysis - You need a pre-implementation threat model for a new feature — route to
threat-modeling - You need end-to-end authorization analysis for one route/action — route to
authz-review
Procedure: Security audit
0. False-positive gate — restate the claim before reporting
Before any finding enters the report, restate it as one falsifiable sentence naming all three of:
- Privilege level — what access the attacker already has (anonymous, authenticated user, tenant admin, CI runner).
- Execution context — where the vulnerable code runs (request handler, queue worker, sandboxed template, build step).
- Attacker precondition — the concrete state or input the attacker must control to trigger it.
If any of the three cannot be named concretely, the item is not a finding yet — trace further or drop it with a one-line reason.
Rationalizations to Reject:
| Rationalization | Reality |
|---|---|
| "It looks dangerous" | Pattern-recognition is not analysis — trace the full data flow from entry to sink first |
| "This is clearly critical" | Complete a devil's-advocate pass — models systematically overrate severity |
| "Report it just in case" | Over-reporting erodes trust; an unverifiable finding is noise, not diligence |
| "Same pattern as a known CVE" | Same pattern ≠ same preconditions — verify the preconditions hold in THIS codebase |
Standard vs. Deep verification routing:
- Standard — traced data flow + all three claim elements named → report with the normal field list.
- Deep — severity would be High/Critical, OR the precondition chain crosses a trust boundary you did not personally trace → run a devil's-advocate pass first: actively try to refute the finding (existing middleware? framework default? type system? config?). Report only what survives; findings the pass killed are listed one-line under Rejected candidates so the triage is auditable.
1. Map attack surface
Identify all entry points where untrusted data enters:
- HTTP request parameters, headers, cookies
- File uploads
- API payloads (JSON, XML, form data)
- Webhook callbacks
- Queue job payloads from external sources
- Import files (CSV, Excel, XML)
- URL path segments and query strings
2. Trace trust boundaries
For each entry point, trace where user input flows:
User Input → Controller → Validation → Service → DB/File/External
↓ ↓ ↓
Is it sanitized? Complete? Used safely?
3. Check vulnerability categories
| Category | What to look for |
|---|---|
| SQL Injection | Raw queries with concatenation, missing parameter binding |
| XSS | Unescaped template output (Blade {!! !!}, JSX dangerouslySetInnerHTML, Jinja ` |
| CSRF | Missing middleware, API endpoints without token verification |
| Auth bypass | Missing policy checks, broken gate logic, withoutMiddleware() |
| IDOR | Direct object access without ownership verification |
| Mass assignment | Missing $fillable/$guarded, request()->all() in create/update |
| File upload | Missing type validation, path traversal, executable uploads |
| SSRF | User-controlled URLs passed to HTTP client |
| Deserialization | Unserializing user input, unsafe queue payloads |
| Secret exposure | Hardcoded credentials, secrets in logs, .env in public dir |
| Rate limiting | Missing throttle on auth endpoints, password reset, API |
| Header injection | User input in response headers, email headers |
| Insecure defaults / fail-open | Guards that allow on error (catch { return true } in an authz check), default-allow matchers, debug mode defaulting on, permissive CORS/verify=false fallbacks, feature flags whose missing value grants access |
Worked example (fail-open): if (!$gate->check($user)) { … } wrapped in a
try/catch that logs and continues fails open — an exception in the gate
grants access. Finding shape: Category Insecure defaults, Evidence the
catch block file:line, Fix fail closed — rethrow or deny on gate error.
4. Framework-specific checks
→ Laravel-specific checks: see laravel § Security audit checks.
5. Dependency audit
- Check
composer.lockfor known vulnerable packages - Check
package-lock.jsonfor frontend vulnerabilities - Identify outdated packages with known CVEs
- Check if security patches are available
Output format
- Emit one entry per vulnerability using the field list below; one finding = one block, never merge.
- Category must map to an OWASP Top 10 (or LLM Top 10) bucket; Severity must use Low / Medium / High / Critical with a single Exploitability tag.
- Close with a Recommended Fix Order ranked by exploitability × blast radius and tag each line with Confidence.
For each vulnerability:
- Vulnerability: concise title
- Category: OWASP category (Injection, Broken Auth, etc.)
- Location: file and line
- Severity: Low / Medium / High / Critical
- Exploitability: How easy to exploit (trivial / requires auth / complex)
- Impact: What an attacker could achieve
- Evidence: code reference showing the weakness
- Fix: concrete mitigation
- Confidence: Low / Medium / High
After the findings, add a Rejected candidates section: one line per look-dangerous-but-benign pattern the Step-0 gate killed, with the traced reason ("raw SQL string is a static migration constant — no user input reaches it"). An audit that rejects nothing has usually skipped the gate.
Integration with other skills
- analysis-autonomous-mode — routes here when security concerns are detected
- security — complementary: security is about writing secure code, this is about finding holes
- universal-project-analysis — provides context about packages and framework usage
- bug-analyzer — some bugs have security implications (chain when found)
- untrusted-input-defense / lethal-trifecta-guard (rules) — prompt-injection / agent-config defense; consult when the audited code ingests untrusted content or wires an autonomous egress path
Gotcha
- Don't report theoretical vulnerabilities without a concrete attack vector — false positives erode trust.
- The model tends to flag framework-handled security as issues (e.g., Laravel's CSRF or Rails'
protect_from_forgeryis already handled). - Always check if a finding is already mitigated by middleware or configuration before reporting it.
Do NOT
- Do NOT report theoretical risks that require impossible preconditions
- Do NOT ignore user input flows — always trace from entry to usage
- Do NOT assume frameworks handle everything — verify middleware and config
- Do NOT confuse code quality issues with security vulnerabilities
- Do NOT skip dependency checking — known CVEs are real risks
See also
docs/threat-model.md— package attack surface and trust boundary documentation.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.