Add reproducible evaluation and provenance research
This commit is contained in:
@@ -34,6 +34,12 @@ class SecretRule:
|
||||
title = "Potential embedded secret"
|
||||
description = "Finds credential-shaped values and reports only a redacted signal."
|
||||
default_severity = Severity.HIGH
|
||||
artifact_kinds = ("text", "configuration", "source-code")
|
||||
standards = ("CWE-798", "NIST AI 600-1")
|
||||
references = (
|
||||
"https://cwe.mitre.org/data/definitions/798.html",
|
||||
"https://doi.org/10.6028/NIST.AI.600-1",
|
||||
)
|
||||
signals = (
|
||||
RegexSignal("private key", re.compile(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----"), Severity.CRITICAL),
|
||||
RegexSignal("AWS access key", re.compile(r"\bAKIA[0-9A-Z]{16}\b"), Severity.HIGH),
|
||||
@@ -72,6 +78,12 @@ class PromptInjectionRule:
|
||||
title = "Prompt injection or tool-exfiltration instruction"
|
||||
description = "Finds instructions commonly used to override controls or disclose protected context."
|
||||
default_severity = Severity.MEDIUM
|
||||
artifact_kinds = ("prompt", "configuration", "document", "dataset-metadata")
|
||||
standards = ("MITRE ATLAS AML.T0051", "OWASP Agentic AI Threats and Mitigations")
|
||||
references = (
|
||||
"https://atlas.mitre.org/techniques/AML.T0051",
|
||||
"https://genai.owasp.org/resource/agentic-ai-threats-and-mitigations/",
|
||||
)
|
||||
pattern = re.compile(
|
||||
r"(?i)\b(ignore|disregard|override)\b.{0,50}\b(previous|prior|system|developer)\b.{0,30}\b(instruction|prompt|message)s?\b"
|
||||
r"|\b(reveal|print|exfiltrate|send)\b.{0,50}\b(system prompt|secret|credential|token)s?\b",
|
||||
@@ -104,6 +116,9 @@ class DependencyPinRule:
|
||||
title = "Unpinned Python dependency"
|
||||
description = "Finds requirements entries without an exact version or immutable reference."
|
||||
default_severity = Severity.MEDIUM
|
||||
artifact_kinds = ("dependency-manifest",)
|
||||
standards = ("SLSA",)
|
||||
references = ("https://slsa.dev/spec/v1.2/",)
|
||||
|
||||
def evaluate(self, artifact: Artifact) -> Iterable[Finding]:
|
||||
if artifact.text is None or artifact.path.name.lower() != "requirements.txt":
|
||||
@@ -135,6 +150,9 @@ class ContainerTagRule:
|
||||
title = "Mutable container image reference"
|
||||
description = "Finds latest or untagged images in Dockerfiles and Compose files."
|
||||
default_severity = Severity.MEDIUM
|
||||
artifact_kinds = ("deployment",)
|
||||
standards = ("SLSA",)
|
||||
references = ("https://slsa.dev/spec/v1.2/",)
|
||||
from_pattern = re.compile(r"(?im)^\s*FROM\s+([^\s]+)")
|
||||
compose_pattern = re.compile(r"(?im)^\s*image:\s*([^\s#]+)")
|
||||
|
||||
@@ -170,6 +188,12 @@ class ProvenanceRule:
|
||||
title = "Incomplete AI artifact provenance"
|
||||
description = "Checks model and dataset metadata for source, version, license, and SHA-256 evidence."
|
||||
default_severity = Severity.MEDIUM
|
||||
artifact_kinds = ("model-metadata", "dataset-metadata")
|
||||
standards = ("NIST AI 600-1", "CycloneDX ML-BOM")
|
||||
references = (
|
||||
"https://doi.org/10.6028/NIST.AI.600-1",
|
||||
"https://cyclonedx.org/guides/OWASP_CycloneDX-Authoritative-Guide-to-AI-ML-BOM-en.pdf",
|
||||
)
|
||||
required = ("source", "version", "license", "sha256")
|
||||
|
||||
def evaluate(self, artifact: Artifact) -> Iterable[Finding]:
|
||||
@@ -193,12 +217,18 @@ class ProvenanceRule:
|
||||
),)
|
||||
|
||||
|
||||
from .structured_rules import AgentToolPermissionRule, CycloneDxMLBomRule, SlsaProvenanceRule
|
||||
|
||||
|
||||
BUILTIN_RULES: tuple[Rule, ...] = (
|
||||
SecretRule(),
|
||||
PromptInjectionRule(),
|
||||
DependencyPinRule(),
|
||||
ContainerTagRule(),
|
||||
ProvenanceRule(),
|
||||
AgentToolPermissionRule(),
|
||||
SlsaProvenanceRule(),
|
||||
CycloneDxMLBomRule(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user