Rules Overview
209 rules. 16 categories. All open-source YAML you can read, extend, or override. Built-in rules ship with the npm package and run on every scan automatically. Custom rules load from your project and run alongside them.
What rules are
Section titled “What rules are”Each rule describes a single threat pattern. At scan time, the rule engine evaluates every rule against every file in a detected component. When the computed confidence score meets or exceeds the rule’s threshold, a finding is emitted.
Rules live in YAML files under a top-level rules: list. A single YAML file can contain many rules of the same or different categories.
rules: - id: tp-001 name: Hidden Instructions in Tool Descriptions description: Detects invisible Unicode characters used to hide instructions category: tool-poisoning severity: critical version: "1.0.0" enabled: true confidenceThreshold: 50 patterns: - type: regex pattern: '[\u200B\u200C\u200D\uFEFF]' weight: 95 description: Zero-width space or BOM character remediation: | Remove all invisible Unicode characters from tool descriptions. references: - https://atlas.mitre.org/techniques/AML.T0051Rule anatomy
Section titled “Rule anatomy”| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique rule identifier (e.g., tp-001, cred-042) |
name | string | Yes | Short human-readable name shown in scan output |
description | string | Yes | What the rule detects and why it matters |
category | string | Yes | One of the 16 threat categories (e.g., tool-poisoning, secret-detection) |
severity | enum | Yes | critical, high, medium, or low |
version | string | No | Rule version for change tracking (e.g., "1.0.0") |
enabled | boolean | No | Set to false to disable a rule globally. Defaults to true |
confidenceThreshold | number | No | Minimum confidence (0–100) required to emit a finding. Defaults to 50 |
platforms | string[] | No | Restrict the rule to specific platforms. Omit to apply to all |
patterns | array | Yes | One or more pattern objects (see below) |
remediation | string | No | Fix guidance shown in reports and terminal output |
references | string[] | No | URLs to MITRE, OWASP, or other reference material |
Pattern objects
Section titled “Pattern objects”Each item in patterns has the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
type | enum | Yes | Matcher type — one of 7 values (see below) |
pattern | string | Yes | The pattern expression to match against file content |
weight | number | Yes | Contribution to the confidence score (0–100) |
description | string | No | Human label for this pattern, shown in verbose output |
flags | string | No | Regex flags for regex type patterns (e.g., "i" for case-insensitive) |
The 7 pattern matcher types
Section titled “The 7 pattern matcher types”Applies a JavaScript regular expression to raw file content. The most common and flexible matcher.
- type: regex pattern: 'AKIA[0-9A-Z]{16}' weight: 100 description: AWS Access Key ID formatApplies a YARA-style string match (not the YARA binary). Supports case-insensitive strings, hex strings, and simple conditions.
- type: yara pattern: '"bitcoin" nocase' weight: 70 description: Reference to bitcoin wallet operationsfile-access
Section titled “file-access”Matches when the file content contains a reference to a specific file path — typically a sensitive credential or system file. Tilde expansion (~ → home directory) is applied before matching.
- type: file-access pattern: "~/.aws/credentials" weight: 90 description: Direct reference to AWS credentials fileimport
Section titled “import”Matches when a specific module or package import appears in the file. Handles Python import/from and JavaScript/TypeScript require/import statements.
- type: import pattern: "paramiko" weight: 60 description: SSH library — check for unauthorized tunnel creationnetwork
Section titled “network”Matches URL or hostname patterns in file content. Used to detect requests to suspicious TLDs, tunneling services, or known malicious domains.
- type: network pattern: "https?://[^/]*\\.(tk|ml|ga|cf|gq|xyz)/" weight: 85 description: Request to suspicious top-level domainstring-literal
Section titled “string-literal”Matches an exact string literal including surrounding quotes. Used for known-bad package names and exact-match indicators.
- type: string-literal pattern: '"event-stream"' weight: 90 description: event-stream — compromised to steal bitcoin walletsPlain substring search against file content. No regex syntax. Fastest matcher — use it for simple keyword matches where regex overhead is not needed.
- type: text pattern: "DISABLE_AUTH=true" weight: 80 description: Authentication bypass flag set in configSeverity levels
Section titled “Severity levels”| Severity | Meaning | Typical examples |
|---|---|---|
critical | Immediate exploitable risk — block CI | Hidden instructions, hardcoded root credentials, auth bypass |
high | Significant vulnerability — fix before merge | API key exposure, data exfiltration, unsigned package installs |
medium | Noteworthy risk — fix in current sprint | Overly broad permissions, weak JWT configuration |
low | Informational — investigate when convenient | Debug logging left enabled, overly verbose error messages |
Use --severity to filter output to a minimum level:
# Only critical and high findingsnpx firmis scan --severity high
# All findings including lownpx firmis scan --severity lowHow rules are loaded
Section titled “How rules are loaded”Built-in rules ship inside the npm package at node_modules/firmis/rules/. They are loaded automatically on every scan. You do not need to reference them in config.
Custom rules are loaded from one of three places, in priority order:
-
A path passed via
--rulesCLI flag:Terminal npx firmis scan --rules ./rules/custom/ -
The
ruleskey in your.firmis.config.yaml(or.firmis.config.json):.firmis.config.yaml rules:- ./rules/custom/my-rules.yaml- ./rules/custom/network-rules.yaml -
A
rules/directory at the project root — Firmis loads any*.yamlfiles found there automatically.
Custom rules are merged with built-in rules. Custom rule IDs that collide with built-in IDs override the built-in rule.
What to do next
Section titled “What to do next”- Built-in Rules → — complete listing of all 209 rules with IDs and descriptions
- Custom Rules → — full YAML schema and working examples for writing your own
- Ignoring Findings → — suppress false positives without disabling rules
- Detection Engine → — confidence scoring and deduplication internals