π Security
AgentRegistry is designed for localhost security with multiple protection layers.
β οΈ LOCALHOST ONLY
AgentRegistry is hardened for local use only. Do not expose it to the public internet or use it in multi-user production environments.
Overview
AgentRegistry implements a defense-in-depth approach with multiple security layers:
- Network-level binding to localhost only
- Host header validation
- Input sanitization and validation
- Real-time static analysis
- Quarantine system for upstream packages
- Audit logging for all security events
Protection Layers
| Layer | Protection |
|---|---|
| Network | Binds to 127.0.0.1 only (not 0.0.0.0) |
| Host Check | Rejects non-localhost hosts (403) |
| Input Validation | Strict regex for names/versions |
| Path Traversal | Blocks ../, null bytes, strict basename() checks |
| XSS Protection | Output encoding via escapeHtml() on all render paths |
| Length Limits | Package names max 214 chars |
| Security Scanner | Static analysis before caching (~10-50ms) |
| Quarantine | All upstream packages scanned first |
Quarantine Flow
All packages fetched from npmjs.org pass through security scanning before becoming available:
npm install lodash
β
π₯ Download from npmjs.org
β
π Write to storage/quarantine/
β
π Security scan (~10-50ms)
β
β
SAFE β Move to storage/tarballs/ + cache
π¨ BLOCKED β Stays in quarantine, returns 403β‘ Auto-Allow for Local Publishes
By default, packages published locally via
npm publish --registry http://localhost:4873
bypass quarantine and security scanning for faster agent workflows.
This behavior can be toggled in the Admin Panel β Quarantine tab, or via WebSocket API
(setAutoAllowSetting).
Blocked Package Response
When a package is blocked, AgentRegistry returns an agent-friendly JSON response:
{
"error": "Package blocked by security scan",
"action_required": "HUMAN INTERVENTION REQUIRED",
"instructions": [
"Visit admin panel at http://localhost:4873/-/admin",
"Navigate to Quarantine tab",
"Review the security issues",
"Either approve or delete the package"
],
"quarantine_location": "storage/quarantine/lodash-4.17.21.tgz"
}Security Scanner
AgentRegistry performs SOTA-level static analysis based on OWASP/CWE patterns and 2025-2026 academic research on prompt injection evasion techniques.
What's Scanned
| Severity | Patterns Detected |
|---|---|
| Critical |
eval(), new Function()curl|sh, remote code loadingProcess spawn with shell commands |
| High |
child_process, exec()SSH/npmrc access Base64-encoded payloads |
| Medium |
File system writes.env accessPrototype pollution patterns |
| Low | process.env access |
Prompt Injection Scanner β 10-Pass Architecture
The prompt injection scanner uses a research-backed 10-pass analysis pipeline to detect LLM manipulation attempts hidden in package metadata, READMEs, and code comments.
| Pass | Technique | Catches |
|---|---|---|
| 1 | Raw content scan | Literal injection patterns in 5 languages (EN, IT, ES, FR, DE) |
| 2 | Unicode normalization + homoglyphs | Cyrillic/Greek/fullwidth char substitution (75 mappings) |
| 3 | Leetspeak decode | 1gn0r3 4ll pr3v10us 1nstruct10ns |
| 4 | ROT13 decode | ROT13-encoded payloads |
| 5 | FlipAttack reversal | Character-reversed injection strings |
| 6 | Reconstruction patterns | String.fromCharCode(), reverse().join() |
| 7 | Policy Puppetry | Config format mimicry (INI/JSON/XML/YAML safety overrides) |
| 8 | MCP injection | Tool description injection, line jumping attacks |
| 9 | Adversarial suffix | GCG-style high-entropy gibberish (Shannon entropy analysis) |
| 10 | Invisible characters | Zero-width joiners, tag characters, BiDi overrides |
π Cross-Field Payload Splitting
Metadata fields (name, description, keywords,
homepage) are concatenated and rescanned to catch payloads split across multiple
fields that would evade per-field detection.
Evasion Resistance
| Attack Vector | Source | Detection Method |
|---|---|---|
| Homoglyph substitution | ACL 2025 (42-59% ASR) | NFKD + character map normalization |
| Leetspeak obfuscation | HiddenLayer, April 2025 | Digitβletter substitution |
| Policy Puppetry | HiddenLayer, April 2025 | Config format pattern matching |
| FlipAttack | ACL 2025 (98% GPT-4o bypass) | Reverse content scanning |
| GCG adversarial suffixes | Zou et al., 2023 | Shannon entropy + punctuation analysis |
| Payload splitting | OWASP LLM01:2025 | Cross-field concatenation |
| MCP line jumping | MCP security research, 2025 | Tool description pattern matching |
| Invisible Unicode | Unicode Consortium TR36 | Zero-width/tag character detection |
π§ͺ Test Coverage
154 prompt injection tests (30 SOTA adversarial) Β· 100% line coverage Β· 97% function coverage
Research References
- Zou et al. β Universal and Transferable Adversarial Attacks on Aligned Language Models (GCG, 2023)
- HiddenLayer β Policy Puppetry: A Universal Jailbreak for LLMs (April 2025)
- ACL 2025 β FlipAttack: Jailbreak LLMs via Flipping (78.97% ASR, 98% GPT-4o bypass)
- ACL 2025 β Homoglyph Attack Analysis on LLM Safety Filters (42-59% success rate)
- OWASP β Top 10 for LLM Applications 2025 (LLM01: Prompt Injection)
- MCP Security Research β Tool Description Injection via Line Jumping (2025)
- Unicode Consortium β TR36: Unicode Security Considerations
- npm Supply Chain Incidents β Shai-Hulud worm, Chalk/Debug attack, Contagious Interview campaign (2024-2025)
Performance
The security scanner is optimized for speed:
- Average scan time: ~10-50ms depending on package size (all 10 passes)
- Scans all JavaScript files in the tarball
- Uses streaming extraction to minimize memory
π¬ AST Deep Scanner π§ͺ Experimental
β οΈ Scope & Limitations
The AST deep scanner is one possible approach to complementing regex-based scanning with lightweight AST analysis. It is well-tested (179 tests, constant propagation, 9 detection patterns) and effective within its scope, but it is not a replacement for dedicated static analysis tools like Semgrep or CodeQL. See known limitations below for details.
Use it as an additional signal, not as a sole security gate.
What It Does
The deep scanner parses JavaScript/TypeScript files into Abstract Syntax Trees (AST) using
acorn and walks the tree looking for suspicious patterns that regex cannot
reliably detect β particularly obfuscated execution patterns.
Detected Patterns (9)
| Pattern | Severity | Detects |
|---|---|---|
dynamic_require |
Critical | require(variable) β runtime-computed module loading |
eval_family |
Critical | eval(), new Function() β dynamic code execution |
encoded_payload_exec |
Critical | eval(atob(...)), Function(Buffer.from(...)) |
process_spawn |
Critical | child_process.exec(), spawn() with shell commands |
network_exfiltration |
Critical | Outbound HTTP with sensitive data (env, ssh,
token)
|
computed_member_exec |
High | global["ev"+"al"]() β bracket-notation invocation |
prototype_pollution |
High | Writes to __proto__, constructor.prototype |
timer_obfuscation |
Medium | setTimeout("code", 0) β string-based deferred execution |
iife_with_suspicious_args |
Medium | Immediately-invoked functions with encoded/suspicious arguments |
Constant Propagation
The scanner includes lightweight constant propagation: when it encounters
const name = "literal", it tracks the value so that later usage of name
can be resolved. This catches patterns like:
const fn = "eval";
const payload = "alert(1)";
global[fn](payload); // Detected as computed_member_execKnown Limitations
π What It Does NOT Do
- β No data-flow analysis β cannot track values across function boundaries
- β No interprocedural analysis β limited to single-file, single-scope
- β No control-flow analysis β no dead code detection or branch analysis
- β No dynamic analysis β no sandbox execution or runtime behavior
- β Expression-based constants not tracked β only
const x = "literal", notconst x = a + b - β Cannot detect multi-stage payloads spread across files
- β Minified/bundled code may produce false positives
How to Use
Deep scan is opt-in only β it never runs automatically during publish or quarantine.
- CLI:
agentregistry scan --deep <file-or-dir> - Admin Panel β Scans: Click "π¬ Scan" on any scanned package
- Admin Panel β Quarantine: Click "π¬ Deep Scan" on quarantined packages
π§ͺ Test Coverage
179 test cases Β· 100% function coverage Β· 99.41% line coverage
Package Allowlist
The Package Allowlist allows you to skip security scanning for trusted packages. This improves performance for known-safe dependencies.
How It Works
Packages matching an allowlist pattern bypass the security scanner entirely and are immediately cached without quarantine.
π¦ Categories
- verified β Core npm packages (lodash, express, etc.)
- build-tools β Bundlers, compilers, transpilers
- testing β Test frameworks (jest, vitest, mocha)
- observability β Logging and monitoring packages
- browser β Browser automation (puppeteer, playwright)
- custom β User-added patterns
Pattern Types
| Pattern | Matches |
|---|---|
lodash |
Exact match only |
@opentelemetry/ |
All packages in scope (e.g., @opentelemetry/api) |
sentry- |
All packages starting with prefix (e.g., sentry-sdk) |
Managing via Admin Panel
Navigate to Security β Package Allowlist to:
- Enable/disable the entire allowlist
- Filter by category
- Add custom package patterns
- Toggle individual entries on/off
π‘ Default Entries
AgentRegistry ships with ~60 default trusted packages. Default entries cannot be deleted, only disabled.
Input Validation
Package Names
/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/i- Max 214 characters
- Supports scoped packages (
@scope/name) - No special characters except
-._~
Versions
Strict semver validation with support for pre-release tags.
Path Containment
All file operations are validated to stay within storage/:
- Blocks
../(path traversal) - Blocks URL-encoded variants (
..%2F) - Blocks null bytes
- Validates resolved path starts with storage directory
Limitations
Designed For
- β Local agent-to-agent package sharing
- β Development and testing
- β Private package hosting on localhost
Not For
- β Public internet exposure
- β Multi-user production environments
- β High-security enterprise deployments
Known Limitations
- Static analysis cannot detect all malicious patterns
- Advanced obfuscation (AST-level transforms, JIT-compiled payloads) may bypass detection
- No sandbox execution testing
- Common obfuscation (leetspeak, homoglyphs, ROT13, reversed text) is detected by the 10-pass scanner
π‘ Best Practices
Always review quarantined packages before approving. When in doubt, delete the package and investigate the security issues reported.