checks

package
v0.47.0-rc.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 3, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CapabilityMismatch

type CapabilityMismatch struct{}

CapabilityMismatch is a SOFT check (FR-009, US2) that flags a gap between what a tool *declares* it does and what it *implies* it touches:

  • Declared-vs-implied: a tool whose declared purpose is pure computation or string manipulation (name/lead like "add", "to_uppercase") that nevertheless references a sensitive resource it has no business touching (~/.ssh, /etc/passwd, an external URL, a shell). A calculator reading id_rsa is a classic capability-mismatch exfiltration tell.
  • Unexplained data-sink param: a free-form input named like an exfiltration channel ("sidenote", "scratchpad") that the description never explains — the model is steered to stuff stolen data into it.

The declared category is taken from the tool NAME and its leading sentence, NOT the full description, so an attacker's benign cover sentence still anchors the declaration while the smuggled access in the rest of the text is treated as implied. Tools that legitimately declare file/network/system access are therefore NOT flagged for touching those resources (FR-009 MUST-NOT).

Being soft, a hit raises a finding for review and never auto-quarantines.

func (*CapabilityMismatch) ID

func (*CapabilityMismatch) ID() string

ID implements detect.Check.

func (*CapabilityMismatch) Inspect

Inspect implements detect.Check. It emits at most one signal per tool, preferring the capability-mismatch signal over an unexplained data-sink.

type DirectiveImperative

type DirectiveImperative struct{}

DirectiveImperative is a SOFT check (FR-009, US2) that flags prompt-injection directives smuggled into a tool's description: hidden-instruction tags (<IMPORTANT>…), secrecy imperatives ("do not tell the user"), instruction overrides ("ignore previous instructions"), and tool-preamble injections ("before using this tool, first …").

It runs over the engine's NORMALIZED text (lowercased, contraction-expanded, format-rune-stripped) so "don't disclose" and "do not tell" collapse to one matchable form. Each hit is position-classified: a phrase quoted or illustrated ("detects prompts such as 'ignore previous instructions'") is example-position and discounted below the emit threshold, so legitimate security tooling that merely *describes* these phrases is not flagged. This is the core false-positive control for US2 (per detect.ClassifyPosition).

Being soft, it raises a finding for human review but never auto-quarantines.

func (*DirectiveImperative) ID

ID implements detect.Check.

func (*DirectiveImperative) Inspect

Inspect implements detect.Check. It emits at most one signal per tool: the highest-confidence directive match that clears directiveMinConfidence after position discounting.

type EmbeddedSecret

type EmbeddedSecret struct{}

EmbeddedSecret is a SOFT check (FR-009, US2) that flags a live credential hardcoded into a tool's description or schema — an AWS key, a private key, a database password, a Luhn-valid card, etc. It wraps the shared internal/security/patterns matchers and carries each match's per-match confidence (Spec 076 T015): a validated card / live cloud key is high, a documented placeholder (AKIA…EXAMPLE) collapses to near-zero and is dropped.

It also restores the two secret categories the deleted legacy security.NewDetector(nil) path covered but the pattern matchers do not (Spec 077): a sensitive file-path reference (~/.ssh/id_rsa, ~/.aws/credentials, .env, /etc/passwd, *.pem, …) and a high-entropy blob that looks like an opaque secret. Both stay self-contained and offline (stdlib regexp + math only), so the detect package keeps its no-network / no-filesystem guarantee.

It scans RAW text (not the engine's normalized text): secrets are case-sensitive and exact, and normalization would lowercase prefixes (AKIA…) and fold the very bytes the matchers key on.

Being soft, a hit raises a finding for review and never auto-quarantines — an embedded secret may be a careless example as easily as a planted one.

func (*EmbeddedSecret) ID

func (*EmbeddedSecret) ID() string

ID implements detect.Check.

func (*EmbeddedSecret) Inspect

Inspect implements detect.Check. It emits at most one signal per tool: the highest-confidence embedded secret found in the raw description + schema, across credential matchers, sensitive file paths, and high-entropy blobs.

type PayloadDecoded

type PayloadDecoded struct{}

PayloadDecoded is a HARD check (FR-008) that decodes base64/hex blobs embedded in a tool's description or schema and flags ONLY when the decoded bytes are a shell/exfiltration command — `curl … | sh`, `wget … | sh`, `chmod`, `rm -rf`, a pipe-to-shell, or a raw IP:port reverse-shell target. Benign encoded data (an icon, a JSON config) decodes to non-matching/non-printable bytes and is never flagged, so the false-positive rate stays near zero. Evidence is the decoded content, surfaced so an operator sees exactly what was hidden.

func (*PayloadDecoded) ID

func (*PayloadDecoded) ID() string

ID implements detect.Check.

func (*PayloadDecoded) Inspect

Inspect implements detect.Check.

type PhraseInjection

type PhraseInjection struct{}

PhraseInjection is the curated HARD check (Spec 077 FR-004) that restores the approval-blocking posture the deleted legacy tpa_hidden_instructions / data_exfiltration substring rules provided — without their false positives.

It fires ONLY on a small, high-confidence set of prompt-injection and data-exfiltration DIRECTIVES:

  • instruction overrides ("ignore all previous instructions"),
  • explicit secret-exfiltration ("send the credentials to …", "exfiltrate ~/.ssh/id_rsa", "upload the .env file to …"),
  • system-prompt / instruction exfiltration ("reveal your system prompt").

Broader, lower-confidence phrasing stays in the SOFT directive.imperative check (review-only). Being hard, a hit here contributes to the dangerous verdict and auto-quarantine, so the patterns are deliberately narrow and every match is position-discounted: a phrase that is quoted or merely described ("detects prompts such as 'ignore previous instructions'") lands below the hard emit floor and is NOT auto-blocked (FR-005, the core false-positive control). Such a matched-but-discounted phrase is not discarded either — it is downgraded to a SOFT review signal (never-fully-suppress, Codex round-3), so a real injection can never disappear behind a framing cue.

It runs over the engine's NORMALIZED text (lowercased, contraction-expanded, lightly-stemmed, format-runes stripped) so "don't disclose" / "do not tell" and "instructions" / "instruction" collapse to one matchable form.

func (*PhraseInjection) ID

func (*PhraseInjection) ID() string

ID implements detect.Check.

func (*PhraseInjection) Inspect

Inspect implements detect.Check. It emits at most one signal per tool: the highest-confidence curated directive found after position discounting.

Tiering (Spec 077 US1, Codex round-3 "never fully suppress"):

  • conf ≥ phraseHardMinConfidence (instruction-position) → HARD (auto-quarantine).
  • a family MATCHED but was discounted below the hard floor (descriptive/example/quoted) → SOFT, re-floored to phraseSoftFloor so the match surfaces for review instead of vanishing. A matched injection is therefore never silently dropped, no matter what framing cue precedes it.
  • nothing matched → no signal.

type Shadowing

type Shadowing struct{}

Shadowing is a HARD check that flags cross-server tool impersonation and reference (FR — shadowing). Two distinct attack shapes:

  1. Name collision: a DISTINCTIVE tool name exposed by two different servers (one impersonating the other so an agent calls the wrong one).
  2. Cross-server reference: a tool whose description names a DISTINCTIVE tool that lives on a different server (steering the agent's tool selection).

To hold near-zero FP, both shapes require the name to be distinctive: generic verbs ("search", "get", "list") collide across servers all the time and are never flagged. A tool referencing its OWN name is also ignored.

func (*Shadowing) ID

func (*Shadowing) ID() string

ID implements detect.Check.

func (*Shadowing) Inspect

func (c *Shadowing) Inspect(tool detect.ToolView, reg detect.RegistryView) []detect.Signal

Inspect implements detect.Check. Cross-tool reasoning uses the RegistryView indexes built once per scan.

type UnicodeHidden

type UnicodeHidden struct{}

UnicodeHidden is a HARD check (FR-007) that flags invisible/format-control runes smuggled into a tool's RAW description or schema text: zero-width joiners/spaces, bidirectional controls, Unicode TAG-block characters, and Private-Use-Area code points. These never appear in a legitimate human-readable tool description, so a hit is near-zero false-positive.

It runs on the RAW text deliberately — detect.Normalize strips format runes to stabilize phrase matching, which would hide exactly the attack this check exists to catch.

Escalation (FR-007): a description carrying ≥3 distinct hidden classes, or TAG-block characters that decode to a printable ASCII message, is rated near-certain (critical); a single class is still hard but high.

func (*UnicodeHidden) ID

func (*UnicodeHidden) ID() string

ID implements detect.Check.

func (*UnicodeHidden) Inspect

Inspect implements detect.Check. It scans the raw description plus raw schema bytes and emits at most one signal per tool.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL