security-review — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited security-review (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
A bulleted imperative like {match} tells the agent to never reveal, disclose, or mention something to the user. Used adversarially it can instruct the agent to hide its tool calls or lie about what it did — stripping the transparency a user relies on to trust the agent.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
@rules/php/core-standards.mdc@rules/php/dependency-selection.mdc — when the audit recommends replacing a vulnerable package with a hardened alternative, run the Activity gate + Compatibility gate on the proposed replacement before recommending the swap. Never trade a vulnerable-but-maintained package for an archived / abandoned / branch-pinned one in the name of security.@rules/code-review/general.mdc@rules/security/backend.mdc@rules/code-review/frontend.mdc@rules/code-review/mobile.mdc@rules/laravel/laravel.mdc, @rules/laravel/architecture.mdc, @rules/laravel/filament.mdc, and @rules/laravel/livewire.mdc@skills/pr-summary/SKILL.md, it follows the language of the source assignment. CVE / CWE / OWASP identifiers and code identifiers stay verbatim regardless of the surrounding prose language.git add, git commit, git push, git reset, git checkout -- …, etc.). Switching to the relevant branch and git pull to read the latest diff are allowed; mutating the working tree or pushing to the remote is not. Output is the audit report only.Perform a focused security review with emphasis on:
Avoid generic best-practice noise.
rand(), timestamps) where a secret is requiredHttpOnly, Secure, SameSite missing on auth cookies (cross-check @rules/security/backend.md HTTP Security headers and Cookies)DES); passwords not hashed with the platform's adaptive hash (bcrypt / argon2 / Laravel Hash)rand() / mt_rand() / uniqid() instead of random_bytes() / Str::random()messages() / attributes(), exception messages reaching JSON / Inertia / Blade responses, Notification subject and body, Mailable bodies, API error envelopes, flash messages, __() / trans() / Lang::get() / @lang / t() / i18next.t() calls across every locale shipped by the project — every key under lang/, resources/lang/, translations/, and locale *.json / *.po / *.mo files) against @rules/security/backend.md Safe Validation & Error Messages (and @rules/security/frontend.md / @rules/security/mobile.md for the equivalent client surfaces). Flag — and rewrite in the Suggested Fix — any wording that (a) distinguishes which auth factor failed (email vs password vs lock vs 2FA vs verification), (b) confirms a resource exists to an unauthorized caller (replace with the project's generic 404 envelope), (c) interpolates the rejected user input verbatim into the message, (d) reveals stack traces / file paths / framework versions / fully-qualified class names / DB table or column names / SQL fragments / queue or cache driver identifiers, or (e) leaks proximity to the password / token policy rule beyond the rule the user can read. Translation drift — a translated locale reintroducing identity-revealing wording the source removed — is the same finding evaluated per locale. Severity: Critical on auth / password-reset / sign-up / authorization surfaces (directly exploitable for enumeration); Medium elsewhere. Schema-level validation that does not leak existence ("The age must be at least 18.") is not a finding.file://, gopher://, etc.)@skills/code-review/SKILL.md — do not duplicate it here.Walk every line the diff adds or modifies in application code, shell / deploy / CI scripts, composer.json / package.json script hooks, and installer hooks against @rules/security/backend.md Malicious Code & Supply-Chain Indicators (and the frontend / mobile mirrors for client surfaces). Raise a finding on each indicator:
curl -s / wget -q fetching a payload, especially piped to an interpreter (| sh, | bash, | php).curl -k / --insecure, CURLOPT_SSL_VERIFYPEER => false, Guzzle 'verify' => false, NODE_TLS_REJECT_UNAUTHORIZED=0, trust-all certificate managers.2>/dev/null / &>/dev/null on a security-relevant command, @-suppressed calls, error_reporting(0), empty catch {}./tmp / hidden dot-files combined with & / nohup / setsid / disown / detached proc_open.Severity: Critical when the indicator maps to active RCE / MITM / persistence (silent fetch piped to a shell, TLS off on a credential request, both halves of the dropper pattern); High otherwise. Provide the four reproducer fields per the Critical / High requirement.
TYPE / TRANSPORT layer (this section owns the accept decision):
evil.php.jpg), path traversal in filename, executability in webrootScope boundary: This section owns the TYPE / TRANSPORT surface (accept decision). The file CONTENT / RENDER surface (active content executed when the file's bytes, name, or metadata are later rendered or served) is owned by @rules/security/backend.md Malicious File Upload Content (issue #680) — raise one finding per violation, never both. A single upload sink that fails both surfaces produces the type/transport finding for the accept decision and the content/render finding for the output decision, on distinct lines; never two findings for the same line.CONTENT / RENDER layer (cross-check @rules/security/backend.md Malicious File Upload Content (issue #680)):
<script> / on* handlers served inline=, +, -, @, \t, \r)nosniff / CSPContent-Disposition: attachment or X-Content-Type-Options: nosniff on upload-serving endpointsWalk every code path the diff adds or modifies that persists a user-controlled string to the database — Eloquent create() / update() / fill() / save() / mass assignment, query-builder insert() / update(), raw column writes, and the FormRequest / Data Validator feeding them — against @rules/security/backend.md Hidden / Invisible Characters in Stored Fields (and the frontend / mobile mirrors). Raise a finding when a user-controlled string is written to a column without NFC normalization and invisible-character handling:
U+200B–U+200D, U+2060, U+FEFF, U+00AD, U+180E (uniqueness / search / length-check bypass, data smuggling past moderation).U+202A–U+202E, U+2066–U+2069 (spoofed render of a stored name / comment / filename; the persisted analogue of CVE-2021-42574).U+0000–U+0008, U+000B, U+000C, U+000E–U+001F, U+007F–U+009F (NUL truncation; log / terminal / CRLF injection when the value is later emitted).The Suggested Fix normalizes to NFC and strips / rejects the disallowed ranges at the input boundary (a reusable validation rule, a Data Validator, or a central attribute cast — never ad-hoc per call site), so the stored bytes are clean for every later consumer; identity-sensitive fields add a single-script / confusable check before the uniqueness lookup. Severity: Critical when the field drives a security decision (authentication identifier, authorization key, allow / deny list, identity uniqueness, financial reference); Medium for general user-content fields. Scope boundary — this owns the stored byte content (INPUT / STORAGE); output encoding (XSS) and file-content render (issue #680) stay with their own rules, one finding per surface.
composer.lock, composer audit)@rules/php/core-standards.mdc, @rules/security/backend.mdc, and, for Laravel projects, @rules/laravel/architecture.mdc. Use n/a — <reason> only when the fix is purely configurational (env var, web-server header) and is described in the Recommended Fix narrative.These fields exist so @skills/process-code-review/SKILL.md can turn each finding into a regression test and apply the fix without re-deriving the attack vector. Medium and Low findings may omit them when no behavior change is implied.
Use the template defined in templates/audit-report.md.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.