Skip to content

Suppressing findings ​

Some findings will be legitimate: a build script that really does need shell=True, or a test fixture that contains a sample payload. Record each accepted finding once, with a reason, in .malware-detector-ignore.json at the root of your repository:

json
[
  {
    "path": "scripts/deploy.py",
    "ruleId": "py-subprocess-shell-true",
    "reason": "Fixed command, no user input — reviewed 2026-10-01"
  },
  {
    "path": "tests/fixtures/",
    "reason": "Intentional malware samples used by our tests"
  },
  {
    "ruleId": "js-network-to-ip",
    "path": "src/dev-server.js",
    "line": 12,
    "reason": "Binds to 127.0.0.1 in development only"
  }
]

The same file covers every engine (Semgrep, heuristics, GuardDog and malcontent).

Matching rules ​

Each entry can set any of these fields. A finding is suppressed when it matches every field the entry sets:

FieldMatches
pathA substring ("tests/fixtures/") or a glob ("*.generated.js")
ruleIdAn exact rule ID from the rule catalogue
lineAn exact starting line number
reasonNot used for matching. Write down why, for the next reviewer

Every entry must set at least path or ruleId. A malformed file stops the scan with exit code 2, so a typo can't silently disable suppressions or hide findings.

Where the file is found ​

malware-detector walks up from the scan target until it finds .malware-detector-ignore.json, so a single file at the repository root covers every subdirectory. To use a file somewhere else:

sh
malware-detector scan . --ignore-file security/ignore.json

Good habits ​

  • Be narrow. Prefer path + ruleId over a bare path. Suppressing a whole folder hides future findings in it too.
  • Always write a reason. Six months from now, "why is this ignored?" should take seconds to answer.
  • Review it in PRs. Treat changes to the ignore file as security-relevant. Adding a CODEOWNERS entry for it is a cheap safeguard.