agentleFS
vrypanvrypan/skills/code-security-review/SKILL.md

code-security-review

Skill1 starsChanged 4 months agoMITView on GitHub

Review unfamiliar/third-party code (repos, scripts, packages) for malicious behavior before running it — network calls, file access, obfuscation, risky deps. Use for pre-run security audits.

  • Reads credentials

4 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions4 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 4

    1. bountyoperator/bounty-operator★ 5same name
    2. Bruno-Cunha-Souza/ValarMindSkills★ 5same name
    3. Greenplumwine/alibaba-java-manual★ 4same name
    4. NoRiceToday/skills★ 1same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

The file

We split this skill into the rules it gives an agent

6 rules. 0 are common, 5 are distinctive, and 1 is very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 5

    Distinctive

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Keep this principle visible throughout the review rather than treating the checklist items below as a disconnected list — each one is …

    line 18
  2. Distinctive:

    Write the one-sentence claim of what it's supposed to do, including any scope limits the project itself declares (offline, LAN-only, …

    line 25
  3. Distinctive:

    Search the source for each category below.

    line 29
  4. Very specific:

    Search "<repo/package name> malware" or "backdoor" for known-compromised packages

    line 77
  5. Distinctive:

    Always state which commit the (re)affirmed verdict covers, and note that installed versions (Homebrew, release tarballs) map to tags — a …

    line 87
  6. Distinctive:

    If asked to produce a reusable checklist document (rather than review a specific piece of code), generate a markdown checklist file …

    line 131

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Code Security Review

Why this matters

A license (MIT, Apache, etc.) only establishes legal permission to use code — it says nothing about whether the specific copy in front of you is safe to execute. The goal of this review is to catch the gap between what a project claims to do and what its code actually does, before that code runs on the user's machine with the user's permissions.

Core principle: README vs. code

Before reading a single line of implementation, write down — literally, in one sentence — what the project claims to do, based on its README/docs/description. Everything else in this review is a search for violations of that sentence. A tool described as "renames files based on EXIF data" has no legitimate reason to make network calls, read SSH keys, or spawn subprocesses. If it does any of those things, that's the finding, and it's usually the whole ballgame — most malicious code reveals itself exactly at the point where behavior exceeds stated purpose.

The test is scope-match, not presence. Capabilities like networking, file writes, or key handling are not inherently red flags — a P2P sync tool is supposed to open sockets, and a password manager is supposed to touch credential files. For such tools the question shifts from "does it do X?" to "does X stay inside the claimed scope?" (e.g., a tool claiming LAN-only sync should have no HTTP client, no hardcoded external hosts, no relay endpoints; a tool claiming "offline, no telemetry" should have zero outbound capability at all). The narrower the claim, the easier the check — and a violated narrow claim is the strongest possible finding.

Keep this principle visible throughout the review rather than treating the checklist items below as a disconnected list — each one is really just a different place to look for that same gap.

Workflow

1. Establish provenance and the one-sentence claim

  • Confirm the repo/package is the one the user actually intended (not a similarly-named fork or typosquat)
  • Record the exact commit hash (or release tag/version) being reviewed — the verdict is pinned to it, and it goes in the report
  • Write the one-sentence claim of what it's supposed to do, including any scope limits the project itself declares (offline, LAN-only, read-only, etc.)
  • Also note any reliability warnings the author gives ("experimental," "may lose data") — these feed the verdict separately from the malice assessment (see Output format)

2. Read the code against that claim

Search the source for each category below. For every hit, ask: does this match the one-sentence claim and its declared scope? If not, flag it as a finding — don't wave it off with a charitable interpretation.

Adapt the search patterns to the project's language rather than grepping only the examples below. Rough equivalents:

CategoryPythonJS/TSRustGoZig
Networkrequests, urllib, socket, http.clientfetch, axios, net, httpreqwest, hyper, TcpStream, std::netnet/http, net.Dialstd.http, std.net
Subprocesssubprocess, os.systemchild_process, execSyncstd::process::Commandos/execstd.process.Child
Dynamic execeval, exec, __import__eval, Function()(rare; look for libloading, JIT)plugin(rare; @embedFile of code)

Also check the dependency manifest for what the imports can do: a project with no HTTP client crate/package anywhere in its dependency tree cannot make web requests no matter what the source hides.

  • Network activity: search per the table above, plus shell-outs to curl/wget. Check any hardcoded IPs or hostnames — distinguish bind addresses (0.0.0.0, 127.0.0.1) and multicast/mDNS (LAN-scoped) from external endpoints. Matches inside test fixtures and detection patterns are not findings, but verify that's what they are by reading the surrounding code, not by filename alone.
  • Filesystem access: reads/writes outside the expected working directory, especially ~/.ssh, ~/.aws, browser profile/cookie stores, .env files, keychains/credential managers.
  • Environment scraping: bulk reads of the environment (os.environ, process.env, std::env::vars) that go anywhere beyond expected config.
  • Dynamic execution: per the table, plus reflection-based dynamic loading.
  • Persistence: writes to cron, systemd units, shell rc files (.bashrc/.zshrc), LaunchAgents (macOS), startup folders.
  • Obfuscation: base64/hex blobs, minified code in a source repo, unusually dense or unreadable sections. Decode anything obfuscated before ruling it benign — obfuscation in source (as opposed to a legitimately compiled binary) is itself a red flag, not a neutral fact.
  • Self-modifying/self-downloading behavior: code that fetches and executes additional payloads at runtime.
  • Hardening measures (positive findings): deliberate defensive choices — stripping setuid/setgid bits from received files, redacting secrets by default, atomic writes, permission preservation, memory-safe crypto libraries. Note these; they raise confidence and belong in the report.

The categories above catch most malicious code because they're visible to a grep — an import, a function name, a string. The categories below (adapted from MITRE ATT&CK's post-execution tactics, not its pre-compromise or infrastructure tactics) catch the behaviors that a grep alone misses: they require reading what the code does with a capability it already legitimately has, not just whether it has one.

  • Credential-store access (ATT&CK: Credential Access): calls into OS keychains (macOS Keychain, Windows Credential Manager, libsecret), browser saved-password/cookie stores, or ~/.ssh/known_hosts/authorized_keys — distinct from generic env/filesystem access because these are named, purpose-built APIs, not incidental file reads.
  • Input/output capture (ATT&CK: Collection): clipboard read/write, screenshot or screen-capture calls, global keyboard/mouse hooks, microphone/camera access. Rare for a CLI tool to need any of these — if found, check hard against the claim.
  • Environment fingerprinting (ATT&CK: Discovery): enumerating running processes, installed security/AV software, or checking for a debugger, VM, or CI environment. Legitimate in a few contexts (a benchmark tool checking for a debugger attach); suspicious when paired with conditional logic that changes behavior based on the result — that pairing is the actual finding, not the fingerprinting call alone.
  • Conditional/time-gated behavior (ATT&CK: Defense Evasion): code that behaves differently based on the current date, a sandbox/CI detection, or an environment check — a time-bomb or logic-bomb pattern. This is different from obfuscation (which hides what code does); this hides when it does it. Read every if that branches on Date.now()/time.time() or an environment fingerprint and ask why.
  • Covert/disguised exfiltration (ATT&CK: Command and Control, Exfiltration): data smuggled through a channel that looks legitimate — encoded into DNS queries, stuffed into extra fields of a request to a domain the tool is supposed to call, or sent via a protocol that bypasses the network-library grep entirely (raw sockets, ICMP). This is the one specifically designed to survive a naive "check the hostname" review — when a network call to an expected host is found, still check what is being sent, not just where.
  • Privilege escalation: editing /etc/sudoers, manipulating setuid/setgid bits upward (not just stripping them), or exploiting a local service/kernel vulnerability rather than requesting elevated privileges through the documented, expected path.
  • Destructive or hijacking impact (ATT&CK: Impact): bulk file deletion or encryption outside the stated scope, or unauthorized background resource use (e.g., a cryptominer riding along in an unrelated tool).
  • Unsafe deserialization: pickle.load, unsafe YAML (yaml.load without SafeLoader), marshal.load, or equivalent on untrusted input — a code-execution path distinct from direct eval/exec calls, easy to miss because it doesn't look like dynamic execution at a glance.
  • Insecure randomness for secrets: Math.random(), random.random(), or another non-CSPRNG used to generate tokens, keys, or session IDs — check any homegrown ID/token generator against the language's cryptographic RNG (crypto.randomBytes, secrets, getrandom).
  • Hardcoded credentials or backdoor checks: a literal API key, password, or a conditional that grants special access when an input matches a fixed hidden string.

3. Check dependencies

  • Typosquatted package names in requirements.txt / package.json / Cargo.toml / build.zig.zon / equivalent
  • Pinned versions vs. wide-open ranges (*, >=) that could pull in a compromised future update. In lockfiles, verify all sources resolve to the standard registry (crates.io, npm, PyPI); flag git-URL dependencies — though note ecosystems without a central registry (Zig) use commit-pinned git URLs normally, so judge by whether the pin is an exact hash.
  • Install-time scripts (postinstall in package.json, custom install in setup.py) — these execute automatically, before any other review step matters. Treat these as highest priority to inspect.

4. Check runtime behavior and permissions

  • Does it request permissions disproportionate to its stated job (e.g., a text tool wanting camera/mic/full-disk/network access)?
  • Signature/notarization warnings on prebuilt binaries
  • For prebuilt binaries: verify checksum/signature against what the maintainer publishes, and consider a VirusTotal check

5. Recommend isolation proportionate to findings

Default recommendation is to run in a container or VM first, monitoring network and filesystem activity (Little Snitch/tcpdump; strace/fs_usage). Reading catches most things; sandboxing catches what reading missed. For a clean review of a low-capability tool, isolation can be framed as good habit rather than necessity; for anything with findings, unusual capabilities, or prebuilt binaries, treat it as required before trusting.

6. Fast supplementary checks

  • Search "<repo/package name> malware" or "backdoor" for known-compromised packages

Repeat reviews

A verdict is valid only for the commit it was issued against. When asked to review something already reviewed (in this conversation or a past one — check past-chat search if available):

  1. Fetch the current HEAD and compare against the previously reviewed commit hash.
  2. Unchanged → spot-check the two or three most critical findings still hold (cheap insurance against a force-push to the same apparent state), then reaffirm the prior verdict, citing the commit.
  3. Changed → review the diff between the reviewed commit and HEAD, focused on the same categories; a full re-review is only needed if the diff is large or touches trust-critical paths (network, install scripts, dependency manifest).

Always state which commit the (re)affirmed verdict covers, and note that installed versions (Homebrew, release tarballs) map to tags — a later upgrade is new unreviewed code.

Output format

Present findings as a short report, not a wall of checklist items with no synthesis:

## Security Review: <name>

**Reviewed at:** <commit hash / tag> (<date>)

**Stated purpose:** <the one-sentence claim, including declared scope limits>

**Findings:**
- <category>: <what was found, and whether it matches or violates the stated purpose/scope>
  (repeat per category with a hit; skip categories with nothing to report, don't pad)
- Hardening: <deliberate defensive measures found, if any>

**Verdict:** <clean / minor concerns / do not run> — <one or two sentences of reasoning>

**Reliability note:** <author's own experimental/data-loss warnings, if any — distinct from
the malice verdict; a tool can be non-malicious and still eat your files>

**Recommended next step:** <e.g., "run in a container first," "test on a throwaway folder",
"ask the maintainer about X before proceeding">

Security label (visual output)

After the prose report above, ALWAYS render the findings as a color-coded label using the visualize tool (HTML mode), styled after privacy nutrition labels (Apple App Privacy, Google Play Data Safety) but adapted to the README-vs-code principle: each row is graded against the stated claim, not scored in isolation.

Structure:

  • Header: package name, reviewed commit/tag, one-line stated claim
  • One row per category from the table above (Network, Filesystem, Subprocess, Dynamic exec, Credentials/env, Persistence, Install-time exec, Obfuscation, Dependencies) — only include categories relevant to the project's language/ecosystem
  • Add a row from the extended (ATT&CK-derived) category list only when that category actually applies or produced a finding — e.g. add "Credential-store access" only if the code touches a keychain/browser store, add "Conditional/time-gated behavior" only if a date- or environment-conditioned branch exists. Don't pad a simple tool's label with rows for capabilities it has no reason to touch.
  • Each row gets a colored pill using CSS role tokens, not raw hex:
    • Green (--bg-success / --text-success): matches claimed scope, or none found
    • Amber (--bg-warning / --text-warning): broader than claimed but disclosed/benign
    • Red (--bg-danger / --text-danger): undisclosed or contradicts the claim — this is the finding
  • A separate "Hardening / declared practices" row below the divider (green if present, red if a security-sensitive project has none)
  • A verdict banner at the bottom, colored to match the worst row present, with a one-line reason

Render this via the visualize tool whenever presenting a review in a chat surface that supports it. The prose report remains the source of truth for detail (exact file/line evidence, reasoning) — the label is a compact, at-a-glance summary, not a replacement for it. For a clean review, every row shows green and the verdict banner is green.

If asked to produce a reusable checklist document (rather than review a specific piece of code), generate a markdown checklist file organized by the same categories above, framed around the README-vs-code principle, rather than embedding the review workflow prose directly.

Boundaries

This process improves confidence but doesn't guarantee safety — sufficiently sophisticated or well-hidden malicious code can evade a manual read-through. Always pair source review with runtime isolation (step 5); don't let a clean-looking read substitute for sandboxing. This skill is for helping a user evaluate code before running it, not for writing or improving obfuscation, exploits, or malicious functionality — if a review surfaces code that looks like it's designed to evade detection, say so plainly rather than helping refine it.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.