Static Analysis Analyzers in SkillSpector: Complete Security Scanning Guide

SkillSpector includes twelve static analysis analyzers—one YARA-based malware detector and eleven pattern-matching security checks—that scan skill source files for threats like prompt injection, privilege escalation, and data exfiltration without executing the code.

SkillSpector is NVIDIA's open-source security framework designed to assess AI skill safety through comprehensive static and dynamic analysis. The static analysis analyzers in SkillSpector serve as the initial defense layer, examining skill artifacts for malicious signatures and vulnerable code patterns before any LLM execution occurs. Located in src/skillspector/nodes/analyzers/, these analyzers operate through a unified execution model that converts raw findings into SARIF-compatible security reports.

Core Architecture and Shared Utilities

All static analyzers follow a consistent interface defined in the shared runner infrastructure. The static_runner.py file provides common constants and conversion utilities used across the analysis pipeline.

The static_runner.py Utility

The src/skillspector/nodes/analyzers/static_runner.py file defines two critical components:

  • MAX_FILE_BYTES: A constant enforcing the maximum file size limit for scanned artifacts
  • analyzer_finding_to_finding(): A helper function that converts raw AnalyzerFinding objects into the standardized SARIF-compatible format used throughout the SkillSpector pipeline

Node Execution Pattern

Each analyzer implements a standardized entry point:

def node(state: SkillspectorState) -> AnalyzerNodeResponse:
    # Analyzer implementation

The state dictionary contains state["components"] and state["file_cache"], providing access to the skill's source files and metadata. The main orchestration graph in src/skillspector/graph.py invokes each static node sequentially, aggregating findings into the final security report.

YARA-Based Malware Detection

The static_yara analyzer provides signature-based threat detection against known malware patterns.

static_yara.py Implementation

Located at src/skillspector/nodes/analyzers/static_yara.py, this analyzer executes curated and user-supplied YARA rules against skill artifacts. It detects:

  • Malware signatures and payloads
  • Web shells and backdoors
  • Cryptocurrency miners
  • Known malicious code patterns

Pattern-Based Security Analyzers

The remaining eleven analyzers use static pattern matching to identify specific vulnerability classes. Each resides in its own file under src/skillspector/nodes/analyzers/ and targets distinct security concerns.

Prompt and System Security

  • static_patterns_prompt_injection: Identifies patterns allowing users to inject malicious prompts into the LLM's system prompt, potentially hijacking model behavior
  • static_patterns_system_prompt_leakage: Detects accidental leakage of system prompt text into skill code, which could expose privileged instructions or internal configuration

Privilege and Agency Controls

  • static_patterns_privilege_escalation: Scans for code that unintentionally grants skills higher privileges than intended, such as unauthorized permission requests
  • static_patterns_excessive_agency: Flags code granting excessive autonomy, including unbounded loops, unrestricted network calls, or unsupervised tool execution
  • static_patterns_rogue_agent: Detects self-modifying code, hidden network calls, or other patterns that could transform a skill into a malicious autonomous agent

Data Protection and Supply Chain

  • static_patterns_data_exfiltration: Identifies patterns that could lead to unauthorized data transmission, such as sending files to external endpoints
  • static_patterns_supply_chain: Flags supply-chain security concerns including hard-coded URLs, insecure imports, suspicious dependencies, and compromised package references

Content Safety and Output Handling

  • static_patterns_harmful_content: Detects static patterns that could generate harmful content, including hate speech, self-harm instructions, or dangerous advice
  • static_patterns_output_handling: Checks for insecure processing of LLM outputs, such as unsanitized string interpolation or unsafe file write operations
  • static_patterns_memory_poisoning: Identifies code that could poison the model's memory or context, such as inserting large irrelevant strings to manipulate context windows

Tool Usage Safety

  • static_patterns_tool_misuse: Detects patterns indicating unsafe tool API usage, such as calling tools with improper validation or dangerous argument patterns

Execution Flow and Integration

The static analysis pipeline follows a specific execution sequence orchestrated by the main SkillSpector graph.

Analysis Pipeline Steps

  1. File Discovery: The system populates state["components"] and state["file_cache"] with skill source files
  2. Size Validation: MAX_FILE_BYTES limits prevent analysis of excessively large files
  3. Node Invocation: Each analyzer's node() function receives the state and returns AnalyzerNodeResponse
  4. Finding Conversion: analyzer_finding_to_finding() standardizes raw findings into SARIF-compatible structures
  5. Aggregation: Results from src/skillspector/nodes/analyzers/static_*.py files merge into the final report via src/skillspector/graph.py

Data Models and Output

The analyzers rely on data structures defined in src/skillspector/models.py and src/skillspector/sarif_models.py. These models ensure compatibility with SARIF (Static Analysis Results Interchange Format), enabling integration with standard security tools and reporting platforms.

Summary

  • SkillSpector includes twelve specialized static analyzers located in src/skillspector/nodes/analyzers/ that perform non-executable security scanning
  • YARA-based detection (static_yara.py) identifies malware using signature matching against curated threat databases
  • Pattern analyzers cover eleven distinct threat categories including prompt injection, privilege escalation, data exfiltration, and supply chain vulnerabilities
  • Shared infrastructure in static_runner.py provides size limits (MAX_FILE_BYTES) and SARIF conversion utilities
  • Unified interface requires each analyzer to implement node(state: SkillspectorState) -> AnalyzerNodeResponse, orchestrated by src/skillspector/graph.py
  • SARIF-compatible output ensures findings integrate with standard security reporting tools and vulnerability management systems

Frequently Asked Questions

What is the difference between the YARA analyzer and pattern-based analyzers in SkillSpector?

The static_yara analyzer uses signature-based detection against curated YARA rules to identify known malware, web shells, and crypto-miners. The eleven pattern-based analyzers (static_patterns_*.py) use custom logic to detect specific code patterns indicating vulnerabilities like privilege escalation or prompt injection, rather than matching known malware signatures.

How does SkillSpector handle large files during static analysis?

The static_runner.py enforces a MAX_FILE_BYTES constant that limits the size of files processed by analyzers. This prevents memory exhaustion and ensures consistent performance when scanning skill artifacts containing large dependencies or data files.

Can I add custom YARA rules to SkillSpector's static analysis?

Yes. The static_yara.py analyzer supports both curated default rules and user-supplied YARA rules, allowing security teams to extend malware detection capabilities with organization-specific threat signatures or updated indicators of compromise.

What format do the static analyzers output for security findings?

All analyzers output findings through the analyzer_finding_to_finding() helper, converting raw AnalyzerFinding objects into SARIF-compatible structures defined in src/skillspector/sarif_models.py. This standardized format enables integration with vulnerability management platforms and code scanning tools.

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 →