{ "rules": [ { "id": "javascript.passport-jwt.security.passport-hardcode.hardcoded-passport-secret", "message": "A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module).", "metadata": { "cwe": [ "CWE-798: Use of Hard-coded Credentials" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html" ], "owasp": [ "A07:2021 - Identification and Authentication Failures", "A07:2025 - Authentication Failures" ], "asvs": { "section": "V3: Session Management Verification Requirements", "control_id": "3.5.2 Static API keys or secret", "control_url": "https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management", "version": "4" }, "category": "security", "technology": [ "jwt", "nodejs", "secrets" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "MEDIUM", "confidence": "HIGH", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Hard-coded Secrets" ], "source": "https://semgrep.dev/r/javascript.passport-jwt.security.passport-hardcode.hardcoded-passport-secret", "shortlink": "https://sg.run/vz70", "semgrep.dev": { "rule": { "r_id": 9333, "rv_id": 1263225, "rule_id": "QrUzq6", "version_id": "X0TzyoE", "url": "https://semgrep.dev/playground/r/X0TzyoE/javascript.passport-jwt.security.passport-hardcode.hardcoded-passport-secret", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "by-side-effect": true, "patterns": [ { "pattern-either": [ { "pattern": "{..., clientSecret: \"...\", ...}\n" }, { "pattern": "{..., secretOrKey: \"...\", ...}\n" }, { "pattern": "{..., consumerSecret: \"...\", ...}\n" }, { "patterns": [ { "pattern-inside": "$OBJ = {}\n...\n" }, { "pattern-either": [ { "pattern": "$OBJ.clientSecret = \"...\"\n" }, { "pattern": "$OBJ.secretOrKey = \"...\"\n" }, { "pattern": "$OBJ.consumerSecret = \"...\"\n" } ] }, { "pattern": "$OBJ" } ] }, { "patterns": [ { "pattern-inside": "$SECRET = '...'\n...\n" }, { "pattern-either": [ { "pattern": "{..., clientSecret: $SECRET, ...}\n" }, { "pattern": "{..., secretOrKey: $SECRET, ...}\n" }, { "pattern": "{..., consumerSecret: $SECRET, ...}\n" } ] } ] }, { "patterns": [ { "pattern-inside": "$SECRET = '...'\n...\n" }, { "pattern-either": [ { "pattern-inside": "$VALUE = {..., clientSecret: $SECRET, ...}\n...\n" }, { "pattern-inside": "$VALUE = {..., secretOrKey: $SECRET, ...}\n...\n" }, { "pattern-inside": "$VALUE = {..., consumerSecret: $SECRET, ...}\n...\n" } ] }, { "pattern": "$VALUE" } ] } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "$F = require(\"$I\").Strategy\n...\n" }, { "pattern-inside": "$F = require(\"$I\")\n...\n" }, { "pattern-inside": "import { $STRAT as $F } from '$I'\n...\n" }, { "pattern-inside": "import $F from '$I'\n...\n" } ] }, { "metavariable-regex": { "metavariable": "$I", "regex": "(passport-.*)" } }, { "pattern-inside": "new $F($VALUE,...)\n" }, { "focus-metavariable": "$VALUE" } ] } ] }, { "id": "javascript.express.security.audit.xss.direct-response-write.direct-response-write", "message": "Detected directly writing to a Response object from user-defined input. This bypasses any HTML escaping and may expose your application to a Cross-Site-scripting (XSS) vulnerability. Instead, use 'resp.render()' to render safely escaped HTML.", "options": { "interfile": true }, "metadata": { "interfile": true, "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html" ], "owasp": [ "A07:2017 - Cross-Site Scripting (XSS)", "A03:2021 - Injection", "A05:2025 - Injection" ], "cwe": [ "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')" ], "category": "security", "technology": [ "express" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "vulnerability_class": [ "Cross-Site-Scripting (XSS)" ], "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "source": "https://semgrep.dev/r/javascript.express.security.audit.xss.direct-response-write.direct-response-write", "shortlink": "https://sg.run/vzGl", "semgrep.dev": { "rule": { "r_id": 9277, "rv_id": 1263150, "rule_id": "3qUPA1", "version_id": "JdTzxeg", "url": "https://semgrep.dev/playground/r/JdTzxeg/javascript.express.security.audit.xss.direct-response-write.direct-response-write", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)" } } ] } ] }, { "pattern-not-inside": "function ... ($REQ, $RES) {\n ...\n $RES.$SET('Content-Type', '$TYPE')\n}\n" }, { "pattern-not-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {\n ...\n $RES.$SET('Content-Type', '$TYPE')\n})\n" }, { "pattern-not-inside": "function ... ($REQ, $RES, $NEXT) {\n ...\n $RES.$SET('Content-Type', '$TYPE')\n}\n" }, { "pattern-not-inside": "function ... ($REQ, $RES) {\n ...\n $RES.set('$TYPE')\n}\n" }, { "pattern-not-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {\n ...\n $RES.set('$TYPE')\n})\n" }, { "pattern-not-inside": "function ... ($REQ, $RES, $NEXT) {\n ...\n $RES.set('$TYPE')\n}\n" }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "pattern-not-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{\n ...\n $RES.$SET('Content-Type', '$TYPE')\n}\n" }, { "pattern-not-inside": "({ $REQ }: Request,$RES: Response) => {\n ...\n $RES.$SET('Content-Type', '$TYPE')\n}\n" }, { "pattern-not-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{\n ...\n $RES.set('$TYPE')\n}\n" }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-inside": "function ... (..., $RES,...) {...}" }, { "pattern-either": [ { "pattern": "$RES.write($ARG)" }, { "pattern": "$RES.send($ARG)" } ] }, { "pattern-not": "$RES. ... .set('...'). ... .send($ARG)" }, { "pattern-not": "$RES. ... .type('...'). ... .send($ARG)" }, { "pattern-not-inside": "$RES.$METHOD({ ... })" }, { "focus-metavariable": "$ARG" } ] } ], "pattern-sanitizers": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "import $S from \"underscore.string\"\n...\n" }, { "pattern-inside": "import * as $S from \"underscore.string\"\n...\n" }, { "pattern-inside": "import $S from \"underscore.string\"\n...\n" }, { "pattern-inside": "$S = require(\"underscore.string\")\n...\n" } ] }, { "pattern-either": [ { "pattern": "$S.escapeHTML(...)" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "import $S from \"dompurify\"\n...\n" }, { "pattern-inside": "import { ..., $S,... } from \"dompurify\"\n...\n" }, { "pattern-inside": "import * as $S from \"dompurify\"\n...\n" }, { "pattern-inside": "$S = require(\"dompurify\")\n...\n" }, { "pattern-inside": "import $S from \"isomorphic-dompurify\"\n...\n" }, { "pattern-inside": "import * as $S from \"isomorphic-dompurify\"\n...\n" }, { "pattern-inside": "$S = require(\"isomorphic-dompurify\")\n...\n" } ] }, { "pattern-either": [ { "patterns": [ { "pattern-inside": "$VALUE = $S(...)\n...\n" }, { "pattern": "$VALUE.sanitize(...)" } ] }, { "patterns": [ { "pattern-inside": "$VALUE = $S.sanitize\n...\n" }, { "pattern": "$S(...)" } ] }, { "pattern": "$S.sanitize(...)" }, { "pattern": "$S(...)" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "import $S from 'xss';\n...\n" }, { "pattern-inside": "import * as $S from 'xss';\n...\n" }, { "pattern-inside": "$S = require(\"xss\")\n...\n" } ] }, { "pattern": "$S(...)" } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "import $S from 'sanitize-html';\n...\n" }, { "pattern-inside": "import * as $S from \"sanitize-html\";\n...\n" }, { "pattern-inside": "$S = require(\"sanitize-html\")\n...\n" } ] }, { "pattern": "$S(...)" } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$S = new Remarkable()\n...\n" } ] }, { "pattern": "$S.render(...)" } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "import $S from 'express-xss-sanitizer';\n...\n" }, { "pattern-inside": "import * as $S from \"express-xss-sanitizer\";\n...\n" }, { "pattern-inside": "const { ..., $S, ... } = require('express-xss-sanitizer');\n...\n" }, { "pattern-inside": "var { ..., $S, ... } = require('express-xss-sanitizer');\n...\n" }, { "pattern-inside": "let { ...,$S,... } = require('express-xss-sanitizer');\n...\n" }, { "pattern-inside": "$S = require(\"express-xss-sanitizer\")\n...\n" } ] }, { "pattern": "$S(...)" } ] }, { "patterns": [ { "pattern": "$RES. ... .type('$F'). ... .send(...)" }, { "metavariable-regex": { "metavariable": "$F", "regex": "(?!.*text/html)" } } ] }, { "patterns": [ { "pattern-inside": "$X = [...];\n...\n" }, { "pattern": "if(<... !$X.includes($SOURCE)...>) {\n ...\n return ...\n}\n...\n" }, { "pattern": "$SOURCE" } ] } ] }, { "id": "javascript.express.security.express-puppeteer-injection.express-puppeteer-injection", "message": "If unverified user data can reach the `puppeteer` methods it can result in Server-Side Request Forgery vulnerabilities", "metadata": { "owasp": [ "A10:2021 - Server-Side Request Forgery (SSRF)", "A01:2025 - Broken Access Control" ], "cwe": [ "CWE-918: Server-Side Request Forgery (SSRF)" ], "category": "security", "technology": [ "express" ], "references": [ "https://pptr.dev/api/puppeteer.page" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Server-Side Request Forgery (SSRF)" ], "source": "https://semgrep.dev/r/javascript.express.security.express-puppeteer-injection.express-puppeteer-injection", "shortlink": "https://sg.run/0QJB", "semgrep.dev": { "rule": { "r_id": 9254, "rv_id": 1263168, "rule_id": "X5U8Nz", "version_id": "X0TzyJY", "url": "https://semgrep.dev/playground/r/X0TzyJY/javascript.express.security.express-puppeteer-injection.express-puppeteer-injection", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "require('puppeteer');\n...\n" }, { "pattern-inside": "import 'puppeteer';\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PAGE.goto($SINK,...)" }, { "pattern": "$PAGE.setContent($SINK,...)" }, { "pattern": "$PAGE.evaluate($SINK,...)" }, { "pattern": "$PAGE.evaluate($CODE,$SINK,...)" }, { "pattern": "$PAGE.evaluateHandle($SINK,...)" }, { "pattern": "$PAGE.evaluateHandle($CODE,$SINK,...)" }, { "pattern": "$PAGE.evaluateOnNewDocument($SINK,...)" }, { "pattern": "$PAGE.evaluateOnNewDocument($CODE,$SINK,...)" } ] }, { "focus-metavariable": "$SINK" } ] } ] }, { "id": "javascript.express.security.audit.express-libxml-noent.express-libxml-noent", "message": "The libxml library processes user-input with the `noent` attribute is set to `true` which can lead to being vulnerable to XML External Entities (XXE) type attacks. It is recommended to set `noent` to `false` when using this feature to ensure you are protected.", "options": { "interfile": true }, "metadata": { "interfile": true, "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html" ], "technology": [ "express" ], "category": "security", "cwe": [ "CWE-611: Improper Restriction of XML External Entity Reference" ], "owasp": [ "A04:2017 - XML External Entities (XXE)", "A05:2021 - Security Misconfiguration", "A02:2025 - Security Misconfiguration" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "HIGH", "confidence": "HIGH", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "XML Injection" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-libxml-noent.express-libxml-noent", "shortlink": "https://sg.run/Z75x", "semgrep.dev": { "rule": { "r_id": 22079, "rv_id": 1263138, "rule_id": "pKUNeD", "version_id": "d6TyxpX", "url": "https://semgrep.dev/playground/r/d6TyxpX/javascript.express.security.audit.express-libxml-noent.express-libxml-noent", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" }, { "pattern": "$REQ.files.$ANYTHING.data.toString('utf8')" }, { "pattern": "$REQ.files.$ANYTHING['data'].toString('utf8')" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" }, { "pattern": "files.$ANYTHING.data.toString('utf8')" }, { "pattern": "files.$ANYTHING['data'].toString('utf8')" } ] } ] } ], "pattern-sinks": [ { "pattern-either": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "$XML = require('$IMPORT')\n...\n" }, { "pattern-inside": "import $XML from '$IMPORT'\n ...\n" }, { "pattern-inside": "import * as $XML from '$IMPORT'\n...\n" } ] }, { "metavariable-regex": { "metavariable": "$IMPORT", "regex": "^(libxmljs|libxmljs2)$" } }, { "pattern-inside": "$XML.$FUNC($QUERY, {...,noent:true,...})" }, { "metavariable-regex": { "metavariable": "$FUNC", "regex": "^(parseXmlString|parseXml)$" } }, { "focus-metavariable": "$QUERY" } ] } ] } ] }, { "id": "javascript.express.security.express-phantom-injection.express-phantom-injection", "message": "If unverified user data can reach the `phantom` methods it can result in Server-Side Request Forgery vulnerabilities", "metadata": { "owasp": [ "A10:2021 - Server-Side Request Forgery (SSRF)", "A01:2025 - Broken Access Control" ], "cwe": [ "CWE-918: Server-Side Request Forgery (SSRF)" ], "category": "security", "technology": [ "express" ], "references": [ "https://phantomjs.org/page-automation.html" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Server-Side Request Forgery (SSRF)" ], "source": "https://semgrep.dev/r/javascript.express.security.express-phantom-injection.express-phantom-injection", "shortlink": "https://sg.run/W8BL", "semgrep.dev": { "rule": { "r_id": 9253, "rv_id": 1263167, "rule_id": "2ZUbx3", "version_id": "2KTv26p", "url": "https://semgrep.dev/playground/r/2KTv26p/javascript.express.security.express-phantom-injection.express-phantom-injection", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "require('phantom');\n...\n" }, { "pattern-inside": "import 'phantom';\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PAGE.open($SINK,...)" }, { "pattern": "$PAGE.setContent($SINK,...)" }, { "pattern": "$PAGE.openUrl($SINK,...)" }, { "pattern": "$PAGE.evaluateJavaScript($SINK,...)" }, { "pattern": "$PAGE.property(\"content\",$SINK,...)" } ] }, { "focus-metavariable": "$SINK" } ] } ] }, { "id": "javascript.express.security.express-vm-injection.express-vm-injection", "message": "Make sure that unverified user data can not reach `$VM`.", "metadata": { "owasp": [ "A03:2021 - Injection", "A05:2025 - Injection" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html" ], "cwe": [ "CWE-94: Improper Control of Generation of Code ('Code Injection')" ], "category": "security", "technology": [ "express" ], "cwe2022-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Code Injection" ], "source": "https://semgrep.dev/r/javascript.express.security.express-vm-injection.express-vm-injection", "shortlink": "https://sg.run/jkqJ", "semgrep.dev": { "rule": { "r_id": 12821, "rv_id": 1263170, "rule_id": "DbUKPX", "version_id": "1QTypXQ", "url": "https://semgrep.dev/playground/r/1QTypXQ/javascript.express.security.express-vm-injection.express-vm-injection", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-inside": "$VM = require('vm');\n...\n" }, { "pattern-either": [ { "pattern": "$VM.runInContext(...)\n" }, { "pattern": "$VM.runInNewContext(...)\n" }, { "pattern": "$VM.compileFunction(...)\n" }, { "pattern": "$VM.runInThisContext(...)\n" }, { "pattern": "new $VM.Script(...)" } ] } ] } ] }, { "id": "javascript.express.security.require-request.require-request", "message": "If an attacker controls the x in require(x) then they can cause code to load that was not intended to run on the server.", "options": { "interfile": true }, "metadata": { "interfile": true, "owasp": [ "A01:2021 - Broken Access Control", "A01:2025 - Broken Access Control" ], "cwe": [ "CWE-706: Use of Incorrectly-Resolved Name or Reference" ], "source-rule-url": "https://nodesecroadmap.fyi/chapter-1/threat-UIR.html", "category": "security", "technology": [ "express" ], "references": [ "https://github.com/google/node-sec-roadmap/blob/master/chapter-2/dynamism.md#dynamism-when-you-need-it" ], "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Improper Authorization" ], "source": "https://semgrep.dev/r/javascript.express.security.require-request.require-request", "shortlink": "https://sg.run/jRbl", "semgrep.dev": { "rule": { "r_id": 9265, "rv_id": 1263177, "rule_id": "OrU3WK", "version_id": "w8TRo0d", "url": "https://semgrep.dev/playground/r/w8TRo0d/javascript.express.security.require-request.require-request", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern": "require($SINK)" }, { "focus-metavariable": "$SINK" } ] } ] }, { "id": "javascript.express.security.audit.express-ssrf.express-ssrf", "message": "The following request $REQUEST.$METHOD() was found to be crafted from user-input `$REQ` which can lead to Server-Side Request Forgery (SSRF) vulnerabilities. It is recommended where possible to not allow user-input to craft the base request, but to be treated as part of the path or query parameter. When user-input is necessary to craft the request, it is recommeneded to follow OWASP best practices to prevent abuse. ", "metadata": { "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html" ], "cwe": [ "CWE-918: Server-Side Request Forgery (SSRF)" ], "technology": [ "express" ], "category": "security", "owasp": [ "A10:2021 - Server-Side Request Forgery (SSRF)", "A01:2025 - Broken Access Control" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "HIGH", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Server-Side Request Forgery (SSRF)" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-ssrf.express-ssrf", "shortlink": "https://sg.run/0PNw", "semgrep.dev": { "rule": { "r_id": 22554, "rv_id": 1263144, "rule_id": "eqU9l2", "version_id": "8KT5rBr", "url": "https://semgrep.dev/playground/r/8KT5rBr/javascript.express.security.audit.express-ssrf.express-ssrf", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "options": { "taint_unify_mvars": true }, "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, ...) {...}" } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,...) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: $EXPRESS.Request,...) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "$REQUEST = require('request')\n...\n" }, { "pattern-inside": "import * as $REQUEST from 'request'\n...\n" }, { "pattern-inside": "import $REQUEST from 'request'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$REQUEST.$METHOD(\"$HTTP\"+$REQ. ... .$VALUE)" }, { "pattern": "$REQUEST.$METHOD(\"$HTTP\"+$REQ. ... .$VALUE + $...A)" }, { "pattern": "$REQUEST.$METHOD(`$HTTP${$REQ. ... .$VALUE}...`)" }, { "pattern": "$REQUEST.$METHOD(\"$HTTP\"+$REQ.$VALUE[...])" }, { "pattern": "$REQUEST.$METHOD(\"$HTTP\"+$REQ.$VALUE[...] + $...A)" }, { "pattern": "$REQUEST.$METHOD(`$HTTP${$REQ.$VALUE[...]}...`)" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|patch|del|head|delete)$" } }, { "metavariable-regex": { "metavariable": "$HTTP", "regex": "^(https?:\\/\\/|//)$" } }, { "pattern-either": [ { "pattern": "$REQ. ... .$VALUE" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$REQUEST = require('request')\n...\n" }, { "pattern-inside": "import * as $REQUEST from 'request'\n...\n" }, { "pattern-inside": "import $REQUEST from 'request'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$REQUEST.$METHOD($REQ. ... .$VALUE,...)" }, { "pattern": "$REQUEST.$METHOD($REQ. ... .$VALUE + $...A,...)" }, { "pattern": "$REQUEST.$METHOD(`${$REQ. ... .$VALUE}...`,...)" } ] }, { "pattern": "$REQ. ... .$VALUE" }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|patch|del|head|delete)$" } } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$REQUEST = require('request')\n...\n" }, { "pattern-inside": "import * as $REQUEST from 'request'\n...\n" }, { "pattern-inside": "import $REQUEST from 'request'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$REQUEST.$METHOD($REQ.$VALUE['...'],...)" }, { "pattern": "$REQUEST.$METHOD($REQ.$VALUE['...'] + $...A,...)" }, { "pattern": "$REQUEST.$METHOD(`${$REQ.$VALUE['...']}...`,...)" } ] }, { "pattern": "$REQ.$VALUE" }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|patch|del|head|delete)$" } } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$REQUEST = require('request')\n...\n" }, { "pattern-inside": "import * as $REQUEST from 'request'\n...\n" }, { "pattern-inside": "import $REQUEST from 'request'\n...\n" } ] }, { "pattern-either": [ { "pattern-inside": "$ASSIGN = $REQ. ... .$VALUE\n...\n" }, { "pattern-inside": "$ASSIGN = $REQ. ... .$VALUE['...']\n...\n" }, { "pattern-inside": "$ASSIGN = $REQ. ... .$VALUE + $...A\n...\n" }, { "pattern-inside": "$ASSIGN = $REQ. ... .$VALUE['...'] + $...A\n... \n" }, { "pattern-inside": "$ASSIGN = `${$REQ. ... .$VALUE}...`\n...\n" }, { "pattern-inside": "$ASSIGN = `${$REQ. ... .$VALUE['...']}...`\n... \n" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$ASSIGN = \"$HTTP\"+ $REQ. ... .$VALUE\n...\n" }, { "pattern-inside": "$ASSIGN = \"$HTTP\"+$REQ. ... .$VALUE + $...A\n...\n" }, { "pattern-inside": "$ASSIGN = \"$HTTP\"+$REQ.$VALUE[...]\n...\n" }, { "pattern-inside": "$ASSIGN = \"$HTTP\"+$REQ.$VALUE[...] + $...A\n...\n" }, { "pattern-inside": "$ASSIGN = `$HTTP${$REQ.$VALUE[...]}...`\n...\n" } ] }, { "metavariable-regex": { "metavariable": "$HTTP", "regex": "^(https?:\\/\\/|//)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQUEST.$METHOD($ASSIGN,...)" }, { "pattern": "$REQUEST.$METHOD($ASSIGN + $...FOO,...)" }, { "pattern": "$REQUEST.$METHOD(`${$ASSIGN}...`,...)" }, { "patterns": [ { "pattern-either": [ { "pattern": "$REQUEST.$METHOD(\"$HTTP\"+$ASSIGN,...)" }, { "pattern": "$REQUEST.$METHOD(\"$HTTP\"+$ASSIGN + $...A,...)" }, { "pattern": "$REQUEST.$METHOD(`$HTTP${$ASSIGN}...`,...)" } ] }, { "metavariable-regex": { "metavariable": "$HTTP", "regex": "^(https?:\\/\\/|//)$" } } ] } ] }, { "pattern": "$ASSIGN" }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|patch|del|head|delete)$" } } ] } ] }, { "id": "javascript.express.security.express-xml2json-xxe.express-xml2json-xxe", "message": "Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities", "metadata": { "owasp": [ "A04:2017 - XML External Entities (XXE)", "A05:2021 - Security Misconfiguration", "A02:2025 - Security Misconfiguration" ], "cwe": [ "CWE-611: Improper Restriction of XML External Entity Reference" ], "asvs": { "section": "V5 Validation, Sanitization and Encoding", "control_id": "5.5.2 Insecue XML Deserialization", "control_url": "https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention", "version": "4" }, "category": "security", "technology": [ "express" ], "references": [ "https://www.npmjs.com/package/xml2json" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "XML Injection" ], "source": "https://semgrep.dev/r/javascript.express.security.express-xml2json-xxe.express-xml2json-xxe", "shortlink": "https://sg.run/XBD4", "semgrep.dev": { "rule": { "r_id": 9264, "rv_id": 1263174, "rule_id": "x8Uneb", "version_id": "bZT534J", "url": "https://semgrep.dev/playground/r/bZT534J/javascript.express.security.express-xml2json-xxe.express-xml2json-xxe", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" }, { "pattern": "$REQ.files.$ANYTHING.data.toString('utf8')" }, { "pattern": "$REQ.files.$ANYTHING['data'].toString('utf8')" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" }, { "pattern": "files.$ANYTHING.data.toString('utf8')" }, { "pattern": "files.$ANYTHING['data'].toString('utf8')" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "require('xml2json');\n...\n" }, { "pattern-inside": "import 'xml2json';\n...\n" } ] }, { "pattern": "$EXPAT.toJson($SINK,...)" }, { "focus-metavariable": "$SINK" } ] } ] }, { "id": "javascript.express.security.audit.express-path-join-resolve-traversal.express-path-join-resolve-traversal", "message": "Possible writing outside of the destination, make sure that the target path is nested in the intended destination", "metadata": { "owasp": [ "A05:2017 - Broken Access Control", "A01:2021 - Broken Access Control", "A01:2025 - Broken Access Control" ], "cwe": [ "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')" ], "category": "security", "references": [ "https://owasp.org/www-community/attacks/Path_Traversal" ], "technology": [ "express", "node.js" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Path Traversal" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-path-join-resolve-traversal.express-path-join-resolve-traversal", "shortlink": "https://sg.run/weRn", "semgrep.dev": { "rule": { "r_id": 9273, "rv_id": 1263141, "rule_id": "L1Uyb8", "version_id": "ExTExX0", "url": "https://semgrep.dev/playground/r/ExTExX0/javascript.express.security.audit.express-path-join-resolve-traversal.express-path-join-resolve-traversal", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "focus-metavariable": "$SINK" }, { "pattern-either": [ { "pattern-inside": "$PATH = require('path');\n...\n" }, { "pattern-inside": "import $PATH from 'path';\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PATH.join(...,$SINK,...)" }, { "pattern": "$PATH.resolve(...,$SINK,...)" } ] } ] }, { "patterns": [ { "focus-metavariable": "$SINK" }, { "pattern-inside": "import 'path';\n...\n" }, { "pattern-either": [ { "pattern": "path.join(...,$SINK,...)" }, { "pattern": "path.resolve(...,$SINK,...)" } ] } ] } ], "pattern-sanitizers": [ { "pattern": "$Y.replace(...)" }, { "pattern": "$Y.indexOf(...)" }, { "pattern": "function ... (...) {\n ...\n <... $Y.indexOf(...) ...>\n ...\n}\n" }, { "patterns": [ { "pattern": "$FUNC(...)" }, { "metavariable-regex": { "metavariable": "$FUNC", "regex": "sanitize" } } ] } ] }, { "id": "javascript.express.security.injection.raw-html-format.raw-html-format", "message": "User data flows into the host portion of this manually-constructed HTML. This can introduce a Cross-Site-Scripting (XSS) vulnerability if this comes from user-provided input. Consider using a sanitization library such as DOMPurify to sanitize the HTML within.", "metadata": { "cwe": [ "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')" ], "owasp": [ "A07:2017 - Cross-Site Scripting (XSS)", "A03:2021 - Injection", "A05:2025 - Injection" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html" ], "category": "security", "technology": [ "express" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Cross-Site-Scripting (XSS)" ], "source": "https://semgrep.dev/r/javascript.express.security.injection.raw-html-format.raw-html-format", "shortlink": "https://sg.run/5DO3", "semgrep.dev": { "rule": { "r_id": 14691, "rv_id": 1263175, "rule_id": "5rUL0X", "version_id": "NdTzyQv", "url": "https://semgrep.dev/playground/r/NdTzyQv/javascript.express.security.injection.raw-html-format.raw-html-format", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "label": "EXPRESS", "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "label": "EXPRESSTS", "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] }, { "label": "CLEAN", "by-side-effect": true, "patterns": [ { "pattern-either": [ { "pattern": "$A($SOURCE)" }, { "pattern": "$SANITIZE. ... .$A($SOURCE)" }, { "pattern": "$A. ... .$SANITIZE($SOURCE)" } ] }, { "focus-metavariable": "$SOURCE" }, { "metavariable-regex": { "metavariable": "$A", "regex": "(?i)(.*valid|.*sanitiz)" } } ] } ], "pattern-sinks": [ { "requires": "(EXPRESS and not CLEAN) or (EXPRESSTS and not CLEAN)", "patterns": [ { "pattern-either": [ { "patterns": [ { "pattern-either": [ { "pattern": "\"$HTMLSTR\" + $EXPR" }, { "pattern": "\"$HTMLSTR\".concat(...)" }, { "pattern": "util.format($HTMLSTR, ...)" } ] }, { "metavariable-pattern": { "metavariable": "$HTMLSTR", "language": "generic", "pattern": "<$TAG ..." } } ] }, { "patterns": [ { "pattern": "`...`\n" }, { "pattern-regex": ".*<\\w+.*\n" } ] } ] } ] } ] }, { "id": "javascript.express.security.audit.express-res-sendfile.express-res-sendfile", "message": "The application processes user-input, this is passed to res.sendFile which can allow an attacker to arbitrarily read files on the system through path traversal. It is recommended to perform input validation in addition to canonicalizing the path. This allows you to validate the path against the intended directory it should be accessing.", "metadata": { "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html" ], "technology": [ "express" ], "category": "security", "cwe": [ "CWE-73: External Control of File Name or Path" ], "owasp": [ "A04:2021 - Insecure Design", "A06:2025 - Insecure Design" ], "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Path Traversal" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-res-sendfile.express-res-sendfile", "shortlink": "https://sg.run/7DJk", "semgrep.dev": { "rule": { "r_id": 22082, "rv_id": 1263142, "rule_id": "j2UzDx", "version_id": "7ZTE3X9", "url": "https://semgrep.dev/playground/r/7ZTE3X9/javascript.express.security.audit.express-res-sendfile.express-res-sendfile", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] }, { "patterns": [ { "pattern-either": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... (...,$REQ: $TYPE, ...) {...}\n" } ] }, { "metavariable-regex": { "metavariable": "$TYPE", "regex": "^(string|String)" } } ] } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern": "$RES.$METH($QUERY,...)" } ] }, { "pattern-not-inside": "$RES.$METH($QUERY,$OPTIONS)" }, { "metavariable-regex": { "metavariable": "$METH", "regex": "^(sendfile|sendFile)$" } }, { "focus-metavariable": "$QUERY" } ] } ] }, { "id": "javascript.express.security.audit.express-open-redirect.express-open-redirect", "message": "The application redirects to a URL specified by user-supplied input `$REQ` that is not validated. This could redirect users to malicious locations. Consider using an allow-list approach to validate URLs, or warn users they are being redirected to a third-party website.", "metadata": { "technology": [ "express" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html" ], "cwe": [ "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')" ], "category": "security", "owasp": [ "A01:2021 - Broken Access Control", "A01:2025 - Broken Access Control" ], "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "MEDIUM", "confidence": "HIGH", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Open Redirect" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-open-redirect.express-open-redirect", "shortlink": "https://sg.run/EpoP", "semgrep.dev": { "rule": { "r_id": 22081, "rv_id": 1263140, "rule_id": "X5ULkq", "version_id": "nWT2L0v", "url": "https://semgrep.dev/playground/r/nWT2L0v/javascript.express.security.audit.express-open-redirect.express-open-redirect", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "options": { "taint_unify_mvars": true, "symbolic_propagation": true }, "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern": "$RES.redirect(\"$HTTP\"+$REQ. ... .$VALUE)" }, { "pattern": "$RES.redirect(\"$HTTP\"+$REQ. ... .$VALUE + $...A)" }, { "pattern": "$RES.redirect(`$HTTP${$REQ. ... .$VALUE}...`)" }, { "pattern": "$RES.redirect(\"$HTTP\"+$REQ.$VALUE[...])" }, { "pattern": "$RES.redirect(\"$HTTP\"+$REQ.$VALUE[...] + $...A)" }, { "pattern": "$RES.redirect(`$HTTP${$REQ.$VALUE[...]}...`)" } ] }, { "metavariable-regex": { "metavariable": "$HTTP", "regex": "^https?:\\/\\/$" } }, { "pattern-either": [ { "pattern": "$REQ. ... .$VALUE" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern": "$RES.redirect($REQ. ... .$VALUE)" }, { "pattern": "$RES.redirect($REQ. ... .$VALUE + $...A)" }, { "pattern": "$RES.redirect(`${$REQ. ... .$VALUE}...`)" } ] }, { "pattern": "$REQ. ... .$VALUE" } ] }, { "patterns": [ { "pattern-either": [ { "pattern": "$RES.redirect($REQ.$VALUE['...'])" }, { "pattern": "$RES.redirect($REQ.$VALUE['...'] + $...A)" }, { "pattern": "$RES.redirect(`${$REQ.$VALUE['...']}...`)" } ] }, { "pattern": "$REQ.$VALUE" } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$ASSIGN = $REQ. ... .$VALUE\n...\n" }, { "pattern-inside": "$ASSIGN = $REQ.$VALUE['...']\n...\n" }, { "pattern-inside": "$ASSIGN = $REQ. ... .$VALUE + $...A\n...\n" }, { "pattern-inside": "$ASSIGN = $REQ.$VALUE['...'] + $...A\n... \n" }, { "pattern-inside": "$ASSIGN = `${$REQ. ... .$VALUE}...`\n...\n" }, { "pattern-inside": "$ASSIGN = `${$REQ.$VALUE['...']}...`\n... \n" } ] }, { "pattern-either": [ { "pattern": "$RES.redirect($ASSIGN)" }, { "pattern": "$RES.redirect($ASSIGN + $...FOO)" }, { "pattern": "$RES.redirect(`${$ASSIGN}...`)" } ] }, { "focus-metavariable": "$ASSIGN" } ] } ] }, { "id": "javascript.express.security.audit.express-third-party-object-deserialization.express-third-party-object-deserialization", "message": "The following function call $SER.$FUNC accepts user controlled data which can result in Remote Code Execution (RCE) through Object Deserialization. It is recommended to use secure data processing alternatives such as JSON.parse() and Buffer.from().", "options": { "interfile": true }, "metadata": { "interfile": true, "technology": [ "express" ], "category": "security", "cwe": [ "CWE-502: Deserialization of Untrusted Data" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html" ], "source_rule_url": [ "https://github.com/ajinabraham/njsscan/blob/75bfbeb9c8d72999e4d527dfa2548f7f0f3cc48a/njsscan/rules/semantic_grep/eval/eval_deserialize.yaml" ], "owasp": [ "A08:2017 - Insecure Deserialization", "A08:2021 - Software and Data Integrity Failures", "A08:2025 - Software or Data Integrity Failures" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "HIGH", "confidence": "HIGH", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Insecure Deserialization " ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-third-party-object-deserialization.express-third-party-object-deserialization", "shortlink": "https://sg.run/8W5j", "semgrep.dev": { "rule": { "r_id": 22084, "rv_id": 1263145, "rule_id": "9AUyqj", "version_id": "gETB7nD", "url": "https://semgrep.dev/playground/r/gETB7nD/javascript.express.security.audit.express-third-party-object-deserialization.express-third-party-object-deserialization", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" }, { "pattern": "$REQ.files.$ANYTHING.data.toString('utf8')" }, { "pattern": "$REQ.files.$ANYTHING['data'].toString('utf8')" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" }, { "pattern": "files.$ANYTHING.data.toString('utf8')" }, { "pattern": "files.$ANYTHING['data'].toString('utf8')" } ] } ] } ], "pattern-sinks": [ { "pattern-either": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "$SER = require('$IMPORT')\n...\n" }, { "pattern-inside": "import $SER from '$IMPORT'\n ...\n" }, { "pattern-inside": "import * as $SER from '$IMPORT'\n...\n" } ] }, { "metavariable-regex": { "metavariable": "$IMPORT", "regex": "^(node-serialize|serialize-to-js)$" } }, { "pattern": "$SER.$FUNC(...)" }, { "metavariable-regex": { "metavariable": "$FUNC", "regex": "^(unserialize|deserialize)$" } } ] } ] } ] }, { "id": "javascript.express.security.express-sandbox-injection.express-sandbox-code-injection", "message": "Make sure that unverified user data can not reach `sandbox`.", "metadata": { "owasp": [ "A03:2021 - Injection", "A05:2025 - Injection" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html" ], "cwe": [ "CWE-94: Improper Control of Generation of Code ('Code Injection')" ], "category": "security", "technology": [ "express" ], "cwe2022-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Code Injection" ], "source": "https://semgrep.dev/r/javascript.express.security.express-sandbox-injection.express-sandbox-code-injection", "shortlink": "https://sg.run/KlwL", "semgrep.dev": { "rule": { "r_id": 9255, "rv_id": 1263169, "rule_id": "j2UvXB", "version_id": "jQTn59D", "url": "https://semgrep.dev/playground/r/jQTn59D/javascript.express.security.express-sandbox-injection.express-sandbox-code-injection", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-inside": "$SANDBOX = require('sandbox');\n...\n" }, { "pattern-either": [ { "patterns": [ { "pattern-inside": "$S = new $SANDBOX(...);\n...\n" }, { "pattern": "$S.run(...)\n" } ] }, { "pattern": "new $SANDBOX($OPTS).run(...)\n" }, { "pattern": "new $SANDBOX().run(...)" } ] } ] } ] }, { "id": "javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-expires", "message": "Default session middleware settings: `expires` not set. Use it to set expiration date for persistent cookies.", "severity": "WARNING", "languages": [ "javascript", "typescript" ], "metadata": { "cwe": [ "CWE-522: Insufficiently Protected Credentials" ], "owasp": [ "A02:2017 - Broken Authentication", "A04:2021 - Insecure Design", "A06:2025 - Insecure Design" ], "source-rule-url": "https://expressjs.com/en/advanced/best-practice-security.html", "category": "security", "technology": [ "express" ], "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "LOW", "confidence": "MEDIUM", "references": [ "https://owasp.org/Top10/A04_2021-Insecure_Design" ], "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Cryptographic Issues" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-expires", "shortlink": "https://sg.run/N4eG", "semgrep.dev": { "rule": { "r_id": 9271, "rv_id": 1263135, "rule_id": "EwU2DZ", "version_id": "O9TpxRq", "url": "https://semgrep.dev/playground/r/O9TpxRq/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-expires", "origin": "community" } } }, "patterns": [ { "pattern-either": [ { "pattern-inside": "$SESSION = require('cookie-session');\n...\n" }, { "pattern-inside": "$SESSION = require('express-session');\n...\n" } ] }, { "pattern": "$SESSION(...)" }, { "pattern-not-inside": "$SESSION(<... {cookie:{expires:...}} ...>,...)" }, { "pattern-not-inside": "$OPTS = <... {cookie:{expires:...}} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE = <... {expires:...} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie = <... {expires:...} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE.expires = ...;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie.expires = ...;\n...\n$SESSION($OPTS,...);" } ] }, { "id": "javascript.express.security.cors-misconfiguration.cors-misconfiguration", "message": "By letting user input control CORS parameters, there is a risk that software does not properly verify that the source of data or communication is valid. Use literal values for CORS settings.", "metadata": { "owasp": [ "A07:2021 - Identification and Authentication Failures", "A07:2025 - Authentication Failures" ], "cwe": [ "CWE-346: Origin Validation Error" ], "category": "security", "references": [ "https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" ], "technology": [ "express" ], "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Improper Authentication" ], "source": "https://semgrep.dev/r/javascript.express.security.cors-misconfiguration.cors-misconfiguration", "shortlink": "https://sg.run/nKXO", "semgrep.dev": { "rule": { "r_id": 13580, "rv_id": 1263162, "rule_id": "5rULJQ", "version_id": "YDTZe8Y", "url": "https://semgrep.dev/playground/r/YDTZe8Y/javascript.express.security.cors-misconfiguration.cors-misconfiguration", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern": "$RES.set($HEADER, $X)" }, { "pattern": "$RES.header($HEADER, $X)" }, { "pattern": "$RES.setHeader($HEADER, $X)" }, { "pattern": "$RES.set({$HEADER: $X}, ...)\n" }, { "pattern": "$RES.writeHead($STATUS, {$HEADER: $X}, ...)\n" } ] }, { "focus-metavariable": "$X" }, { "metavariable-regex": { "metavariable": "$HEADER", "regex": ".*(Access-Control-Allow-Origin|access-control-allow-origin).*" } } ] } ] }, { "id": "javascript.express.security.audit.express-check-directory-listing.express-check-directory-listing", "message": "Directory listing/indexing is enabled, which may lead to disclosure of sensitive directories and files. It is recommended to disable directory listing unless it is a public resource. If you need directory listing, ensure that sensitive files are inaccessible when querying the resource.", "options": { "interfile": true }, "metadata": { "interfile": true, "cwe": [ "CWE-548: Exposure of Information Through Directory Listing" ], "owasp": [ "A06:2017 - Security Misconfiguration", "A01:2021 - Broken Access Control", "A01:2025 - Broken Access Control" ], "category": "security", "technology": [ "express" ], "references": [ "https://www.npmjs.com/package/serve-index", "https://www.acunetix.com/blog/articles/directory-listing-information-disclosure/" ], "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Mishandled Sensitive Information" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-check-directory-listing.express-check-directory-listing", "shortlink": "https://sg.run/DX2G", "semgrep.dev": { "rule": { "r_id": 22552, "rv_id": 1263129, "rule_id": "x8UqEb", "version_id": "rxTAKGb", "url": "https://semgrep.dev/playground/r/rxTAKGb/javascript.express.security.audit.express-check-directory-listing.express-check-directory-listing", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "patterns": [ { "pattern-either": [ { "pattern": "$APP.use(require('serve-index')(...))\n" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$SERVEINDEX = require('serve-index')\n...\n" }, { "pattern-inside": "import $SERVEINDEX from 'serve-index'\n...\n" }, { "pattern-inside": "import * as $SERVEINDEX from 'serve-index'\n...\n" } ] }, { "pattern-either": [ { "patterns": [ { "pattern-inside": "$VALUE = $SERVEINDEX(...)\n...\n" }, { "pattern": "$VALUE(...)\n" } ] }, { "pattern": "$APP.use(..., $SERVEINDEX(...), ...)\n" } ] } ] } ] } ] }, { "id": "javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection", "message": "Detected a sequelize statement that is tainted by user-input. This could lead to SQL injection if the variable is user-controlled and is not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements.", "options": { "interfile": true }, "metadata": { "interfile": true, "references": [ "https://sequelize.org/docs/v6/core-concepts/raw-queries/#replacements" ], "category": "security", "technology": [ "express" ], "cwe": [ "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" ], "owasp": [ "A01:2017 - Injection", "A03:2021 - Injection", "A05:2025 - Injection" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "HIGH", "confidence": "HIGH", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "SQL Injection" ], "source": "https://semgrep.dev/r/javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection", "shortlink": "https://sg.run/gjoe", "semgrep.dev": { "rule": { "r_id": 22085, "rv_id": 1263241, "rule_id": "yyU0GX", "version_id": "nWT2Llx", "url": "https://semgrep.dev/playground/r/nWT2Llx/javascript.sequelize.security.audit.sequelize-injection-express.express-sequelize-injection", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" }, { "pattern": "$REQ.files.$ANYTHING.data.toString('utf8')" }, { "pattern": "$REQ.files.$ANYTHING['data'].toString('utf8')" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" }, { "pattern": "files.$ANYTHING.data.toString('utf8')" }, { "pattern": "files.$ANYTHING['data'].toString('utf8')" } ] } ] } ], "pattern-sinks": [ { "pattern-either": [ { "patterns": [ { "pattern-either": [ { "pattern": "sequelize.query($QUERY,...)" }, { "pattern": "$DB.sequelize.query($QUERY,...)" } ] }, { "focus-metavariable": "$QUERY" } ] } ] } ], "pattern-sanitizers": [ { "pattern-either": [ { "pattern": "parseInt(...)" }, { "pattern": "$FUNC. ... .hash(...)" } ] } ] }, { "id": "javascript.express.security.express-expat-xxe.express-expat-xxe", "message": "Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities.", "options": { "interfile": true }, "metadata": { "interfile": true, "owasp": [ "A04:2017 - XML External Entities (XXE)", "A05:2021 - Security Misconfiguration", "A02:2025 - Security Misconfiguration" ], "cwe": [ "CWE-611: Improper Restriction of XML External Entity Reference" ], "asvs": { "section": "V5 Validation, Sanitization and Encoding", "control_id": "5.5.2 Insecue XML Deserialization", "control_url": "https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention", "version": "4" }, "references": [ "https://github.com/astro/node-expat" ], "category": "security", "technology": [ "express" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "XML Injection" ], "source": "https://semgrep.dev/r/javascript.express.security.express-expat-xxe.express-expat-xxe", "shortlink": "https://sg.run/BkXx", "semgrep.dev": { "rule": { "r_id": 9251, "rv_id": 1263164, "rule_id": "zdUkJl", "version_id": "o5TbD5l", "url": "https://semgrep.dev/playground/r/o5TbD5l/javascript.express.security.express-expat-xxe.express-expat-xxe", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "$XML = require('node-expat')\n...\n" }, { "pattern-inside": "import $XML from 'node-expat'\n...\n" }, { "pattern-inside": "import * as $XML from 'node-expat'\n...\n" } ] }, { "pattern-either": [ { "pattern-inside": "$PARSER = new $XML.Parser(...);\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PARSER.parse($QUERY)" }, { "pattern": "$PARSER.write($QUERY)" } ] }, { "focus-metavariable": "$QUERY" } ] } ] }, { "id": "javascript.lang.security.audit.code-string-concat.code-string-concat", "message": "Found data from an Express or Next web request flowing to `eval`. If this data is user-controllable this can lead to execution of arbitrary system commands in the context of your application process. Avoid `eval` whenever possible.", "options": { "interfile": true }, "metadata": { "interfile": true, "confidence": "HIGH", "owasp": [ "A03:2021 - Injection", "A05:2025 - Injection" ], "cwe": [ "CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')" ], "references": [ "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval", "https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback", "https://www.stackhawk.com/blog/nodejs-command-injection-examples-and-prevention/", "https://ckarande.gitbooks.io/owasp-nodegoat-tutorial/content/tutorial/a1_-_server_side_js_injection.html" ], "category": "security", "technology": [ "node.js", "Express", "Next.js" ], "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Code Injection" ], "source": "https://semgrep.dev/r/javascript.lang.security.audit.code-string-concat.code-string-concat", "shortlink": "https://sg.run/96Yk", "semgrep.dev": { "rule": { "r_id": 13023, "rv_id": 1263192, "rule_id": "DbUKEz", "version_id": "44TEjYX", "url": "https://semgrep.dev/playground/r/44TEjYX/javascript.lang.security.audit.code-string-concat.code-string-concat", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "ERROR", "mode": "taint", "pattern-sources": [ { "pattern-either": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "import { ...,$IMPORT,... } from 'next/router'\n...\n" }, { "pattern-inside": "import $IMPORT from 'next/router';\n...\n" } ] }, { "pattern-either": [ { "patterns": [ { "pattern-inside": "$ROUTER = $IMPORT()\n...\n" }, { "pattern-either": [ { "pattern-inside": "const { ...,$PROPS,... } = $ROUTER.query\n...\n" }, { "pattern-inside": "var { ...,$PROPS,... } = $ROUTER.query\n...\n" }, { "pattern-inside": "let { ...,$PROPS,... } = $ROUTER.query\n...\n" } ] }, { "focus-metavariable": "$PROPS" } ] }, { "patterns": [ { "pattern-inside": "$ROUTER = $IMPORT()\n...\n" }, { "pattern": "$ROUTER.query.$VALUE \n" } ] }, { "patterns": [ { "pattern": "$IMPORT().query.$VALUE" } ] } ] } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern": "eval(...)\n" } ] } ] }, { "id": "javascript.express.security.audit.express-jwt-not-revoked.express-jwt-not-revoked", "message": "No token revoking configured for `express-jwt`. A leaked token could still be used and unable to be revoked. Consider using function as the `isRevoked` option.", "metadata": { "cwe": [ "CWE-522: Insufficiently Protected Credentials" ], "owasp": [ "A02:2017 - Broken Authentication", "A04:2021 - Insecure Design", "A06:2025 - Insecure Design" ], "source-rule-url": "https://github.com/goldbergyoni/nodebestpractices/blob/master/sections/security/expirejwt.md", "asvs": { "section": "V3: Session Management Verification Requirements", "control_id": "3.5.3 Insecure Stateless Session Tokens", "control_url": "https://github.com/OWASP/ASVS/blob/master/4.0/en/0x12-V3-Session-management.md#v35-token-based-session-management", "version": "4" }, "category": "security", "technology": [ "express" ], "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "references": [ "https://owasp.org/Top10/A04_2021-Insecure_Design" ], "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Cryptographic Issues" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-jwt-not-revoked.express-jwt-not-revoked", "shortlink": "https://sg.run/kXNo", "semgrep.dev": { "rule": { "r_id": 9272, "rv_id": 1263137, "rule_id": "7KUQ9k", "version_id": "vdT06Bg", "url": "https://semgrep.dev/playground/r/vdT06Bg/javascript.express.security.audit.express-jwt-not-revoked.express-jwt-not-revoked", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "patterns": [ { "pattern-inside": "$JWT = require('express-jwt');\n...\n" }, { "pattern": "$JWT(...)" }, { "pattern-not-inside": "$JWT(<... {isRevoked:...} ...>,...)" }, { "pattern-not-inside": "$OPTS = <... {isRevoked:...} ...>;\n...\n$JWT($OPTS,...);" } ] }, { "id": "javascript.express.security.audit.res-render-injection.res-render-injection", "message": "User controllable data `$REQ` enters `$RES.render(...)` this can lead to the loading of other HTML/templating pages that they may not be authorized to render. An attacker may attempt to use directory traversal techniques e.g. `../folder/index` to access other HTML pages on the file system. Where possible, do not allow users to define what should be loaded in $RES.render or use an allow list for the existing application.", "options": { "interfile": true }, "metadata": { "interfile": true, "owasp": [ "A01:2021 - Broken Access Control", "A01:2025 - Broken Access Control" ], "cwe": [ "CWE-706: Use of Incorrectly-Resolved Name or Reference" ], "category": "security", "technology": [ "express" ], "references": [ "http://expressjs.com/en/4x/api.html#res.render" ], "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Improper Authorization" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.res-render-injection.res-render-injection", "shortlink": "https://sg.run/eLjd", "semgrep.dev": { "rule": { "r_id": 9276, "rv_id": 1263149, "rule_id": "QrUzrq", "version_id": "PkTR3OY", "url": "https://semgrep.dev/playground/r/PkTR3OY/javascript.express.security.audit.res-render-injection.res-render-injection", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern": "$RES.render($SINK, ...)" } ] }, { "focus-metavariable": "$SINK" } ] } ] }, { "id": "javascript.lang.security.audit.sqli.node-knex-sqli.node-knex-sqli", "message": "Detected SQL statement that is tainted by `$REQ` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, it is recommended to use parameterized queries or prepared statements. An example of parameterized queries like so: `knex.raw('SELECT $1 from table', [userinput])` can help prevent SQLi.", "metadata": { "confidence": "MEDIUM", "references": [ "https://knexjs.org/#Builder-fromRaw", "https://knexjs.org/#Builder-whereRaw", "https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html" ], "category": "security", "owasp": [ "A01:2017 - Injection", "A03:2021 - Injection", "A05:2025 - Injection" ], "cwe": [ "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" ], "technology": [ "express", "nodejs", "knex" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "SQL Injection" ], "source": "https://semgrep.dev/r/javascript.lang.security.audit.sqli.node-knex-sqli.node-knex-sqli", "shortlink": "https://sg.run/l9eE", "semgrep.dev": { "rule": { "r_id": 18257, "rv_id": 1263205, "rule_id": "d8UKLD", "version_id": "l4TJRey", "url": "https://semgrep.dev/playground/r/l4TJRey/javascript.lang.security.audit.sqli.node-knex-sqli.node-knex-sqli", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" }, { "pattern": "$REQ.files.$ANYTHING.data.toString('utf8')" }, { "pattern": "$REQ.files.$ANYTHING['data'].toString('utf8')" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" }, { "pattern": "files.$ANYTHING.data.toString('utf8')" }, { "pattern": "files.$ANYTHING['data'].toString('utf8')" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "focus-metavariable": "$QUERY" }, { "pattern-either": [ { "pattern-inside": "$KNEX.fromRaw($QUERY, ...)" }, { "pattern-inside": "$KNEX.whereRaw($QUERY, ...)" }, { "pattern-inside": "$KNEX.raw($QUERY, ...)" } ] }, { "pattern-either": [ { "pattern-inside": "require('knex')\n...\n" }, { "pattern-inside": "import 'knex'\n...\n" } ] } ] } ], "pattern-sanitizers": [ { "patterns": [ { "pattern": "parseInt(...)" } ] } ] }, { "id": "javascript.express.security.express-insecure-template-usage.express-insecure-template-usage", "message": "User data from `$REQ` is being compiled into the template, which can lead to a Server Side Template Injection (SSTI) vulnerability.", "options": { "interfile": true }, "metadata": { "interfile": true, "category": "security", "cwe": [ "CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine" ], "owasp": [ "A03:2021 - Injection", "A01:2017 - Injection", "A05:2025 - Injection" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html" ], "technology": [ "javascript", "typescript", "express", "pug", "jade", "dot", "ejs", "nunjucks", "lodash", "handlbars", "mustache", "hogan.js", "eta", "squirrelly" ], "source_rule_url": [ "https://github.com/github/codeql/blob/2ba2642c7ab29b9eedef33bcc2b8cd1d203d0c10/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js" ], "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Code Injection" ], "source": "https://semgrep.dev/r/javascript.express.security.express-insecure-template-usage.express-insecure-template-usage", "shortlink": "https://sg.run/b49v", "semgrep.dev": { "rule": { "r_id": 19226, "rv_id": 1263165, "rule_id": "EwUr9k", "version_id": "zyTb2eD", "url": "https://semgrep.dev/playground/r/zyTb2eD/javascript.express.security.express-insecure-template-usage.express-insecure-template-usage", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-propagators": [ { "pattern": "$MODEL.$FIND($E).then((...,$S,...)=>{...})", "from": "$E", "to": "$S" } ], "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "pattern-either": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "$PUG = require('pug')\n...\n" }, { "pattern-inside": "import * as $PUG from 'pug'\n...\n" }, { "pattern-inside": "$PUG = require('jade')\n...\n" }, { "pattern-inside": "import * as $PUG from 'jade'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PUG.compile(...)" }, { "pattern": "$PUG.compileClient(...)" }, { "pattern": "$PUG.compileClientWithDependenciesTracked(...)" }, { "pattern": "$PUG.render(...)" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$PUG = require('dot')\n...\n" }, { "pattern-inside": "import * as $PUG from 'dot'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PUG.template(...)" }, { "pattern": "$PUG.compile(...)" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$PUG = require('ejs')\n...\n" }, { "pattern-inside": "import * as $PUG from 'ejs'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PUG.render(...)" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$PUG = require('nunjucks')\n...\n" }, { "pattern-inside": "import * as $PUG from 'nunjucks'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PUG.renderString(...)" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$PUG = require('lodash')\n...\n" }, { "pattern-inside": "import * as $PUG from 'lodash'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PUG.template(...)" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$PUG = require('mustache')\n...\n" }, { "pattern-inside": "import * as $PUG from 'mustache'\n...\n" }, { "pattern-inside": "$PUG = require('eta')\n...\n" }, { "pattern-inside": "import * as $PUG from 'eta'\n...\n" }, { "pattern-inside": "$PUG = require('squirrelly')\n...\n" }, { "pattern-inside": "import * as $PUG from 'squirrelly'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PUG.render(...)" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$PUG = require('hogan.js')\n...\n" }, { "pattern-inside": "import * as $PUG from 'hogan.js'\n...\n" }, { "pattern-inside": "$PUG = require('handlebars')\n...\n" }, { "pattern-inside": "import * as $PUG from 'handlebars'\n...\n" } ] }, { "pattern-either": [ { "pattern": "$PUG.compile(...)" } ] } ] } ] } ] }, { "id": "javascript.express.security.express-vm2-injection.express-vm2-injection", "message": "Make sure that unverified user data can not reach `vm2`.", "metadata": { "owasp": [ "A03:2021 - Injection", "A05:2025 - Injection" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html" ], "cwe": [ "CWE-94: Improper Control of Generation of Code ('Code Injection')" ], "category": "security", "technology": [ "express" ], "cwe2022-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Code Injection" ], "source": "https://semgrep.dev/r/javascript.express.security.express-vm2-injection.express-vm2-injection", "shortlink": "https://sg.run/1GWv", "semgrep.dev": { "rule": { "r_id": 12822, "rv_id": 1263171, "rule_id": "WAUPXJ", "version_id": "9lT4bnX", "url": "https://semgrep.dev/playground/r/9lT4bnX/javascript.express.security.express-vm2-injection.express-vm2-injection", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-inside": "require('vm2')\n...\n" }, { "pattern-either": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "$VM = new VM(...)\n...\n" }, { "pattern-inside": "$VM = new NodeVM(...)\n...\n" } ] }, { "pattern": "$VM.run(...)\n" } ] }, { "pattern": "new VM(...).run(...)\n" }, { "pattern": "new NodeVM(...).run(...)\n" }, { "pattern": "new VMScript(...)\n" }, { "pattern": "new VM(...)\n" }, { "pattern": "new NodeVM(...)" } ] } ] } ] }, { "id": "javascript.express.security.audit.express-xml2json-xxe-event.express-xml2json-xxe-event", "message": "Xml Parser is used inside Request Event. Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities", "metadata": { "owasp": [ "A04:2017 - XML External Entities (XXE)", "A05:2021 - Security Misconfiguration", "A02:2025 - Security Misconfiguration" ], "cwe": [ "CWE-611: Improper Restriction of XML External Entity Reference" ], "category": "security", "technology": [ "express" ], "references": [ "https://www.npmjs.com/package/xml2json" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "HIGH", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "XML Injection" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-xml2json-xxe-event.express-xml2json-xxe-event", "shortlink": "https://sg.run/x1AA", "semgrep.dev": { "rule": { "r_id": 9274, "rv_id": 1263146, "rule_id": "8GUjkk", "version_id": "QkTGqgo", "url": "https://semgrep.dev/playground/r/QkTGqgo/javascript.express.security.audit.express-xml2json-xxe-event.express-xml2json-xxe-event", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) => {...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "require('xml2json');\n...\n" }, { "pattern-inside": "import 'xml2json';\n...\n" } ] }, { "pattern": "$REQ.on('...', function(...) { ... $EXPAT.toJson($INPUT,...); ... })" }, { "focus-metavariable": "$INPUT" } ] } ] }, { "id": "javascript.express.security.express-jwt-hardcoded-secret.express-jwt-hardcoded-secret", "message": "A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module).", "options": { "interfile": true }, "metadata": { "interfile": true, "cwe": [ "CWE-798: Use of Hard-coded Credentials" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html" ], "owasp": [ "A07:2021 - Identification and Authentication Failures", "A07:2025 - Authentication Failures" ], "category": "security", "technology": [ "express", "secrets" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "audit" ], "likelihood": "HIGH", "impact": "MEDIUM", "confidence": "HIGH", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Hard-coded Secrets" ], "source": "https://semgrep.dev/r/javascript.express.security.express-jwt-hardcoded-secret.express-jwt-hardcoded-secret", "shortlink": "https://sg.run/Do1d", "semgrep.dev": { "rule": { "r_id": 9252, "rv_id": 1263166, "rule_id": "pKUOjy", "version_id": "pZT03Q0", "url": "https://semgrep.dev/playground/r/pZT03Q0/javascript.express.security.express-jwt-hardcoded-secret.express-jwt-hardcoded-secret", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "patterns": [ { "pattern-either": [ { "pattern-inside": "$JWT = require('express-jwt');\n...\n" }, { "pattern-inside": "import $JWT from 'express-jwt';\n...\n" }, { "pattern-inside": "import * as $JWT from 'express-jwt';\n...\n" }, { "pattern-inside": "import { ..., $JWT, ... } from 'express-jwt';\n...\n" } ] }, { "pattern-either": [ { "pattern": "$JWT({...,secret: \"$Y\",...},...)\n" }, { "pattern": "$OPTS = \"$Y\";\n...\n$JWT({...,secret: $OPTS},...);\n" } ] }, { "focus-metavariable": "$Y" } ] }, { "id": "javascript.express.security.x-frame-options-misconfiguration.x-frame-options-misconfiguration", "message": "By letting user input control `X-Frame-Options` header, there is a risk that software does not properly verify whether or not a browser should be allowed to render a page in an `iframe`.", "metadata": { "references": [ "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options" ], "owasp": [ "A04:2021 - Insecure Design", "A06:2025 - Insecure Design" ], "cwe": [ "CWE-451: User Interface (UI) Misrepresentation of Critical Information" ], "category": "security", "technology": [ "express" ], "subcategory": [ "vuln" ], "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Other" ], "source": "https://semgrep.dev/r/javascript.express.security.x-frame-options-misconfiguration.x-frame-options-misconfiguration", "shortlink": "https://sg.run/EvjA", "semgrep.dev": { "rule": { "r_id": 13581, "rv_id": 1263178, "rule_id": "GdUrLy", "version_id": "xyTjz3D", "url": "https://semgrep.dev/playground/r/xyTjz3D/javascript.express.security.x-frame-options-misconfiguration.x-frame-options-misconfiguration", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "mode": "taint", "pattern-sources": [ { "patterns": [ { "pattern-either": [ { "pattern-inside": "function ... ($REQ, $RES) {...}" }, { "pattern-inside": "function ... ($REQ, $RES, $NEXT) {...}" }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES) {...})" }, { "pattern-inside": "$APP.$METHOD(..., function $FUNC($REQ, $RES, $NEXT) {...})" } ] }, { "metavariable-regex": { "metavariable": "$METHOD", "regex": "^(get|post|put|head|delete|options)$" } } ] } ] }, { "pattern-either": [ { "pattern": "$REQ.query" }, { "pattern": "$REQ.body" }, { "pattern": "$REQ.params" }, { "pattern": "$REQ.cookies" }, { "pattern": "$REQ.headers" } ] } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "({ $REQ }: Request,$RES: Response, $NEXT: NextFunction) =>\n{...}\n" }, { "pattern-inside": "({ $REQ }: Request,$RES: Response) => {...}\n" } ] }, { "focus-metavariable": "$REQ" }, { "pattern-either": [ { "pattern": "params" }, { "pattern": "query" }, { "pattern": "cookies" }, { "pattern": "headers" }, { "pattern": "body" } ] } ] } ], "pattern-sinks": [ { "patterns": [ { "pattern-either": [ { "pattern": "$RES.set($HEADER, ...)" }, { "pattern": "$RES.header($HEADER, ...)" }, { "pattern": "$RES.setHeader($HEADER, ...)" }, { "pattern": "$RES.set({$HEADER: ...}, ...)\n" }, { "pattern": "$RES.writeHead($STATUS, {$HEADER: ...}, ...)\n" } ] }, { "metavariable-regex": { "metavariable": "$HEADER", "regex": ".*(X-Frame-Options|x-frame-options).*" } } ] } ] }, { "id": "javascript.express.security.audit.express-cookie-settings.express-cookie-session-default-name", "message": "Don\u2019t use the default session cookie name Using the default session cookie name can open your app to attacks. The security issue posed is similar to X-Powered-By: a potential attacker can use it to fingerprint the server and target attacks accordingly.", "severity": "WARNING", "languages": [ "javascript", "typescript" ], "metadata": { "cwe": [ "CWE-522: Insufficiently Protected Credentials" ], "owasp": [ "A02:2017 - Broken Authentication", "A04:2021 - Insecure Design", "A06:2025 - Insecure Design" ], "source-rule-url": "https://expressjs.com/en/advanced/best-practice-security.html", "category": "security", "technology": [ "express" ], "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "LOW", "confidence": "MEDIUM", "references": [ "https://owasp.org/Top10/A04_2021-Insecure_Design" ], "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Cryptographic Issues" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-cookie-settings.express-cookie-session-default-name", "shortlink": "https://sg.run/1Z5x", "semgrep.dev": { "rule": { "r_id": 9266, "rv_id": 1263130, "rule_id": "eqU8k2", "version_id": "bZT536J", "url": "https://semgrep.dev/playground/r/bZT536J/javascript.express.security.audit.express-cookie-settings.express-cookie-session-default-name", "origin": "community" } } }, "patterns": [ { "pattern-either": [ { "pattern-inside": "$SESSION = require('cookie-session');\n...\n" }, { "pattern-inside": "$SESSION = require('express-session');\n...\n" } ] }, { "pattern": "$SESSION(...)" }, { "pattern-not-inside": "$SESSION(<... {name:...} ...>,...)" }, { "pattern-not-inside": "$OPTS = <... {name:...} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.name = ...;\n...\n$SESSION($OPTS,...);\n" } ] }, { "id": "javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-domain", "message": "Default session middleware settings: `domain` not set. It indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.", "severity": "WARNING", "languages": [ "javascript", "typescript" ], "metadata": { "cwe": [ "CWE-522: Insufficiently Protected Credentials" ], "owasp": [ "A02:2017 - Broken Authentication", "A04:2021 - Insecure Design", "A06:2025 - Insecure Design" ], "source-rule-url": "https://expressjs.com/en/advanced/best-practice-security.html", "category": "security", "technology": [ "express" ], "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "LOW", "confidence": "MEDIUM", "references": [ "https://owasp.org/Top10/A04_2021-Insecure_Design" ], "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Cryptographic Issues" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-domain", "shortlink": "https://sg.run/rd41", "semgrep.dev": { "rule": { "r_id": 9269, "rv_id": 1263133, "rule_id": "ZqU5Pn", "version_id": "w8TRoyd", "url": "https://semgrep.dev/playground/r/w8TRoyd/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-domain", "origin": "community" } } }, "patterns": [ { "pattern-either": [ { "pattern-inside": "$SESSION = require('cookie-session');\n...\n" }, { "pattern-inside": "$SESSION = require('express-session');\n...\n" } ] }, { "pattern": "$SESSION(...)" }, { "pattern-not-inside": "$SESSION(<... {cookie:{domain:...}} ...>,...)" }, { "pattern-not-inside": "$OPTS = <... {cookie:{domain:...}} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE = <... {domain:...} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie = <... {domain:...} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE.domain = ...;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie.domain = ...;\n...\n$SESSION($OPTS,...);\n" } ] }, { "id": "javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-httponly", "message": "Default session middleware settings: `httpOnly` not set. It ensures the cookie is sent only over HTTP(S), not client JavaScript, helping to protect against cross-site scripting attacks.", "severity": "WARNING", "languages": [ "javascript", "typescript" ], "metadata": { "cwe": [ "CWE-522: Insufficiently Protected Credentials" ], "owasp": [ "A02:2017 - Broken Authentication", "A04:2021 - Insecure Design", "A06:2025 - Insecure Design" ], "source-rule-url": "https://expressjs.com/en/advanced/best-practice-security.html", "category": "security", "technology": [ "express" ], "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "LOW", "confidence": "MEDIUM", "references": [ "https://owasp.org/Top10/A04_2021-Insecure_Design" ], "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Cryptographic Issues" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-httponly", "shortlink": "https://sg.run/ydBO", "semgrep.dev": { "rule": { "r_id": 9268, "rv_id": 1263132, "rule_id": "d8UjGo", "version_id": "kbTzGev", "url": "https://semgrep.dev/playground/r/kbTzGev/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-httponly", "origin": "community" } } }, "patterns": [ { "pattern-either": [ { "pattern-inside": "$SESSION = require('cookie-session');\n...\n" }, { "pattern-inside": "$SESSION = require('express-session');\n...\n" } ] }, { "pattern": "$SESSION(...)" }, { "pattern-not-inside": "$SESSION(<... {cookie:{httpOnly:true}} ...>,...)" }, { "pattern-not-inside": "$OPTS = <... {cookie:{httpOnly:true}} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE = <... {httpOnly:true} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie = <... {httpOnly:true} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE.httpOnly = true;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie.httpOnly = true;\n...\n$SESSION($OPTS,...);\n" } ] }, { "id": "javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-path", "message": "Default session middleware settings: `path` not set. It indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.", "severity": "WARNING", "languages": [ "javascript", "typescript" ], "metadata": { "cwe": [ "CWE-522: Insufficiently Protected Credentials" ], "owasp": [ "A02:2017 - Broken Authentication", "A04:2021 - Insecure Design", "A06:2025 - Insecure Design" ], "source-rule-url": "https://expressjs.com/en/advanced/best-practice-security.html", "category": "security", "technology": [ "express" ], "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "LOW", "confidence": "MEDIUM", "references": [ "https://owasp.org/Top10/A04_2021-Insecure_Design" ], "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Cryptographic Issues" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-path", "shortlink": "https://sg.run/b7pd", "semgrep.dev": { "rule": { "r_id": 9270, "rv_id": 1263134, "rule_id": "nJUz4X", "version_id": "xyTjzQD", "url": "https://semgrep.dev/playground/r/xyTjzQD/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-path", "origin": "community" } } }, "patterns": [ { "pattern-either": [ { "pattern-inside": "$SESSION = require('cookie-session');\n...\n" }, { "pattern-inside": "$SESSION = require('express-session');\n...\n" } ] }, { "pattern": "$SESSION(...)" }, { "pattern-not-inside": "$SESSION(<... {cookie:{path:...}} ...>,...)" }, { "pattern-not-inside": "$OPTS = <... {cookie:{path:...}} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE = <... {path:...} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie = <... {path:...} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE.path = ...;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie.path = ...;\n...\n$SESSION($OPTS,...);\n" } ] }, { "id": "javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-secure", "message": "Default session middleware settings: `secure` not set. It ensures the browser only sends the cookie over HTTPS.", "severity": "WARNING", "languages": [ "javascript", "typescript" ], "metadata": { "cwe": [ "CWE-522: Insufficiently Protected Credentials" ], "owasp": [ "A02:2017 - Broken Authentication", "A04:2021 - Insecure Design", "A06:2025 - Insecure Design" ], "source-rule-url": "https://expressjs.com/en/advanced/best-practice-security.html", "category": "security", "technology": [ "express" ], "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "LOW", "confidence": "MEDIUM", "references": [ "https://owasp.org/Top10/A04_2021-Insecure_Design" ], "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Cryptographic Issues" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-secure", "shortlink": "https://sg.run/9oKz", "semgrep.dev": { "rule": { "r_id": 9267, "rv_id": 1263131, "rule_id": "v8Unzw", "version_id": "NdTzyrv", "url": "https://semgrep.dev/playground/r/NdTzyrv/javascript.express.security.audit.express-cookie-settings.express-cookie-session-no-secure", "origin": "community" } } }, "patterns": [ { "pattern-either": [ { "pattern-inside": "$SESSION = require('cookie-session');\n...\n" }, { "pattern-inside": "$SESSION = require('express-session');\n...\n" } ] }, { "pattern": "$SESSION(...)" }, { "pattern-not-inside": "$SESSION(<... {cookie:{secure:true}} ...>,...)" }, { "pattern-not-inside": "$OPTS = <... {cookie:{secure:true}} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE = <... {secure:true} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie = <... {secure:true} ...>;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$COOKIE.secure = true;\n...\n$SESSION($OPTS,...);\n" }, { "pattern-not-inside": "$OPTS = ...;\n...\n$OPTS.cookie.secure = true;\n...\n$SESSION($OPTS,...);\n" } ] }, { "id": "javascript.express.security.audit.express-session-hardcoded-secret.express-session-hardcoded-secret", "message": "A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module).", "options": { "interfile": true }, "metadata": { "interfile": true, "cwe": [ "CWE-798: Use of Hard-coded Credentials" ], "references": [ "https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html" ], "owasp": [ "A07:2021 - Identification and Authentication Failures", "A07:2025 - Authentication Failures" ], "category": "security", "technology": [ "express", "secrets" ], "cwe2022-top25": true, "cwe2021-top25": true, "subcategory": [ "vuln" ], "likelihood": "HIGH", "impact": "HIGH", "confidence": "HIGH", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Hard-coded Secrets" ], "source": "https://semgrep.dev/r/javascript.express.security.audit.express-session-hardcoded-secret.express-session-hardcoded-secret", "shortlink": "https://sg.run/LYvG", "semgrep.dev": { "rule": { "r_id": 22083, "rv_id": 1263143, "rule_id": "10Uo39", "version_id": "LjTkgle", "url": "https://semgrep.dev/playground/r/LjTkgle/javascript.express.security.audit.express-session-hardcoded-secret.express-session-hardcoded-secret", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "severity": "WARNING", "patterns": [ { "pattern-either": [ { "pattern-inside": "$SESSION = require('express-session');\n...\n" }, { "pattern-inside": "import $SESSION from 'express-session'\n...\n" }, { "pattern-inside": "import {..., $SESSION, ...} from 'express-session'\n...\n" }, { "pattern-inside": "import * as $SESSION from 'express-session'\n...\n" } ] }, { "patterns": [ { "pattern-either": [ { "pattern-inside": "$APP.use($SESSION({...}))" }, { "pattern": "$SECRET = $VALUE\n...\n$APP.use($SESSION($SECRET))\n" } ] }, { "pattern": "secret: '$Y'\n" } ] } ] }, { "id": "problem-based-packs.insecure-transport.js-node.bypass-tls-verification.bypass-tls-verification", "message": "Checks for setting the environment variable NODE_TLS_REJECT_UNAUTHORIZED to 0, which disables TLS verification. This should only be used for debugging purposes. Setting the option rejectUnauthorized to false bypasses verification against the list of trusted CAs, which also leads to insecure transport. These options lead to vulnerability to MTM attacks, and should not be used.", "severity": "WARNING", "metadata": { "likelihood": "MEDIUM", "impact": "MEDIUM", "confidence": "MEDIUM", "category": "security", "cwe": "CWE-319: Cleartext Transmission of Sensitive Information", "owasp": "A03:2017 - Sensitive Data Exposure", "references": [ "https://nodejs.org/api/https.html#https_https_request_options_callback", "https://stackoverflow.com/questions/20433287/node-js-request-cert-has-expired#answer-29397100" ], "subcategory": [ "vuln" ], "technology": [ "node.js" ], "vulnerability": "Insecure Transport", "license": "Semgrep Rules License v1.0. For more details, visit semgrep.dev/legal/rules-license", "vulnerability_class": [ "Mishandled Sensitive Information" ], "source": "https://semgrep.dev/r/problem-based-packs.insecure-transport.js-node.bypass-tls-verification.bypass-tls-verification", "shortlink": "https://sg.run/9oxr", "semgrep.dev": { "rule": { "r_id": 9423, "rv_id": 946067, "rule_id": "OrU3Y6", "version_id": "JdTDybO", "url": "https://semgrep.dev/playground/r/JdTDybO/problem-based-packs.insecure-transport.js-node.bypass-tls-verification.bypass-tls-verification", "origin": "community" } } }, "languages": [ "javascript", "typescript" ], "pattern-either": [ { "pattern": "process.env[\"NODE_TLS_REJECT_UNAUTHORIZED\"] = 0;\n" }, { "pattern": "{rejectUnauthorized:false}\n" } ] } ], "missed": 212 }