Security Review Automator
Quest 85: Security Review Automator
medium 25-30 minutes🎯 Learning Objectives
- How to build automated security scanners that catch common vulnerabilities
- Why Security by Default means catching issues before they reach production
- How to detect hardcoded secrets, eval usage, HTTP without TLS, and prototype pollution
- The critical difference between reading secrets and hardcoding them
📖 Concept: Security by Default
The OWASP Top 10 lists the most critical web application security risks. Many of them — injection, broken authentication, sensitive data exposure — can be caught by simple pattern matching in source code. A security review automator scans code for these patterns and flags them before the code ever reaches production.
The core principle is Security by Default: instead of relying on developers to remember every security rule, you automate the checks. Just like linting catches style issues automatically, security scanning catches vulnerability patterns automatically.
The tricky part is context. A naive scanner flags every line containing password as a hardcoded secret — but const { password } = req.body is reading a password from a request, not hardcoding one. Context-aware scanning is what separates a useful security tool from a noisy one.
⚙️ How It Works
Security Patterns We Detect
| Pattern | Severity | Example |
|---|---|---|
| Hardcoded secrets | critical | password = "admin123" |
eval() usage | critical | eval(userInput) |
| HTTP without TLS | high | fetch("http://api.example.com") |
| Missing input validation | high | req.body without sanitization |
| Prototype pollution | high | Object.assign({}, userInput) |
Context Matters
// ❌ HARDCODED SECRET — this is dangerousconst password = "admin123";
// ✅ READING FROM REQUEST — this is normalconst { password } = req.body;
// ❌ EVAL WITH USER INPUT — critical vulnerabilityeval(req.query.code);
// ✅ JSON.parse (safe alternative)JSON.parse(req.query.data);💡 Example: Security Review in Action
Consider this Express.js route handler:
app.post('/login', (req, res) => { const api_key = "sk-12345"; const query = `SELECT * FROM users WHERE name='${req.body.name}'`; eval(req.body.callback); fetch("http://api.internal/verify"); Object.assign(config, req.body.settings);});A security scanner would flag:
[ { "severity": "critical", "type": "hardcoded-secret", "line": 2, "message": "Hardcoded API key detected" }, { "severity": "critical", "type": "eval-usage", "line": 4, "message": "eval() with user input — SQL injection risk" }, { "severity": "high", "type": "http-no-tls", "line": 5, "message": "HTTP without TLS — data transmitted in plaintext" }, { "severity": "high", "type": "prototype-pollution", "line": 6, "message": "Object.assign with user input — prototype pollution risk" }]⚠️ Common Mistakes
Mistake 1: Flagging destructured imports as hardcoded secrets
“Line has
passwordin it → hardcoded secret!” →const { password } = req.bodyis READING from a request, not hardcoding. Check whether the assignment comes from a literal string or from an external source.
Mistake 2: Ignoring severity levels
“All security issues are critical” → A hardcoded password is critical. A missing
removeEventListeneris medium. Treating everything as critical means developers start ignoring alerts.
Mistake 3: Only checking variable names, not values
“It’s called
passwordso it must be a secret” → A variable namedpasswordholdingreq.body.passwordis fine. A variable namedpwholding"admin123"is dangerous. Check the VALUE, not just the name.
Mistake 4: Missing HTTP scheme detection
“I’ll just check for
http://anywhere in the code” →http://in a comment is different fromhttp://in afetch()call. Focus on HTTP requests specifically, not all text.
📝 Knowledge Check
📝 Knowledge Check
Q1:Why should `const { password } = req.body` NOT be flagged as a hardcoded secret?
Q2:Which of these is the MOST critical security issue a scanner should detect?
Q3:What is 'context-aware scanning' in the context of security review?
🏋️ Quest: Security Review Automator
Now it’s time to practice! Build a security scanner for source code.
-
Download ไฟล์เริ่มต้นของ quest:
Terminal window npx bluebeltdojo download quest-85-security-reviewcd quest-85-security-review -
เปิด
problem.jsใน editor ของคุณพร้อมความช่วยเหลือของ AI -
Implement the
securityReview(code)function that detects:- Hardcoded passwords/secrets (
password=,secret=,api_key=,token=) eval()usage- HTTP without TLS (
http://in fetch/axios/request) - Prototype pollution (
Object.assignwith user input)
- Hardcoded passwords/secrets (
-
Critical edge case: Don’t flag destructured imports like
const { password } = req.body -
ตรวจสอบ solution ของคุณ:
Terminal window node test.js -
When all tests pass, submit your solution:
Terminal window npx bluebeltdojo submit
💡 Tip: The hardest part is distinguishing
password = "secret"(hardcoded) fromconst { password } = req.body(reading). Look at what’s on the RIGHT side of the assignment.
คำใบ้
- ตรวจสอบว่าค่ามาจาก literal string หรือจาก external source
const { password } = req.bodyคือการอ่าน ไม่ใช่ hardcoding- ตรวจสอบ
http://เฉพาะใน HTTP requests (fetch,axios,request) ไม่ใช่ทุกที่ - ดู severity levels ที่ problem.js กำหนด — อย่าทำทุกอย่างเป็น critical