Created
July 15, 2025 04:24
-
-
Save adithyan-ak/fa2fb8158604d323adcf19f7e6be0694 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Vulnerable Web Application - Demo for Security Scanner Testing | |
| // WARNING: This code contains intentional security vulnerabilities | |
| // DO NOT USE IN PRODUCTION | |
| const express = require('express'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const crypto = require('crypto'); | |
| const { exec } = require('child_process'); | |
| const mysql = require('mysql2'); | |
| const mongodb = require('mongodb'); | |
| const libxml = require('libxmljs'); | |
| const app = express(); | |
| // Hardcoded credentials vulnerability | |
| const DB_PASSWORD = 'admin123'; | |
| const API_KEY = 'sk-1234567890abcdef'; | |
| const SECRET_TOKEN = 'hardcoded-secret-key-2024'; | |
| // Insecure randomness vulnerability | |
| function generateSessionId() { | |
| return Math.random().toString(36).substring(2, 15); | |
| } | |
| // Database connection with hardcoded credentials | |
| const dbConfig = { | |
| host: 'localhost', | |
| user: 'root', | |
| password: DB_PASSWORD, | |
| database: 'testdb' | |
| }; | |
| const connection = mysql.createConnection(dbConfig); | |
| app.use(express.urlencoded({ extended: true })); | |
| app.use(express.json()); | |
| // Vulnerable route with XSS | |
| app.get('/search', (req, res) => { | |
| const query = req.query.q; | |
| // XSS vulnerability - direct output without sanitization | |
| res.send(`<h1>Search Results for: ${query}</h1>`); | |
| }); | |
| // Vulnerable route with SQL Injection | |
| app.post('/login', (req, res) => { | |
| const { username, password } = req.body; | |
| // SQL Injection vulnerability - direct string concatenation | |
| const sql = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`; | |
| connection.execute(sql, (err, results) => { | |
| if (err) { | |
| res.status(500).send('Database error'); | |
| return; | |
| } | |
| if (results.length > 0) { | |
| const sessionId = generateSessionId(); | |
| res.cookie('sessionId', sessionId); | |
| res.json({ success: true, user: results[0] }); | |
| } else { | |
| res.status(401).json({ success: false }); | |
| } | |
| }); | |
| }); | |
| // Vulnerable route with NoSQL Injection | |
| app.post('/findUser', async (req, res) => { | |
| const { email, role } = req.body; | |
| try { | |
| const client = new mongodb.MongoClient('mongodb://localhost:27017'); | |
| await client.connect(); | |
| const db = client.db('userdb'); | |
| // NoSQL Injection vulnerability - direct object injection | |
| const user = await db.collection('users').findOne({ | |
| email: email, | |
| role: role | |
| }); | |
| res.json(user); | |
| client.close(); | |
| } catch (error) { | |
| res.status(500).json({ error: 'Database connection failed' }); | |
| } | |
| }); | |
| // Vulnerable route with Command Injection | |
| app.post('/backup', (req, res) => { | |
| const { filename } = req.body; | |
| // Command injection vulnerability - direct command execution | |
| exec(`tar -czf backup_${filename}.tar.gz /var/www/html`, (error, stdout, stderr) => { | |
| if (error) { | |
| res.status(500).send(`Error: ${error.message}`); | |
| return; | |
| } | |
| res.send(`Backup created: backup_${filename}.tar.gz`); | |
| }); | |
| }); | |
| // Vulnerable route with Path Traversal | |
| app.get('/files/:filename', (req, res) => { | |
| const filename = req.params.filename; | |
| // Path traversal vulnerability - no path sanitization | |
| const filepath = path.join(__dirname, 'uploads', filename); | |
| fs.readFile(filepath, 'utf8', (err, data) => { | |
| if (err) { | |
| res.status(404).send('File not found'); | |
| return; | |
| } | |
| res.send(data); | |
| }); | |
| }); | |
| // Vulnerable route with eval() injection | |
| app.post('/calculate', (req, res) => { | |
| const { expression } = req.body; | |
| try { | |
| // Code injection vulnerability - eval() with user input | |
| const result = eval(expression); | |
| res.json({ result: result }); | |
| } catch (error) { | |
| res.status(400).json({ error: 'Invalid expression' }); | |
| } | |
| }); | |
| // Vulnerable route with XXE | |
| app.post('/processXML', (req, res) => { | |
| const { xmlData } = req.body; | |
| try { | |
| // XXE vulnerability - XML parsing with external entities enabled | |
| const doc = libxml.parseXmlString(xmlData, { | |
| noent: true, | |
| dtdload: true | |
| }); | |
| res.json({ message: 'XML processed successfully', data: doc.toString() }); | |
| } catch (error) { | |
| res.status(400).json({ error: 'XML parsing failed' }); | |
| } | |
| }); | |
| // Vulnerable route with prototype pollution | |
| app.post('/updateSettings', (req, res) => { | |
| const settings = req.body; | |
| const userConfig = {}; | |
| // Prototype pollution vulnerability - recursive merge without validation | |
| function merge(target, source) { | |
| for (const key in source) { | |
| if (typeof source[key] === 'object' && source[key] !== null) { | |
| if (!target[key]) { | |
| target[key] = {}; | |
| } | |
| merge(target[key], source[key]); | |
| } else { | |
| target[key] = source[key]; | |
| } | |
| } | |
| } | |
| merge(userConfig, settings); | |
| res.json({ message: 'Settings updated', config: userConfig }); | |
| }); | |
| // Vulnerable route with ReDoS | |
| app.get('/validate-email', (req, res) => { | |
| const { email } = req.query; | |
| // ReDoS vulnerability - inefficient regex pattern | |
| const emailRegex = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{1,5}|[0-9]{1,3})(\]?)$/; | |
| if (emailRegex.test(email)) { | |
| res.json({ valid: true }); | |
| } else { | |
| res.json({ valid: false }); | |
| } | |
| }); | |
| // Vulnerable route with information disclosure | |
| app.get('/debug', (req, res) => { | |
| // Information disclosure vulnerability - exposing sensitive system info | |
| const debugInfo = { | |
| environment: process.env, | |
| version: process.version, | |
| platform: process.platform, | |
| uptime: process.uptime(), | |
| memory: process.memoryUsage(), | |
| secret: SECRET_TOKEN, | |
| dbPassword: DB_PASSWORD | |
| }; | |
| res.json(debugInfo); | |
| }); | |
| // Vulnerable CSRF endpoint | |
| app.post('/transfer', (req, res) => { | |
| const { amount, recipient } = req.body; | |
| // CSRF vulnerability - no CSRF protection | |
| // This would execute without proper token validation | |
| res.json({ | |
| message: `Transferred $${amount} to ${recipient}`, | |
| timestamp: new Date().toISOString() | |
| }); | |
| }); | |
| // Client-side JavaScript with vulnerabilities | |
| const clientSideCode = ` | |
| // Client-side vulnerabilities | |
| // XSS vulnerability in DOM manipulation | |
| function displayUserInput() { | |
| const userInput = document.getElementById('userInput').value; | |
| // XSS vulnerability - innerHTML with unsanitized input | |
| document.getElementById('output').innerHTML = userInput; | |
| } | |
| // Hardcoded API credentials | |
| const API_ENDPOINT = 'https://api.example.com/v1/'; | |
| const CLIENT_SECRET = 'client-secret-12345'; | |
| // Insecure randomness for session tokens | |
| function generateClientToken() { | |
| return Math.random().toString(36); | |
| } | |
| // Vulnerable AJAX request with XSS | |
| function searchUsers() { | |
| const searchTerm = document.getElementById('searchInput').value; | |
| fetch('/api/users?search=' + encodeURIComponent(searchTerm)) | |
| .then(response => response.json()) | |
| .then(data => { | |
| let html = '<ul>'; | |
| data.forEach(user => { | |
| // XSS vulnerability - unsanitized output | |
| html += '<li>' + user.name + ' - ' + user.email + '</li>'; | |
| }); | |
| html += '</ul>'; | |
| document.getElementById('results').innerHTML = html; | |
| }); | |
| } | |
| // Vulnerable form submission with eval | |
| function processFormula() { | |
| const formula = document.getElementById('formula').value; | |
| try { | |
| // Code injection vulnerability - eval with user input | |
| const result = eval(formula); | |
| document.getElementById('calculationResult').textContent = result; | |
| } catch (error) { | |
| document.getElementById('calculationResult').textContent = 'Error: ' + error.message; | |
| } | |
| } | |
| // Information disclosure in comments | |
| // TODO: Remove before production | |
| // Database connection: mysql://admin:password123@localhost:3306/production_db | |
| // API Key: sk-live-1234567890abcdef | |
| // Admin panel: /admin/secret-panel | |
| // Vulnerable cookie handling | |
| function setUserPreferences() { | |
| const prefs = { | |
| theme: document.getElementById('theme').value, | |
| language: document.getElementById('language').value, | |
| // Sensitive data in cookie | |
| userId: getCurrentUserId(), | |
| adminFlag: isAdmin() | |
| }; | |
| // Insecure cookie - no httpOnly, secure flags | |
| document.cookie = 'userPrefs=' + JSON.stringify(prefs) + '; path=/'; | |
| } | |
| // Vulnerable local storage usage | |
| function saveSecrets() { | |
| const secrets = { | |
| apiKey: API_KEY, | |
| authToken: getAuthToken(), | |
| userPassword: document.getElementById('password').value | |
| }; | |
| // Information disclosure - sensitive data in localStorage | |
| localStorage.setItem('appSecrets', JSON.stringify(secrets)); | |
| } | |
| // Vulnerable regex for input validation | |
| function validateInput(input) { | |
| // ReDoS vulnerability - catastrophic backtracking | |
| const pattern = /^(a+)+$/; | |
| return pattern.test(input); | |
| } | |
| // Prototype pollution on client side | |
| function updateUserObject(user, updates) { | |
| // Prototype pollution vulnerability | |
| for (const key in updates) { | |
| if (updates.hasOwnProperty(key)) { | |
| user[key] = updates[key]; | |
| } | |
| } | |
| return user; | |
| } | |
| // Vulnerable event handler | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // XSS vulnerability - unsanitized URL parameter | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const welcomeMessage = urlParams.get('welcome'); | |
| if (welcomeMessage) { | |
| document.getElementById('welcomeDiv').innerHTML = welcomeMessage; | |
| } | |
| }); | |
| // Insecure random number generation for security purposes | |
| function generateVerificationCode() { | |
| return Math.floor(Math.random() * 1000000).toString().padStart(6, '0'); | |
| } | |
| // Vulnerable JSONP callback | |
| function handleJSONPResponse(data) { | |
| // XSS vulnerability - eval-like behavior | |
| const callback = getUrlParameter('callback'); | |
| if (callback) { | |
| eval(callback + '(' + JSON.stringify(data) + ')'); | |
| } | |
| } | |
| function getUrlParameter(name) { | |
| const regex = new RegExp('[?&]' + name + '=([^&#]*)'); | |
| const results = regex.exec(window.location.search); | |
| return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' ')); | |
| } | |
| // Vulnerable file upload handling | |
| function handleFileUpload() { | |
| const fileInput = document.getElementById('fileUpload'); | |
| const file = fileInput.files[0]; | |
| if (file) { | |
| // Information disclosure - exposing file system paths | |
| console.log('File path:', file.webkitRelativePath); | |
| console.log('File size:', file.size); | |
| console.log('File type:', file.type); | |
| // Vulnerable file reading | |
| const reader = new FileReader(); | |
| reader.onload = function(e) { | |
| // XSS vulnerability - unsanitized file content | |
| document.getElementById('fileContent').innerHTML = e.target.result; | |
| }; | |
| reader.readAsText(file); | |
| } | |
| } | |
| // Vulnerable WebSocket handling | |
| function initializeWebSocket() { | |
| const ws = new WebSocket('ws://localhost:8080'); | |
| ws.onmessage = function(event) { | |
| const data = JSON.parse(event.data); | |
| // XSS vulnerability - unsanitized WebSocket message | |
| document.getElementById('messages').innerHTML += '<div>' + data.message + '</div>'; | |
| }; | |
| ws.onerror = function(error) { | |
| // Information disclosure - exposing WebSocket errors | |
| console.error('WebSocket error:', error); | |
| }; | |
| } | |
| // Vulnerable postMessage handling | |
| window.addEventListener('message', function(event) { | |
| // Missing origin validation - security vulnerability | |
| const data = event.data; | |
| if (data.type === 'updateContent') { | |
| // XSS vulnerability - unsanitized message content | |
| document.getElementById('content').innerHTML = data.content; | |
| } | |
| }); | |
| // Vulnerable iframe communication | |
| function sendMessageToIframe() { | |
| const iframe = document.getElementById('userIframe'); | |
| const message = document.getElementById('iframeMessage').value; | |
| // Missing origin validation | |
| iframe.contentWindow.postMessage({ | |
| type: 'userMessage', | |
| content: message | |
| }, '*'); | |
| } | |
| `; | |
| // Additional server-side vulnerabilities | |
| app.use('/static', express.static('public')); | |
| // Vulnerable middleware | |
| app.use((req, res, next) => { | |
| // Information disclosure - exposing request details | |
| console.log('Request details:', { | |
| ip: req.ip, | |
| headers: req.headers, | |
| body: req.body, | |
| query: req.query | |
| }); | |
| next(); | |
| }); | |
| // Vulnerable error handler | |
| app.use((err, req, res, next) => { | |
| // Information disclosure - exposing stack traces | |
| res.status(500).json({ | |
| error: err.message, | |
| stack: err.stack, | |
| request: { | |
| url: req.url, | |
| method: req.method, | |
| headers: req.headers | |
| } | |
| }); | |
| }); | |
| // Vulnerable admin endpoint | |
| app.get('/admin/users', (req, res) => { | |
| // Missing authentication check | |
| const users = [ | |
| { id: 1, username: 'admin', password: 'admin123', role: 'admin' }, | |
| { id: 2, username: 'user', password: 'user123', role: 'user' } | |
| ]; | |
| res.json(users); | |
| }); | |
| // Vulnerable password reset | |
| app.post('/reset-password', (req, res) => { | |
| const { email } = req.body; | |
| // Insecure random token generation | |
| const resetToken = Math.random().toString(36).substring(2, 15); | |
| // Information disclosure - exposing reset token | |
| res.json({ | |
| message: 'Password reset email sent', | |
| token: resetToken, | |
| email: email | |
| }); | |
| }); | |
| // Vulnerable file serving | |
| app.get('/download/:filename', (req, res) => { | |
| const filename = req.params.filename; | |
| // Path traversal vulnerability | |
| const filePath = './files/' + filename; | |
| res.download(filePath, (err) => { | |
| if (err) { | |
| // Information disclosure - exposing file system errors | |
| res.status(500).json({ | |
| error: err.message, | |
| path: filePath | |
| }); | |
| } | |
| }); | |
| }); | |
| // Start server | |
| const PORT = process.env.PORT || 3000; | |
| app.listen(PORT, () => { | |
| console.log(`Server running on port ${PORT}`); | |
| console.log(`Database password: ${DB_PASSWORD}`); | |
| console.log(`API Key: ${API_KEY}`); | |
| }); | |
| // Export for testing | |
| module.exports = app; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment