Skip to content

[LEGIT] Fix - Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks#99

Open
legit-app-ci[bot] wants to merge 1 commit into
masterfrom
legit-security-a3873f
Open

[LEGIT] Fix - Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks#99
legit-app-ci[bot] wants to merge 1 commit into
masterfrom
legit-security-a3873f

Conversation

@legit-app-ci

@legit-app-ci legit-app-ci Bot commented Jun 23, 2026

Copy link
Copy Markdown

🔍 The problem

Change this code to not reflect user-controlled data.
See issue in Legit

🔒 Fix Details

Fixed a Server-Side Request Forgery (SSRF) vulnerability combined with reflected Cross-Site Scripting (XSS). The code previously accepted arbitrary URLs from user input (req.query.url) and fetched them server-side without validation, then reflected the response body directly into the HTML response without encoding.

The fix implements two defenses: (1) an allowlist of trusted base URLs that validates req.query.url before making the request, rejecting any URL that doesn't start with an approved domain, and (2) HTML entity encoding using the he library on the fetched response body before writing it to the response. This prevents attackers from accessing internal resources via SSRF and from injecting malicious scripts via reflected content.

--- a/app/routes/research.js
+++ b/app/routes/research.js
@@ -1,21 +1,26 @@
 const ResearchDAO = require("../data/research-dao").ResearchDAO;
 const needle = require('needle');
+const he = require('he');
 
 function ResearchHandler (db) {
     "use strict";
 
     const researchDAO = new ResearchDAO(db);
+    const ALLOWED_BASE_URLS = ['https://api.trustedstockprovider.com/', 'https://finance.trustedsite.com/'];
 
     this.displayResearch = (req, res) => {
         
         if (req.query.symbol) {
+            if (!req.query.url || !ALLOWED_BASE_URLS.some(allowed => req.query.url.startsWith(allowed))) {
+                return res.status(400).send('Invalid URL parameter');
+            }
             const url = req.query.url+req.query.symbol; 
             return needle.get(url, (error, newResponse) => {
                 if (!error && newResponse.statusCode == 200)
                     res.writeHead(200, {'Content-Type': 'text/html'});
                     res.write('<h1>The following is the stock information you requested.</h1>\n\n');
                     res.write('\n\n');
-                    res.write(newResponse.body);
+                    res.write(he.encode(newResponse.body));
                     return res.end();
             });
         }

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants