Skip to content

Whole-package analysis

Razin analyzes the directory containing each SKILL.md without importing or executing package code. The analyzer is deterministic and bounded. It:

  • hashes scanned paths, contents, sizes, and file modes into a versioned SHA-256 coverage digest;
  • parses Python helpers with the standard-library AST;
  • applies conservative source-to-sink correlations to JavaScript, TypeScript, and shell helpers;
  • links helper findings to file references in SKILL.md;
  • checks mutable GitHub/GitLab branch references;
  • matches operator-configured known-bad domains, file hashes, and literal IOCs;
  • emits explicit analysis gaps for limits, parse failures, symlinks, archives, compiled binaries, and unsupported source languages.

Source and sink presence alone is not an attack-chain finding. For example, an API token used only in an Authorization header is not treated as data exfiltration. PACKAGE_DATA_EXFILTRATION requires a correlated sensitive value in outbound body/data content. PACKAGE_REMOTE_CODE_EXECUTION requires remote content to reach an execution sink, or a declared executable helper that pipes a download directly to a shell. This is high-priority dangerous behavior, but does not by itself make a malicious-intent claim.

Bounds

package_analysis:
  enabled: true
  max_files: 256
  max_directories: 128
  max_total_mb: 16
  max_file_mb: 2
  max_findings_per_rule: 20
  emit_inventory: false

The defaults prevent a package from forcing unbounded filesystem work or unbounded output. Reaching a limit produces INCOMPLETE_SCAN; it does not make the package appear fully covered. Archives, binary executables, and unsupported source languages produce DYNAMIC_ANALYSIS_REQUIRED.

emit_inventory is off by default so inventory alone does not change a package from no-actionable-malicious-evidence to capability-only. API callers can use the package analyzer's deterministic manifest and versioned coverage digest directly; enabling this setting also emits a PACKAGE_INVENTORY capability finding.

The v3 package-analysis digest binds the bounded static inventory and its package-level coverage markers. It is not an execution-approval or sandbox snapshot digest: outer parsing and MCP failures are reported separately in coverage_reasons.

Known-bad indicators

Razin has no implicit threat-intelligence feed. Configured indicator findings are only as current and trustworthy as the values you configure:

package_analysis:
  known_bad:
    domains:
      - webhook.example
    sha256:
      - "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
    indicators:
      - campaign-marker-123

Domain matching includes subdomains. Hashes must be full 64-character SHA-256 values. Literal indicators are matched case-insensitively. An exact file-hash match is treated as a strong IOC; domain and literal matches remain review signals because context can make them ambiguous. Keep these lists small, reviewed, and provenance-backed.

Supported and unsupported content

Python (.py), JavaScript/TypeScript (.js, .jsx, .mjs, .cjs, .ts, .tsx), and shell (.sh, .bash, .zsh) receive helper behavior analysis. Recognized source files outside those languages, such as Go, Rust, Ruby, PHP, Java, Kotlin, Swift, PowerShell, Lua, Perl, and R, are explicitly reported as requiring additional analysis.

Razin does not follow symlinks, unpack archives, emulate programs, make network requests, or run package installation hooks.