plugins/lisa-copilot/skills/lisa-security-review/SKILL.md
Security review methodology. STRIDE threat modeling, OWASP Top 10 vulnerability checks, auth/validation/secrets handling review, and mitigation recommendations.
npx skillsauth add codyswanngt/lisa lisa-security-reviewInstall 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.
Identify vulnerabilities, evaluate threats, and recommend mitigations for code changes.
Severity is earned, not pattern-matched. Every security-shaped finding is classified mechanically, before it is written up:
| Field | What it holds |
|-------|---------------|
| reproducer | an evidence ref of a kind that reaches the claim's boundary, or none |
| impact | a bounded impact/exploitability statement (who can do what, to what data, under what preconditions), or unproven |
| reason | one line saying why the finding landed in its bucket |
The bar: a finding is proven only when it carries both a reproducer and a bounded impact statement. Missing either ⇒ unproven. No other input changes the bucket.
What counts as a reaching reproducer is defined by the claim-evidence-mapping contract (BCE-1,
#1835), not here: an injection claim at the http-api boundary needs an http-transcript; a UI
claim needs a screenshot or recording. A passing unit test-run-log reaches code-unit only and
never discharges either.
Each field stands on its own. The two halves are recorded independently: a finding with a bounded
impact but no reproducer keeps its impact statement verbatim and only reproducer reads none; a
finding with a reproducer but no bounded impact keeps the evidence ref and only impact reads
unproven. Never overwrite a field you actually have with a missing-value placeholder — the
reason line names which half is missing, and the surviving half is the head start the next reviewer
needs.
Findings render in two clearly-labeled buckets: Security (proven) and Security (unproven).
A reproducer-less finding stays in the security section, labeled unproven with its reason. It
is never auto-demoted to a maintenance bucket and it is not removed from the report —
under-reporting a real vulnerability is the worse failure, so the conservative default keeps it
visible where a security reader looks.
Single policy point. The unproven bucket's label is the only thing an owner may change:
security.review.unprovenBucket in .lisa.config.json, default security-unproven. An owner who
prefers true demotion sets it to a maintenance label; the finding then renders under that bucket and
no other classification logic changes — the bar, the fields, and the reasons are identical.
Write both buckets in operator voice (factory-model rule 5): a person who does not code reads this
at the gate. "Anyone who can reach the search box can read other customers' orders — reproduced with
the request transcript below" is usable; "possible SQLi in handler" is not.
This bar governs code-review security findings. Dependency CVE remediation keeps its own decision
ladder in the security-audit-handling rule — cite it, do not restate or fork it.
Bucketing is advisory — it shapes the report, it does not block a merge — on the same terms as
the boundary checks, which stay reporting-only until verification.gate.enforceBoundaries is true
in .lisa.config.json.
Structure findings as:
## Security Analysis
### Threat Model (STRIDE)
| Threat | Applies? | Description | Mitigation |
|--------|----------|-------------|------------|
| Spoofing | Yes/No | ... | ... |
| Tampering | Yes/No | ... | ... |
| Repudiation | Yes/No | ... | ... |
| Info Disclosure | Yes/No | ... | ... |
| Denial of Service | Yes/No | ... | ... |
| Elevation of Privilege | Yes/No | ... | ... |
### Security Checklist
- [ ] Input validation at system boundaries
- [ ] No secrets in code or logs
- [ ] Auth/authz enforced on new endpoints
- [ ] No SQL/NoSQL injection vectors
- [ ] No XSS vectors in user-facing output
- [ ] Dependencies free of known CVEs
### Security (proven)
- [finding] -- where in the code, how to prevent
- reproducer: [evidence ref, e.g. evidence/<ticket>/http-transcript-01.txt]
- impact: [who can do what, to what data, under what preconditions]
- reason: reproducer + bounded impact
### Security (unproven)
- [finding] -- where in the code, how to prevent
- reproducer: [evidence ref if one exists, else `none`]
- impact: [bounded statement if one exists, else `unproven`]
- reason: [which half is missing -- e.g. "impact bounded, but never reproduced"]
-- kept in the security section, not demoted
### Recommendations
- [recommendation] -- priority (critical/warning/suggestion)
Rename the unproven heading only when security.review.unprovenBucket is set to something other
than security-unproven; everything else stays as written.
unproven is the
conservative landing spot, and the reason line says why.gitleaksignore patterns to understand what secrets scanning is already in placedevelopment
Prepare a machine — a fresh laptop or a throwaway container — to run coding agents, before any repository exists. Detects which of Lisa's supported agents (Claude Code, Codex, Cursor, OpenCode, Antigravity, Copilot) are already installed, asks which credential manager the machine uses (Bitwarden, 1Password, Doppler, Vault, AWS, or none), and installs only what is missing, each by its vendor's own preferred method. Idempotent, headless by default, and emits a Dockerfile for a spin-up/spin-down environment. Run it on a new machine, in a container, or before cloning anything.
tools
Provision and verify a remote execution environment for a host project — Codex Cloud today, other remote surfaces as they are added. Generates a repository-owned setup script that installs the declared toolchain, materializes secrets through lisa-secrets-access, and runs the project's own hook. Provisions by API where one exists, by driving the vendor console where one does not, and by emitting exact config otherwise — then proves the result with the same read-back regardless of which tier did the work. Use before dispatching any work with executionEnv.
tools
Bring a developer's machine in line with the toolchain the project declares. Reports every tool in remoteEnv.tools that is missing, outdated, or unpinned for this platform, and installs the missing ones into ~/.local/bin from the same pinned, checksummed entries the remote surfaces use — but only when asked. Same manifest, same pins, same installers as lisa-setup-remote-env; what differs is consent and that the pin is a floor rather than an equality. Run it on a fresh checkout, after a manifest change, or when a tool fails at the moment of use.
tools
Route one unit of work to a remote execution surface. Reads the executionEnv parameter (local by default, codex-cloud or claude-web today), verifies the environment is provisioned and bound to this repository, submits a thin skill invocation, records the task identifier to .lisa/remote-dispatch.json, and exits without polling. Routing only — the remote runs the identical skill from the identical repository. Composable and inline: other skills invoke it via the Skill tool rather than users calling it directly.