skipLink.label

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

PatternSeverityExample
Hardcoded secretscriticalpassword = "admin123"
eval() usagecriticaleval(userInput)
HTTP without TLShighfetch("http://api.example.com")
Missing input validationhighreq.body without sanitization
Prototype pollutionhighObject.assign({}, userInput)

Context Matters

// ❌ HARDCODED SECRET — this is dangerous
const password = "admin123";
// ✅ READING FROM REQUEST — this is normal
const { password } = req.body;
// ❌ EVAL WITH USER INPUT — critical vulnerability
eval(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 password in it → hardcoded secret!” → const { password } = req.body is 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 removeEventListener is medium. Treating everything as critical means developers start ignoring alerts.

Mistake 3: Only checking variable names, not values

“It’s called password so it must be a secret” → A variable named password holding req.body.password is fine. A variable named pw holding "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 from http:// in a fetch() 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.

  1. Download ไฟล์เริ่มต้นของ quest:

    Terminal window
    npx bluebeltdojo download quest-85-security-review
    cd quest-85-security-review
  2. เปิด problem.js ใน editor ของคุณพร้อมความช่วยเหลือของ AI

  3. 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.assign with user input)
  4. Critical edge case: Don’t flag destructured imports like const { password } = req.body

  5. ตรวจสอบ solution ของคุณ:

    Terminal window
    node test.js
  6. When all tests pass, submit your solution:

    Terminal window
    npx bluebeltdojo submit

💡 Tip: The hardest part is distinguishing password = "secret" (hardcoded) from const { 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