eigent/resources/example-skills/skill-security-auditor/references/vulnerability-patterns.md
statxc 31828e68b8
Some checks failed
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 4s
CodeQL Advanced / Analyze (actions) (push) Failing after 4s
CodeQL Advanced / Analyze (python) (push) Failing after 3s
Test / Run Python Tests (push) Failing after 30s
Pre-commit / pre-commit (push) Failing after 36s
feat: add skill-security-auditor as default example skill (#1479)
Co-authored-by: Tao Sun <168447269+fengju0213@users.noreply.github.com>
2026-03-18 18:43:12 +08:00

6.8 KiB

Vulnerability Patterns Reference

Detailed patterns for identifying security vulnerabilities across languages and frameworks.

Table of Contents

Injection Vulnerabilities

SQL Injection

Vulnerable patterns (string concatenation or f-strings in queries):

# Python
execute(f"...{var}...")
execute("..." + var + "...")
execute("...%s..." % var)

# JavaScript
query(`...${var}...`)
query("..." + var + "...")

# Go
db.Query("..." + var + "...")
fmt.Sprintf("SELECT ... %s", var) passed to Query()

# Java
statement.execute("..." + var + "...")

Safe alternatives: Parameterized queries, prepared statements, ORM query builders.

NoSQL Injection

Vulnerable patterns:

// MongoDB: user input directly in query object
db.collection.find({ user: req.body.user, pass: req.body.pass })
// Attacker sends: { "pass": { "$gt": "" } }

Safe alternative: Validate input types, use $eq explicitly, sanitize with libraries like mongo-sanitize.

Command Injection

Vulnerable functions by language:

Python:  os.system(), os.popen(), subprocess.call(shell=True), subprocess.Popen(shell=True)
Node.js: child_process.exec(), child_process.execSync()
Go:      exec.Command("sh", "-c", userInput)
Java:    Runtime.exec(userInput)
PHP:     exec(), system(), passthru(), shell_exec(), backticks
Ruby:    system(), exec(), backticks, %x{}

Safe alternative: Use subprocess with list arguments (no shell), validate and allowlist input values.

LDAP Injection

Vulnerable pattern:

ldap.search_s(base, scope, f"(uid={username})")

Safe alternative: Escape special characters ()*\ and null bytes in user input.

XSS (Cross-Site Scripting)

Vulnerable sinks:

JavaScript: innerHTML, outerHTML, document.write(), eval(), v-html, dangerouslySetInnerHTML
Template:   |safe, {% autoescape off %}, !=, !{}, {!! !!}

Safe alternatives: Use textContent, template auto-escaping, CSP headers, DOMPurify for required HTML.

Authentication and Session Issues

Weak Password Storage

Vulnerable:

# Plaintext or weak hashing
hashlib.md5(password.encode()).hexdigest()
hashlib.sha256(password.encode()).hexdigest()

Safe:

# Use adaptive hashing with salt
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))

JWT Vulnerabilities

Common issues:

  • Accepting alg: "none"
  • Using symmetric algorithms (HS256) with public keys
  • Not validating expiry (exp) or issuer (iss)
  • Storing sensitive data in payload (JWT is base64, not encrypted)

Verification checklist:

# Ensure algorithm is explicitly specified
jwt.decode(token, key, algorithms=["RS256"])  # explicit algorithm
jwt.decode(token, key)  # VULNERABLE: accepts any algorithm

Session Management

Issues to flag:

  • Session IDs in URLs
  • Missing HttpOnly, Secure, SameSite flags on session cookies
  • No session timeout or rotation after authentication
  • Predictable session identifiers

Cryptographic Weaknesses

Insecure Algorithms

Deprecated/broken (flag if found):

Hash:    MD5, SHA1 (for security purposes)
Cipher:  DES, 3DES, RC4, Blowfish
Mode:    ECB mode for any block cipher
RSA:     Key size < 2048 bits

Acceptable:

Hash:    SHA-256, SHA-384, SHA-512, BLAKE2
Cipher:  AES-128/256-GCM, ChaCha20-Poly1305
RSA:     2048+ bits with OAEP padding
ECDSA:   P-256 or P-384 curves

Hardcoded Cryptographic Material

Flag if found in source:

  • Encryption keys, IV/nonce values
  • Private keys (RSA, ECDSA, Ed25519)
  • Salt values for password hashing

Insecure Deserialization

Vulnerable functions by language:

Python:  pickle.loads(), yaml.load() (without SafeLoader), marshal.loads()
Java:    ObjectInputStream.readObject(), XMLDecoder
PHP:     unserialize()
Ruby:    Marshal.load(), YAML.load()
Node.js: node-serialize, js-yaml.load() (with dangerous schema)

Safe alternatives: Use JSON for data exchange, use safe loaders (yaml.safe_load()), validate and type-check deserialized data.

Server-Side Request Forgery

Vulnerable pattern:

# User controls the URL
requests.get(user_provided_url)
urllib.request.urlopen(user_provided_url)

Mitigations:

  • Validate URLs against an allowlist of domains/IPs
  • Block requests to internal/private IP ranges (10.x, 172.16-31.x, 192.168.x, 127.x, 169.254.x)
  • Disable redirects or validate redirect targets
  • Use a network-level firewall for outbound requests

File Operations

Path Traversal

Vulnerable pattern:

# User controls filename
open(os.path.join(base_dir, user_filename))

Safe pattern:

import pathlib
base = pathlib.Path(base_dir).resolve()
target = (base / user_filename).resolve()
if not str(target).startswith(str(base)):
    raise ValueError("Path traversal detected")

Unrestricted File Upload

Checklist:

  • Validate file type by content (magic bytes), not just extension
  • Enforce maximum file size limits
  • Store uploads outside the web root
  • Generate random filenames, do not use user-supplied names
  • Scan uploads for malware when possible

Framework-Specific Patterns

Django

# Dangerous: raw SQL
Model.objects.raw(f"SELECT * FROM t WHERE id = {user_id}")
# Safe: ORM or parameterized raw
Model.objects.filter(id=user_id)
Model.objects.raw("SELECT * FROM t WHERE id = %s", [user_id])

# Check settings.py
DEBUG = True                      # Must be False in production
ALLOWED_HOSTS = ['*']            # Must be restricted
CSRF_COOKIE_SECURE = False       # Must be True with HTTPS
SESSION_COOKIE_SECURE = False    # Must be True with HTTPS

Flask

# Dangerous: XSS via Markup
from markupsafe import Markup
return Markup(f"<p>{user_input}</p>")
# Safe: Use templates with auto-escaping
return render_template("page.html", data=user_input)

# Check for debug mode
app.run(debug=True)  # Must be False in production

Express.js

// Missing security headers - use helmet
const helmet = require('helmet');
app.use(helmet());

// Missing CSRF protection on state-changing routes
// Missing rate limiting on auth endpoints
// Missing input validation (use express-validator or zod)

Spring Boot

// Dangerous: SpEL injection
parser.parseExpression(userInput).getValue();

// Check application.properties
server.error.include-stacktrace=always  // Leaks internals
management.endpoints.web.exposure.include=*  // Exposes actuator