NVIDIA SkillSpector 64 Vulnerability Patterns: Complete Catalog with Severity Levels

SkillSpector defines 64 static-analysis rule IDs mapped to four severity levels (CRITICAL, HIGH, MEDIUM, LOW) based on the Severity enum in skillspector/models.py, with each pattern implemented in specific analyzer modules under src/skillspector/nodes/analyzers/.

NVIDIA's SkillSpector is an open-source security framework that uses static analysis to detect vulnerabilities in AI agent implementations and supply chain dependencies. The tool catalogs exactly 64 vulnerability patterns—each assigned a default severity—that drive risk scores in the final SARIF reports. These patterns are organized into functional categories ranging from excessive agency detection to supply chain security, with severity levels derived from the core Severity enum and verified through comprehensive unit tests.

How Severity Levels Are Defined in SkillSpector

The severity system centers on the Severity enum defined in src/skillspector/models.py. This enum provides four distinct levels: CRITICAL, HIGH, MEDIUM, and LOW. When analyzer modules detect a vulnerability, they instantiate a Finding object that includes the severity= parameter, which directly references these enum values.

For supply chain vulnerabilities detected via the OSV database (Open Source Vulnerabilities), severity is dynamically determined by CVSS scores. The logic in static_patterns_supply_chain.py maps CVSS scores to SkillSpector severities: scores ≥ 9.0 yield CRITICAL, 7.0–8.9 yield HIGH, 4.0–6.9 yield MEDIUM, and scores below 4.0 yield LOW.

Complete List of 64 Vulnerability Patterns by Category

The 64 patterns are distributed across twelve analyzer modules, each targeting specific attack vectors. The following tables list every pattern ID, its description, and its default severity.

Excessive Agency Patterns (EA1–EA4)

Implemented in static_patterns_excessive_agency.py:

Pattern ID Description Default Severity
EA1 Excessive tool wildcard MEDIUM
EA2 Unsafe "auto-approve" flags MEDIUM
EA3 Scope-creep wording LOW
EA4 Infinite-retry / no-rate-limit MEDIUM

Output Handling Patterns (OH1–OH3)

Implemented in static_patterns_output_handling.py:

Pattern ID Description Default Severity
OH1 Direct code execution (exec, eval, subprocess.run) HIGH
OH2 Prompt-injection via output HIGH
OH3 Unrestricted output (no length limit) HIGH

System Prompt Leakage Patterns (P6–P8)

Implemented in static_patterns_system_prompt_leakage.py:

Pattern ID Description Default Severity
P6 Disclosing system prompt HIGH
P7 Prompt-leakage via "help" wording HIGH
P8 Prompt-leakage via external write HIGH

Memory Poisoning Patterns (MP1–MP3)

Implemented in static_patterns_memory_poisoning.py:

Pattern ID Description Default Severity
MP1 Persistent memory instructions (remember forever) HIGH
MP2 Repetitive filler / padding MEDIUM
MP3 Malicious memory poisoning (instruction override) HIGH

Tool Misuse Patterns (TM1–TM3)

Implemented in static_patterns_tool_misuse.py:

Pattern ID Description Default Severity
TM1 Tool-parameter abuse (rm -rf /, chmod 777, git push --force, curl –insecure) HIGH (unless whitelisted)
TM2 Command-chaining abuse (&& rm -rf, ; curl … | sh) HIGH
TM3 Unsafe defaults (e.g., verify = False, CORS = "*") HIGH

Rogue Agent Patterns (RA1–RA2)

Implemented in static_patterns_rogue_agent.py:

Pattern ID Description Default Severity
RA1 Rogue-agent self-modifying code (open(__file__), path.write_text) HIGH
RA2 Persistence / privilege-escalation instructions (cron, systemd, registry) HIGH

Supply Chain Security Patterns (SC2–SC23)

Implemented in static_patterns_supply_chain.py. This category contains 22 patterns covering script downloads, dependency vulnerabilities, and typosquatting:

Pattern ID Description Default Severity
SC2 Trusted-source script download (e.g., curl https://astral.sh/uv/install.sh) LOW
SC3 Trusted-source, low-confidence download LOW
SC4 Vulnerable dependency discovered via OSV (e.g., Jinja2 XSS) HIGH or CRITICAL
SC5 Abandoned / unmaintained package (PyPI or npm) HIGH
SC6 Typosquat of a popular package name HIGH
SC7 Supply-chain safe pattern (non-malicious curl … | bash) LOW
SC8 npm package with known CVE (via OSV) CRITICAL
SC9 PyPI package with known CVE (via OSV) CRITICAL
SC10 Dependency version out-of-date (no CVE) MEDIUM
SC11 Non-dependency file ignored (no finding) —
SC12 Unmaintained package with no CVE HIGH
SC13 Typosquat with high similarity (> 80%) HIGH
SC14 Typosquat with low similarity (ignored) —
SC15 Trusted-source script with high confidence (e.g., curl https://brew.sh/install.sh) LOW
SC16 Untrusted domain script download HIGH
SC17 Supply-chain safe pattern for pip install (get-pip.py) LOW
SC18 Supply-chain safe pattern for npm install (npm install) LOW
SC19 Supply-chain safe pattern for Dockerfile apt cleanup LOW
SC20 Supply-chain safe pattern for Dockerfile user-setup LOW
SC21 Supply-chain safe pattern for Dockerfile chown LOW
SC22 Supply-chain safe pattern for non-Dockerfile rm-rf HIGH
SC23 Supply-chain safe pattern for generic script download HIGH

Trigger Word Patterns (TR1–TR5)

Implemented in static_patterns_supply_chain.py:

Pattern ID Description Default Severity
TR1 Overly-broad trigger word (e.g., "the") LOW
TR2 Shadow-builtin command trigger (e.g., "help") LOW
TR3 Keyword baiting trigger (e.g., "anything") LOW
TR4 Future-proof placeholder LOW
TR5 Future-proof placeholder LOW

Legacy Security Patterns (P1–P5, E1–E2, PE3)

Implemented in static_patterns.py:

Pattern ID Description Default Severity
P1 Deprecated "python-2" pattern (legacy) MEDIUM
P2 Insecure exec-style usage (legacy) HIGH
P3 Hard-coded credentials (legacy) CRITICAL
P4 Insecure command construction (legacy) HIGH
P5 Unsafe file-write pattern (legacy) MEDIUM
E1 Environment-variable leakage (legacy) HIGH
E2 Exposed secret via logs (legacy) HIGH
PE3 Poor encryption usage (legacy) CRITICAL

Tool Poisoning Patterns (TP1–TP4)

Implemented in static_patterns_tool_poisoning.py:

Pattern ID Description Default Severity
TP1 Zero-width char injection (tool-poisoning) HIGH
TP2 Base64-encoded payload (tool-poisoning) HIGH
TP3 Data-URI script injection (tool-poisoning) HIGH
TP4 Mixed-confidence script injection (tool-poisoning) MEDIUM or HIGH

Least Privilege Patterns (LP1–LP4)

Implemented in static_patterns_least_privilege.py:

Pattern ID Description Default Severity
LP1 Least-privilege under-declared permission HIGH
LP2 Least-privilege safe pattern LOW
LP3 Least-privilege moderate pattern MEDIUM
LP4 Least-privilege low-risk pattern LOW

Model Information Patterns (ML1–ML3)

Implemented in model_info.py:

Pattern ID Description Default Severity
ML1 Model-info mismatch (LLM provider) HIGH
ML2 Model-info low-risk discrepancy MEDIUM
ML3 Model-info safe discrepancy LOW

How Severity Is Assigned in the Source Code

When analyzers detect a vulnerability, they construct a Finding object by passing the severity directly from the Severity enum. For example, in static_patterns_output_handling.py, the OH1 pattern for direct code execution is flagged with HIGH severity:


# Example from static_patterns_output_handling.py

if re.search(r'\b(exec|eval|subprocess\.run)\b', content):
    findings.append(
        Finding(
            rule_id="OH1",
            message="Potential code execution via exec/eval/subprocess.run",
            severity=Severity.HIGH,
            confidence=0.95,
            matched_text=matched,
        )
    )

This pattern is repeated across all analyzer modules, with each module importing Severity from skillspector/models.py and assigning the appropriate level based on the potential impact of the vulnerability.

Verification Through Unit Tests

The severity mapping for all 64 patterns is immutable and verified through unit tests in tests/unit/test_patterns_new.py and tests/unit/test_patterns.py. These tests assert that every generated Finding matches its expected severity level, ensuring that any code modification that alters severity assignments will cause immediate test failures. This guarantees that the severity catalog remains synchronized with the source code implementation.

Summary

  • SkillSpector defines 64 vulnerability patterns across twelve analyzer modules, each targeting specific security risks in AI agents and dependencies.
  • Four severity levels (CRITICAL, HIGH, MEDIUM, LOW) are defined in skillspector/models.py and assigned based on potential impact or CVSS scores for supply chain vulnerabilities.
  • Supply chain patterns (SC2–SC23) constitute the largest category with 22 patterns, dynamically mapping OSV CVSS scores to SkillSpector severity levels.
  • Legacy patterns (P1–P5, E1–E2, PE3) maintain backward compatibility while still enforcing critical security checks like hard-coded credentials detection.
  • Unit test enforcement in test_patterns_new.py ensures severity assignments remain immutable and accurate across versions.

Frequently Asked Questions

How does SkillSpector determine severity for OSV-based vulnerabilities?

SkillSpector queries the Open Source Vulnerabilities (OSV) database and maps the returned CVSS vector to SkillSpector severity levels. According to the logic in static_patterns_supply_chain.py, CVSS scores ≥ 9.0 map to CRITICAL, scores between 7.0–8.9 map to HIGH, 4.0–6.9 map to MEDIUM, and scores below 4.0 map to LOW.

Can the default severity levels be customized or overridden?

No, the severity mapping is immutable by design. The unit tests in tests/unit/test_patterns_new.py enforce strict assertions that each pattern ID must emit findings with specific severity levels. Any modification to these assignments would cause test failures, ensuring consistent risk scoring across all SkillSpector deployments.

Which patterns are classified as CRITICAL severity?

Only three patterns carry CRITICAL severity: P3 (Hard-coded credentials) and PE3 (Poor encryption usage) from the legacy analyzer, and SC8/SC9 (npm/PyPI packages with known CVEs) when the OSV CVSS score exceeds 9.0. These represent the most severe security risks requiring immediate remediation.

What is the difference between SC2 and SC16 supply chain patterns?

SC2 detects downloads from trusted sources (e.g., curl https://astral.sh/uv/install.sh) and receives LOW severity because the domain is verified. SC16 detects downloads from untrusted domains and receives HIGH severity due to the elevated risk of malicious script injection. Both patterns are evaluated in static_patterns_supply_chain.py using domain reputation heuristics.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →