Skip to content

Malware scanning (Pass 14)

Pass 14 is an opt-in assessment pass that scans application source code for security threats across three phases: secret detection and dependency vulnerability scanning (Phase 1), antivirus signature and custom YARA rule matching (Phase 2), and OSS licence compliance via ORT (Phase 3, disabled by default). All tools are optional -- the pass skips any tool that is not installed rather than failing.

Pass key: malware Output file: wsp/runs/<timestamp>/passes/14-malware.yaml


What it does

Phase 1 -- Secret detection and dependency vulnerability scanning

  • Gitleaks scans the source path for committed secrets, API keys, tokens, and credentials. On a finding, SWAO emits signal MAL-03 (severity: high) with the rule ID and file location for each detected secret.
  • OSV-Scanner reads the lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml) and queries the Open Source Vulnerabilities database for known CVEs. On a finding, SWAO emits signal MAL-09 (severity: high) with each affected package and its CVE identifier.

Phase 2 -- Antivirus and custom rule matching

  • ClamAV runs a recursive antivirus signature scan over the source tree. The pass tries clamdscan (daemon mode) first for speed; if the daemon is not running it falls back to clamscan (one-shot mode). On a finding, SWAO emits signal MAL-01 (severity: critical) listing each infected file and the matched signature name.
  • YARA applies every .yar and .yara rule file found in wsp/inputs/yara-rules/ to the source tree. On a match, SWAO emits signal MAL-02 (severity: high) with each matching rule name and file path.

Phase 3 -- OSS licence compliance (opt-in)

  • ORT (OSS Review Toolkit) analyses declared package licences. Three signals may be emitted:
    • MAL-10 (severity: high) -- copyleft dependencies (GPL, AGPL, LGPL, MPL, CDDL, EPL, and similar).
    • MAL-11 (severity: high, confidence: medium) -- dependencies with no declared licence.
    • MAL-12 (severity: high) -- ORT policy rule violations, when a wsp/inputs/ort-rules.kts policy script is present. ORT is disabled by default because an analyse run on a large repository can take several minutes. Enable it explicitly in .swao.yml (see Configuration below).

Tools and signal IDs

ToolSignalSeverityWhat it detects
GitleaksMAL-03highHardcoded secrets, API keys, tokens
OSV-ScannerMAL-09highKnown CVEs in lockfile dependencies
ClamAVMAL-01criticalKnown malware signatures
YARAMAL-02highCustom rule matches
ORTMAL-10highCopyleft licence dependencies
ORTMAL-11high (medium confidence)Undeclared licence
ORTMAL-12highPolicy rule violations

A positive (clean) signal is recorded for each tool that runs and finds nothing, so the pass output reflects which tools actually ran.


Prerequisites -- installing the tools

All four Phase 1 and Phase 2 tools are optional. The pass skips any tool that is absent from PATH and continues to the next one. swao health-check reports each tool's status as warn when it is absent and ok when it is installed.

Gitleaks

bash
# macOS
brew install gitleaks

# Linux -- download from GitHub releases
curl -sSL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks_linux_x64.tar.gz \
  | tar xz -C /usr/local/bin gitleaks

Licence: MIT. See https://github.com/gitleaks/gitleaks/releases for all platform builds.

OSV-Scanner

bash
# Via Go toolchain
go install github.com/google/osv-scanner/cmd/osv-scanner@latest

# Or download a pre-built binary from GitHub releases
# https://github.com/google/osv-scanner/releases

OSV-Scanner only runs when a lockfile (package-lock.json, yarn.lock, or pnpm-lock.yaml) is present directly in the source path. Projects without a lockfile have MAL-09 skipped automatically.

ClamAV

bash
# Ubuntu / Debian
apt-get install clamav clamav-daemon
freshclam   # download the latest virus database

# macOS
brew install clamav

Keep the virus database current with freshclam before running assessments. A stale database reduces detection accuracy. The pass uses clamdscan (daemon) when available and falls back to clamscan (one-shot) automatically.

YARA

bash
# Ubuntu / Debian
apt-get install yara

# macOS
brew install yara

Place your custom rule files (.yar or .yara extension) in wsp/inputs/yara-rules/ within the application workspace. The pass scans all files in that directory (non-recursive) and skips YARA entirely if the directory is absent or contains no rule files.

ORT (Phase 3 -- opt-in)

ORT requires a Java runtime (JDK 11 or later). See https://github.com/oss-review-toolkit/ort/releases for installation instructions. After installation, confirm ort is on your PATH:

bash
ort --version

Verifying tool installation

bash
swao health-check

Look for these entries in the output:

EntryStatus okStatus warn
gitleaksInstalled; Pass 14 MAL-03 activeAbsent; MAL-03 skipped
osv-scannerInstalled; Pass 14 MAL-09 activeAbsent; MAL-09 skipped
clamavInstalled; Pass 14 MAL-01 activeAbsent; MAL-01 skipped
yaraInstalled; Pass 14 MAL-02 activeAbsent; MAL-02 skipped

warn is not a failure -- the pass still runs with the remaining tools.


How to enable

Pass 14 is opt-in and is never included in the default pass set. Invoke it explicitly via --passes:

bash
# Run malware scan alongside the standard assessment passes
swao assess --app sovereign-health --passes inv,state,sbom,crypto,malware

# Run malware scan only
swao assess --app sovereign-health --passes malware

# Fail the assessment if secrets or malware are detected (for CI pipelines)
swao assess --app sovereign-health --passes malware --malware-fail-on-detection

--malware-fail-on-detection causes SWAO to exit with a non-zero status code when any MAL-01 (antivirus match) or MAL-03 (secret detection) finding is present. This enables use as a CI gate.


Configuration (.swao.yml)

The following block in .swao.yml (at the application workspace root) controls Pass 14 behaviour. All fields are optional; the defaults are shown.

yaml
passes:
  malware:
    enabled: true                         # true when --passes malware is explicit
    severity_threshold: high              # minimum severity to include in report
    exclude:
      paths:
        - "node_modules/"
        - "dist/"
        - "*.min.js"
    tools:
      gitleaks:
        enabled: true
        config_file: ".gitleaks.toml"     # optional custom Gitleaks config
      osv_scanner:
        enabled: true
      clamav:
        enabled: true
      yara:
        enabled: true
        rules_dir: "wsp/inputs/yara-rules/"   # default; override to use a different path
      ort:
        enabled: false                    # Phase 3 -- opt-in; requires ORT on PATH
        rules_file: "wsp/inputs/ort-rules.kts"   # optional ORT policy rules script

To enable Phase 3 (ORT licence compliance), set passes.malware.tools.ort.enabled: true. ORT policy violation checks (MAL-12) are activated automatically when wsp/inputs/ort-rules.kts is present, or when passes.malware.tools.ort.rules_file points to a valid Kotlin script.


Example output

Pass 14 writes its results to wsp/runs/<timestamp>/passes/14-malware.yaml. A typical summary section:

yaml
pass:
  id: 14
  name: malware_scanning
  signal_prefix: MAL
  status: complete
assessment:
  tools_attempted:
    - gitleaks
    - osv-scanner
    - clamav
  tools_skipped:
    - "yara (no rules in wsp/inputs/yara-rules/)"
    - "ort (not enabled; set passes.malware.tools.ort.enabled: true in .swao.yml to enable)"
signals:
  - id: MAL-03
    severity: positive
    derivation: "No secrets detected by Gitleaks."
  - id: MAL-09
    severity: high
    derivation: "3 CVE(s) found by OSV-Scanner."
    evidence:
      - "lodash@4.17.20: CVE-2021-23337"
      - "minimist@1.2.5: CVE-2021-44906"
      - "node-fetch@2.6.6: CVE-2022-0235"
  - id: MAL-01
    severity: positive
    derivation: "No AV signature matches detected by ClamAV."

Known limitations

  • OSV-Scanner requires a lockfile (package-lock.json, yarn.lock, or pnpm-lock.yaml) directly in the source path. Projects without one have MAL-09 skipped.
  • ClamAV virus database must be kept current (freshclam) for accurate detection. A stale database may miss recently catalogued signatures.
  • YARA requires at least one .yar or .yara rule file in the configured rules directory (wsp/inputs/yara-rules/ by default). The tool is skipped when the directory is absent or empty.
  • YARA rules are loaded non-recursively from the configured directory. Sub-directories are not scanned.

Note: Signals MAL-04 to MAL-08 are planned and not yet emitted in the current release.

  • The following signal IDs are not yet implemented: MAL-04 and MAL-05 (VirusTotal cloud scan), MAL-06 (binary entropy anomaly), MAL-07 (suspicious archive detection), MAL-08 (container image CVE scan via Grype).
  • OSV-Scanner SBOM mode -- feeding the CycloneDX output from Pass 05 into OSV-Scanner via --sbom -- is not yet implemented. The current implementation uses lockfile mode (--lockfile).