\"/>\n\n```\nWhen the above function transforms the string, it becomes a string that results in an alert when a browser treats it as HTML.\n\n\n```html\n
\n

\"/>\n\n```\n\n## References\n* jQuery: [Security fixes in jQuery 3.5.0](https://blog.jquery.com/2020/04/10/jquery-3-5-0-released/)\n* OWASP: [DOM based XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html).\n* OWASP: [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html).\n* OWASP [Types of Cross-Site](https://owasp.org/www-community/Types_of_Cross-Site_Scripting).\n* Wikipedia: [Cross-site scripting](http://en.wikipedia.org/wiki/Cross-site_scripting).\n* Common Weakness Enumeration: [CWE-79](https://cwe.mitre.org/data/definitions/79.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n"
},
"properties" : {
- "tags" : [ "reliability", "frameworks/angularjs", "security", "external/cwe/cwe-1176" ],
- "description" : "Recompiling an already compiled part of the DOM can lead to\n unexpected behavior of directives, performance problems, and memory leaks.",
- "id" : "js/angular/double-compilation",
+ "tags" : [ "correctness", "security", "external/cwe/cwe-079", "external/cwe/cwe-116" ],
+ "description" : "Using regular expressions to expand self-closing HTML\n tags may lead to cross-site scripting vulnerabilities.",
+ "id" : "js/unsafe-html-expansion",
"kind" : "problem",
- "name" : "Double compilation",
+ "name" : "Unsafe expansion of self-closing HTML tag",
"precision" : "very-high",
"problem.severity" : "warning",
- "security-severity" : "8.8"
+ "security-severity" : "6.1"
}
}, {
- "id" : "js/angular/insecure-url-whitelist",
- "name" : "js/angular/insecure-url-whitelist",
+ "id" : "js/bad-tag-filter",
+ "name" : "js/bad-tag-filter",
"shortDescription" : {
- "text" : "Insecure URL whitelist"
+ "text" : "Bad HTML filtering regexp"
},
"fullDescription" : {
- "text" : "URL whitelists that are too permissive can cause security vulnerabilities."
+ "text" : "Matching HTML tags using regular expressions is hard to do right, and can easily lead to security issues."
},
"defaultConfiguration" : {
"enabled" : true,
"level" : "warning"
},
"help" : {
- "text" : "# Insecure URL whitelist\nAngularJS uses filters to ensure that the URLs used for sourcing AngularJS templates and other script-running URLs are safe. One such filter is a whitelist of URL patterns to allow.\n\nA URL pattern that is too permissive can cause security vulnerabilities.\n\n\n## Recommendation\nMake the whitelist URL patterns as restrictive as possible.\n\n\n## Example\nThe following example shows an AngularJS application with whitelist URL patterns that all are too permissive.\n\n\n```javascript\nangular.module('myApp', [])\n .config(function($sceDelegateProvider) {\n $sceDelegateProvider.resourceUrlWhitelist([\n \"*://example.org/*\", // BAD\n \"https://**.example.com/*\", // BAD\n \"https://example.**\", // BAD\n \"https://example.*\" // BAD\n ]);\n });\n\n```\nThis is problematic, since the four patterns match the following malicious URLs, respectively:\n\n* `javascript://example.org/a%0A%0Dalert(1)` (`%0A%0D` is a linebreak)\n* `https://evil.com/?ignore=://example.com/a`\n* `https://example.evil.com`\n* `https://example.evilTld`\n\n## References\n* OWASP/Google presentation: [Securing AngularJS Applications](https://www.owasp.org/images/6/6e/Benelus_day_20161125_S_Lekies_Securing_AngularJS_Applications.pdf)\n* AngularJS Developer Guide: [Format of items in resourceUrlWhitelist/Blacklist](https://docs.angularjs.org/api/ng/service/$sce#resourceUrlPatternItem).\n* Common Weakness Enumeration: [CWE-183](https://cwe.mitre.org/data/definitions/183.html).\n* Common Weakness Enumeration: [CWE-625](https://cwe.mitre.org/data/definitions/625.html).\n",
- "markdown" : "# Insecure URL whitelist\nAngularJS uses filters to ensure that the URLs used for sourcing AngularJS templates and other script-running URLs are safe. One such filter is a whitelist of URL patterns to allow.\n\nA URL pattern that is too permissive can cause security vulnerabilities.\n\n\n## Recommendation\nMake the whitelist URL patterns as restrictive as possible.\n\n\n## Example\nThe following example shows an AngularJS application with whitelist URL patterns that all are too permissive.\n\n\n```javascript\nangular.module('myApp', [])\n .config(function($sceDelegateProvider) {\n $sceDelegateProvider.resourceUrlWhitelist([\n \"*://example.org/*\", // BAD\n \"https://**.example.com/*\", // BAD\n \"https://example.**\", // BAD\n \"https://example.*\" // BAD\n ]);\n });\n\n```\nThis is problematic, since the four patterns match the following malicious URLs, respectively:\n\n* `javascript://example.org/a%0A%0Dalert(1)` (`%0A%0D` is a linebreak)\n* `https://evil.com/?ignore=://example.com/a`\n* `https://example.evil.com`\n* `https://example.evilTld`\n\n## References\n* OWASP/Google presentation: [Securing AngularJS Applications](https://www.owasp.org/images/6/6e/Benelus_day_20161125_S_Lekies_Securing_AngularJS_Applications.pdf)\n* AngularJS Developer Guide: [Format of items in resourceUrlWhitelist/Blacklist](https://docs.angularjs.org/api/ng/service/$sce#resourceUrlPatternItem).\n* Common Weakness Enumeration: [CWE-183](https://cwe.mitre.org/data/definitions/183.html).\n* Common Weakness Enumeration: [CWE-625](https://cwe.mitre.org/data/definitions/625.html).\n"
+ "text" : "# Bad HTML filtering regexp\nIt is possible to match some single HTML tags using regular expressions (parsing general HTML using regular expressions is impossible). However, if the regular expression is not written well it might be possible to circumvent it, which can lead to cross-site scripting or other security issues.\n\nSome of these mistakes are caused by browsers having very forgiving HTML parsers, and will often render invalid HTML containing syntax errors. Regular expressions that attempt to match HTML should also recognize tags containing such syntax errors.\n\n\n## Recommendation\nUse a well-tested sanitization or parser library if at all possible. These libraries are much more likely to handle corner cases correctly than a custom implementation.\n\n\n## Example\nThe following example attempts to filters out all `` as script end tags, but also tags such as `` even though it is a parser error. This means that an attack string such as `` will not be filtered by the function, and `alert(1)` will be executed by a browser if the string is rendered as HTML.\n\nOther corner cases include that HTML comments can end with `--!>`, and that HTML tag names can contain upper case characters.\n\n\n## References\n* Securitum: [The Curious Case of Copy & Paste](https://research.securitum.com/the-curious-case-of-copy-paste/).\n* stackoverflow.com: [You can't parse \\[X\\]HTML with regex](https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454).\n* HTML Standard: [Comment end bang state](https://html.spec.whatwg.org/multipage/parsing.html#comment-end-bang-state).\n* stackoverflow.com: [Why aren't browsers strict about HTML?](https://stackoverflow.com/questions/25559999/why-arent-browsers-strict-about-html).\n* Common Weakness Enumeration: [CWE-20](https://cwe.mitre.org/data/definitions/20.html).\n* Common Weakness Enumeration: [CWE-80](https://cwe.mitre.org/data/definitions/80.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n* Common Weakness Enumeration: [CWE-184](https://cwe.mitre.org/data/definitions/184.html).\n* Common Weakness Enumeration: [CWE-185](https://cwe.mitre.org/data/definitions/185.html).\n* Common Weakness Enumeration: [CWE-186](https://cwe.mitre.org/data/definitions/186.html).\n",
+ "markdown" : "# Bad HTML filtering regexp\nIt is possible to match some single HTML tags using regular expressions (parsing general HTML using regular expressions is impossible). However, if the regular expression is not written well it might be possible to circumvent it, which can lead to cross-site scripting or other security issues.\n\nSome of these mistakes are caused by browsers having very forgiving HTML parsers, and will often render invalid HTML containing syntax errors. Regular expressions that attempt to match HTML should also recognize tags containing such syntax errors.\n\n\n## Recommendation\nUse a well-tested sanitization or parser library if at all possible. These libraries are much more likely to handle corner cases correctly than a custom implementation.\n\n\n## Example\nThe following example attempts to filters out all `` as script end tags, but also tags such as `` even though it is a parser error. This means that an attack string such as `` will not be filtered by the function, and `alert(1)` will be executed by a browser if the string is rendered as HTML.\n\nOther corner cases include that HTML comments can end with `--!>`, and that HTML tag names can contain upper case characters.\n\n\n## References\n* Securitum: [The Curious Case of Copy & Paste](https://research.securitum.com/the-curious-case-of-copy-paste/).\n* stackoverflow.com: [You can't parse \\[X\\]HTML with regex](https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454).\n* HTML Standard: [Comment end bang state](https://html.spec.whatwg.org/multipage/parsing.html#comment-end-bang-state).\n* stackoverflow.com: [Why aren't browsers strict about HTML?](https://stackoverflow.com/questions/25559999/why-arent-browsers-strict-about-html).\n* Common Weakness Enumeration: [CWE-20](https://cwe.mitre.org/data/definitions/20.html).\n* Common Weakness Enumeration: [CWE-80](https://cwe.mitre.org/data/definitions/80.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n* Common Weakness Enumeration: [CWE-184](https://cwe.mitre.org/data/definitions/184.html).\n* Common Weakness Enumeration: [CWE-185](https://cwe.mitre.org/data/definitions/185.html).\n* Common Weakness Enumeration: [CWE-186](https://cwe.mitre.org/data/definitions/186.html).\n"
},
"properties" : {
- "tags" : [ "security", "frameworks/angularjs", "external/cwe/cwe-183", "external/cwe/cwe-625" ],
- "description" : "URL whitelists that are too permissive can cause security vulnerabilities.",
- "id" : "js/angular/insecure-url-whitelist",
+ "tags" : [ "correctness", "security", "external/cwe/cwe-020", "external/cwe/cwe-080", "external/cwe/cwe-116", "external/cwe/cwe-184", "external/cwe/cwe-185", "external/cwe/cwe-186" ],
+ "description" : "Matching HTML tags using regular expressions is hard to do right, and can easily lead to security issues.",
+ "id" : "js/bad-tag-filter",
"kind" : "problem",
- "name" : "Insecure URL whitelist",
- "precision" : "very-high",
+ "name" : "Bad HTML filtering regexp",
+ "precision" : "high",
"problem.severity" : "warning",
- "security-severity" : "7.5"
+ "security-severity" : "7.8"
}
}, {
- "id" : "js/angular/disabling-sce",
- "name" : "js/angular/disabling-sce",
+ "id" : "js/double-escaping",
+ "name" : "js/double-escaping",
"shortDescription" : {
- "text" : "Disabling SCE"
+ "text" : "Double escaping or unescaping"
},
"fullDescription" : {
- "text" : "Disabling strict contextual escaping (SCE) can cause security vulnerabilities."
+ "text" : "When escaping special characters using a meta-character like backslash or ampersand, the meta-character has to be escaped first to avoid double-escaping, and conversely it has to be unescaped last to avoid double-unescaping."
},
"defaultConfiguration" : {
"enabled" : true,
"level" : "warning"
},
"help" : {
- "text" : "# Disabling SCE\nAngularJS is secure by default through automated sanitization and filtering of untrusted values that could cause vulnerabilities such as XSS. Strict Contextual Escaping (SCE) is an execution mode in AngularJS that provides this security mechanism.\n\nDisabling SCE in an AngularJS application is strongly discouraged. It is even more discouraged to disable SCE in a library, since it is an application-wide setting.\n\n\n## Recommendation\nDo not disable SCE.\n\n\n## Example\nThe following example shows an AngularJS application that disables SCE in order to dynamically construct an HTML fragment, which is later inserted into the DOM through `$scope.html`.\n\n\n```javascript\nangular.module('app', [])\n .config(function($sceProvider) {\n $sceProvider.enabled(false); // BAD\n }).controller('controller', function($scope) {\n // ...\n $scope.html = '
';\n });\n\n```\nThis is problematic, since it disables SCE for the entire AngularJS application.\n\nInstead, just mark the dynamically constructed HTML fragment as safe using `$sce.trustAsHtml`, before assigning it to `$scope.html`:\n\n\n```javascript\nangular.module('app', [])\n .controller('controller', function($scope, $sce) {\n // ...\n // GOOD (but should use the templating system instead)\n $scope.html = $sce.trustAsHtml('
'); \n });\n\n```\nPlease note that this example is for illustrative purposes only; use the AngularJS templating system to dynamically construct HTML when possible.\n\n\n## References\n* AngularJS Developer Guide: [Strict Contextual Escaping](https://docs.angularjs.org/api/ng/service/$sce)\n* AngularJS Developer Guide: [Can I disable SCE completely?](https://docs.angularjs.org/api/ng/service/$sce#can-i-disable-sce-completely-).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n",
- "markdown" : "# Disabling SCE\nAngularJS is secure by default through automated sanitization and filtering of untrusted values that could cause vulnerabilities such as XSS. Strict Contextual Escaping (SCE) is an execution mode in AngularJS that provides this security mechanism.\n\nDisabling SCE in an AngularJS application is strongly discouraged. It is even more discouraged to disable SCE in a library, since it is an application-wide setting.\n\n\n## Recommendation\nDo not disable SCE.\n\n\n## Example\nThe following example shows an AngularJS application that disables SCE in order to dynamically construct an HTML fragment, which is later inserted into the DOM through `$scope.html`.\n\n\n```javascript\nangular.module('app', [])\n .config(function($sceProvider) {\n $sceProvider.enabled(false); // BAD\n }).controller('controller', function($scope) {\n // ...\n $scope.html = '
';\n });\n\n```\nThis is problematic, since it disables SCE for the entire AngularJS application.\n\nInstead, just mark the dynamically constructed HTML fragment as safe using `$sce.trustAsHtml`, before assigning it to `$scope.html`:\n\n\n```javascript\nangular.module('app', [])\n .controller('controller', function($scope, $sce) {\n // ...\n // GOOD (but should use the templating system instead)\n $scope.html = $sce.trustAsHtml('
'); \n });\n\n```\nPlease note that this example is for illustrative purposes only; use the AngularJS templating system to dynamically construct HTML when possible.\n\n\n## References\n* AngularJS Developer Guide: [Strict Contextual Escaping](https://docs.angularjs.org/api/ng/service/$sce)\n* AngularJS Developer Guide: [Can I disable SCE completely?](https://docs.angularjs.org/api/ng/service/$sce#can-i-disable-sce-completely-).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n"
+ "text" : "# Double escaping or unescaping\nEscaping meta-characters in untrusted input is an important technique for preventing injection attacks such as cross-site scripting. One particular example of this is HTML entity encoding, where HTML special characters are replaced by HTML character entities to prevent them from being interpreted as HTML markup. For example, the less-than character is encoded as `<` and the double-quote character as `"`. Other examples include backslash-escaping for including untrusted data in string literals and percent-encoding for URI components.\n\nThe reverse process of replacing escape sequences with the characters they represent is known as unescaping.\n\nNote that the escape characters themselves (such as ampersand in the case of HTML encoding) play a special role during escaping and unescaping: they are themselves escaped, but also form part of the escaped representations of other characters. Hence care must be taken to avoid double escaping and unescaping: when escaping, the escape character must be escaped first, when unescaping it has to be unescaped last.\n\nIf used in the context of sanitization, double unescaping may render the sanitization ineffective. Even if it is not used in a security-critical context, it may still result in confusing or garbled output.\n\n\n## Recommendation\nUse a (well-tested) sanitization library if at all possible. These libraries are much more likely to handle corner cases correctly than a custom implementation. For URI encoding, you can use the standard `encodeURIComponent` and `decodeURIComponent` functions.\n\nOtherwise, make sure to always escape the escape character first, and unescape it last.\n\n\n## Example\nThe following example shows a pair of hand-written HTML encoding and decoding functions:\n\n\n```javascript\nmodule.exports.encode = function(s) {\n return s.replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n};\n\nmodule.exports.decode = function(s) {\n return s.replace(/&/g, \"&\")\n .replace(/"/g, \"\\\"\")\n .replace(/'/g, \"'\");\n};\n\n```\nThe encoding function correctly handles ampersand before the other characters. For example, the string `me & \"you\"` is encoded as `me & "you"`, and the string `"` is encoded as `"`.\n\nThe decoding function, however, incorrectly decodes `&` into `&` before handling the other characters. So while it correctly decodes the first example above, it decodes the second example (`"`) to `\"` (a single double quote), which is not correct.\n\nInstead, the decoding function should decode the ampersand last:\n\n\n```javascript\nmodule.exports.encode = function(s) {\n return s.replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n};\n\nmodule.exports.decode = function(s) {\n return s.replace(/"/g, \"\\\"\")\n .replace(/'/g, \"'\")\n .replace(/&/g, \"&\");\n};\n\n```\n\n## References\n* OWASP Top 10: [A1 Injection](https://www.owasp.org/index.php/Top_10-2017_A1-Injection).\n* npm: [html-entities](https://www.npmjs.com/package/html-entities) package.\n* npm: [js-string-escape](https://www.npmjs.com/package/js-string-escape) package.\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n* Common Weakness Enumeration: [CWE-20](https://cwe.mitre.org/data/definitions/20.html).\n",
+ "markdown" : "# Double escaping or unescaping\nEscaping meta-characters in untrusted input is an important technique for preventing injection attacks such as cross-site scripting. One particular example of this is HTML entity encoding, where HTML special characters are replaced by HTML character entities to prevent them from being interpreted as HTML markup. For example, the less-than character is encoded as `<` and the double-quote character as `"`. Other examples include backslash-escaping for including untrusted data in string literals and percent-encoding for URI components.\n\nThe reverse process of replacing escape sequences with the characters they represent is known as unescaping.\n\nNote that the escape characters themselves (such as ampersand in the case of HTML encoding) play a special role during escaping and unescaping: they are themselves escaped, but also form part of the escaped representations of other characters. Hence care must be taken to avoid double escaping and unescaping: when escaping, the escape character must be escaped first, when unescaping it has to be unescaped last.\n\nIf used in the context of sanitization, double unescaping may render the sanitization ineffective. Even if it is not used in a security-critical context, it may still result in confusing or garbled output.\n\n\n## Recommendation\nUse a (well-tested) sanitization library if at all possible. These libraries are much more likely to handle corner cases correctly than a custom implementation. For URI encoding, you can use the standard `encodeURIComponent` and `decodeURIComponent` functions.\n\nOtherwise, make sure to always escape the escape character first, and unescape it last.\n\n\n## Example\nThe following example shows a pair of hand-written HTML encoding and decoding functions:\n\n\n```javascript\nmodule.exports.encode = function(s) {\n return s.replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n};\n\nmodule.exports.decode = function(s) {\n return s.replace(/&/g, \"&\")\n .replace(/"/g, \"\\\"\")\n .replace(/'/g, \"'\");\n};\n\n```\nThe encoding function correctly handles ampersand before the other characters. For example, the string `me & \"you\"` is encoded as `me & "you"`, and the string `"` is encoded as `"`.\n\nThe decoding function, however, incorrectly decodes `&` into `&` before handling the other characters. So while it correctly decodes the first example above, it decodes the second example (`"`) to `\"` (a single double quote), which is not correct.\n\nInstead, the decoding function should decode the ampersand last:\n\n\n```javascript\nmodule.exports.encode = function(s) {\n return s.replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n};\n\nmodule.exports.decode = function(s) {\n return s.replace(/"/g, \"\\\"\")\n .replace(/'/g, \"'\")\n .replace(/&/g, \"&\");\n};\n\n```\n\n## References\n* OWASP Top 10: [A1 Injection](https://www.owasp.org/index.php/Top_10-2017_A1-Injection).\n* npm: [html-entities](https://www.npmjs.com/package/html-entities) package.\n* npm: [js-string-escape](https://www.npmjs.com/package/js-string-escape) package.\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n* Common Weakness Enumeration: [CWE-20](https://cwe.mitre.org/data/definitions/20.html).\n"
},
"properties" : {
- "tags" : [ "security", "maintainability", "frameworks/angularjs", "external/cwe/cwe-116" ],
- "description" : "Disabling strict contextual escaping (SCE) can cause security vulnerabilities.",
- "id" : "js/angular/disabling-sce",
+ "tags" : [ "correctness", "security", "external/cwe/cwe-116", "external/cwe/cwe-020" ],
+ "description" : "When escaping special characters using a meta-character like backslash or\n ampersand, the meta-character has to be escaped first to avoid double-escaping,\n and conversely it has to be unescaped last to avoid double-unescaping.",
+ "id" : "js/double-escaping",
"kind" : "problem",
- "name" : "Disabling SCE",
- "precision" : "very-high",
+ "name" : "Double escaping or unescaping",
+ "precision" : "high",
"problem.severity" : "warning",
"security-severity" : "7.8"
}
}, {
- "id" : "js/loop-bound-injection",
- "name" : "js/loop-bound-injection",
+ "id" : "js/incomplete-multi-character-sanitization",
+ "name" : "js/incomplete-multi-character-sanitization",
"shortDescription" : {
- "text" : "Loop bound injection"
+ "text" : "Incomplete multi-character sanitization"
},
"fullDescription" : {
- "text" : "Iterating over an object with a user-controlled .length property can cause indefinite looping."
+ "text" : "A sanitizer that removes a sequence of characters may reintroduce the dangerous sequence."
},
"defaultConfiguration" : {
"enabled" : true,
"level" : "warning"
},
"help" : {
- "text" : "# Loop bound injection\nUsing the `.length` property of an untrusted object as a loop bound may cause indefinite looping since a malicious attacker can set the `.length` property to a very large number. For example, when a program that expects an array is passed a JSON object such as `{length: 1e100}`, the loop will be run for 10
100 iterations. This may cause the program to hang or run out of memory, which can be used to mount a denial-of-service (DoS) attack.\n\n\n## Recommendation\nEither check that the object is indeed an array or limit the size of the `.length` property.\n\n\n## Example\nIn the example below, an HTTP request handler iterates over a user-controlled object `obj` using the `obj.length` property in order to copy the elements from `obj` to an array.\n\n\n```javascript\nvar express = require('express');\nvar app = express();\n\napp.post(\"/foo\", (req, res) => {\n var obj = req.body;\n\n var ret = [];\n\n // Potential DoS if obj.length is large.\n for (var i = 0; i < obj.length; i++) {\n ret.push(obj[i]);\n }\n});\n\n```\nThis is not secure since an attacker can control the value of `obj.length`, and thereby cause the loop to iterate indefinitely. Here the potential DoS is fixed by enforcing that the user-controlled object is an array.\n\n\n```javascript\nvar express = require('express');\nvar app = express();\n\napp.post(\"/foo\", (req, res) => {\n var obj = req.body;\n \n if (!(obj instanceof Array)) { // Prevents DoS.\n return [];\n }\n\n var ret = [];\n\n for (var i = 0; i < obj.length; i++) {\n ret.push(obj[i]);\n }\n});\n\n```\n\n## References\n* Common Weakness Enumeration: [CWE-834](https://cwe.mitre.org/data/definitions/834.html).\n* Common Weakness Enumeration: [CWE-730](https://cwe.mitre.org/data/definitions/730.html).\n",
- "markdown" : "# Loop bound injection\nUsing the `.length` property of an untrusted object as a loop bound may cause indefinite looping since a malicious attacker can set the `.length` property to a very large number. For example, when a program that expects an array is passed a JSON object such as `{length: 1e100}`, the loop will be run for 10
100 iterations. This may cause the program to hang or run out of memory, which can be used to mount a denial-of-service (DoS) attack.\n\n\n## Recommendation\nEither check that the object is indeed an array or limit the size of the `.length` property.\n\n\n## Example\nIn the example below, an HTTP request handler iterates over a user-controlled object `obj` using the `obj.length` property in order to copy the elements from `obj` to an array.\n\n\n```javascript\nvar express = require('express');\nvar app = express();\n\napp.post(\"/foo\", (req, res) => {\n var obj = req.body;\n\n var ret = [];\n\n // Potential DoS if obj.length is large.\n for (var i = 0; i < obj.length; i++) {\n ret.push(obj[i]);\n }\n});\n\n```\nThis is not secure since an attacker can control the value of `obj.length`, and thereby cause the loop to iterate indefinitely. Here the potential DoS is fixed by enforcing that the user-controlled object is an array.\n\n\n```javascript\nvar express = require('express');\nvar app = express();\n\napp.post(\"/foo\", (req, res) => {\n var obj = req.body;\n \n if (!(obj instanceof Array)) { // Prevents DoS.\n return [];\n }\n\n var ret = [];\n\n for (var i = 0; i < obj.length; i++) {\n ret.push(obj[i]);\n }\n});\n\n```\n\n## References\n* Common Weakness Enumeration: [CWE-834](https://cwe.mitre.org/data/definitions/834.html).\n* Common Weakness Enumeration: [CWE-730](https://cwe.mitre.org/data/definitions/730.html).\n"
+ "text" : "# Incomplete multi-character sanitization\nSanitizing untrusted input is a common technique for preventing injection attacks and other security vulnerabilities. Regular expressions are often used to perform this sanitization. However, when the regular expression matches multiple consecutive characters, replacing it just once can result in the unsafe text reappearing in the sanitized input.\n\nAttackers can exploit this issue by crafting inputs that, when sanitized with an ineffective regular expression, still contain malicious code or content. This can lead to code execution, data exposure, or other vulnerabilities.\n\n\n## Recommendation\nTo prevent this issue, it is highly recommended to use a well-tested sanitization library whenever possible. These libraries are more likely to handle corner cases and ensure effective sanitization.\n\nIf a library is not an option, you can consider alternative strategies to fix the issue. For example, applying the regular expression replacement repeatedly until no more replacements can be performed, or rewriting the regular expression to match single characters instead of the entire unsafe text.\n\n\n## Example\nConsider the following JavaScript code that aims to remove all HTML comment start and end tags:\n\n```javascript\n\nstr.replace(/`, and that HTML tag names can contain upper case characters.\n\n\n## References\n* Securitum: [The Curious Case of Copy & Paste](https://research.securitum.com/the-curious-case-of-copy-paste/).\n* stackoverflow.com: [You can't parse \\[X\\]HTML with regex](https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454).\n* HTML Standard: [Comment end bang state](https://html.spec.whatwg.org/multipage/parsing.html#comment-end-bang-state).\n* stackoverflow.com: [Why aren't browsers strict about HTML?](https://stackoverflow.com/questions/25559999/why-arent-browsers-strict-about-html).\n* Common Weakness Enumeration: [CWE-20](https://cwe.mitre.org/data/definitions/20.html).\n* Common Weakness Enumeration: [CWE-80](https://cwe.mitre.org/data/definitions/80.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n* Common Weakness Enumeration: [CWE-184](https://cwe.mitre.org/data/definitions/184.html).\n* Common Weakness Enumeration: [CWE-185](https://cwe.mitre.org/data/definitions/185.html).\n* Common Weakness Enumeration: [CWE-186](https://cwe.mitre.org/data/definitions/186.html).\n",
- "markdown" : "# Bad HTML filtering regexp\nIt is possible to match some single HTML tags using regular expressions (parsing general HTML using regular expressions is impossible). However, if the regular expression is not written well it might be possible to circumvent it, which can lead to cross-site scripting or other security issues.\n\nSome of these mistakes are caused by browsers having very forgiving HTML parsers, and will often render invalid HTML containing syntax errors. Regular expressions that attempt to match HTML should also recognize tags containing such syntax errors.\n\n\n## Recommendation\nUse a well-tested sanitization or parser library if at all possible. These libraries are much more likely to handle corner cases correctly than a custom implementation.\n\n\n## Example\nThe following example attempts to filters out all `` as script end tags, but also tags such as `` even though it is a parser error. This means that an attack string such as `` will not be filtered by the function, and `alert(1)` will be executed by a browser if the string is rendered as HTML.\n\nOther corner cases include that HTML comments can end with `--!>`, and that HTML tag names can contain upper case characters.\n\n\n## References\n* Securitum: [The Curious Case of Copy & Paste](https://research.securitum.com/the-curious-case-of-copy-paste/).\n* stackoverflow.com: [You can't parse \\[X\\]HTML with regex](https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454).\n* HTML Standard: [Comment end bang state](https://html.spec.whatwg.org/multipage/parsing.html#comment-end-bang-state).\n* stackoverflow.com: [Why aren't browsers strict about HTML?](https://stackoverflow.com/questions/25559999/why-arent-browsers-strict-about-html).\n* Common Weakness Enumeration: [CWE-20](https://cwe.mitre.org/data/definitions/20.html).\n* Common Weakness Enumeration: [CWE-80](https://cwe.mitre.org/data/definitions/80.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n* Common Weakness Enumeration: [CWE-184](https://cwe.mitre.org/data/definitions/184.html).\n* Common Weakness Enumeration: [CWE-185](https://cwe.mitre.org/data/definitions/185.html).\n* Common Weakness Enumeration: [CWE-186](https://cwe.mitre.org/data/definitions/186.html).\n"
+ "text" : "# Creating biased random numbers from a cryptographically secure source\nGenerating secure random numbers can be an important part of creating a secure software system. This can be done using APIs that create cryptographically secure random numbers.\n\nHowever, using some mathematical operations on these cryptographically secure random numbers can create biased results, where some outcomes are more likely than others. Such biased results can make it easier for an attacker to guess the random numbers, and thereby break the security of the software system.\n\n\n## Recommendation\nBe very careful not to introduce bias when performing mathematical operations on cryptographically secure random numbers.\n\nIf possible, avoid performing mathematical operations on cryptographically secure random numbers at all, and use a preexisting library instead.\n\n\n## Example\nThe example below uses the modulo operator to create an array of 10 random digits using random bytes as the source for randomness.\n\n\n```javascript\nconst crypto = require('crypto');\n\nconst digits = [];\nfor (let i = 0; i < 10; i++) {\n digits.push(crypto.randomBytes(1)[0] % 10); // NOT OK\n}\n```\nThe random byte is a uniformly random value between 0 and 255, and thus the result from using the modulo operator is slightly more likely to be between 0 and 5 than between 6 and 9.\n\nThe issue has been fixed in the code below by using a library that correctly generates cryptographically secure random values.\n\n\n```javascript\nconst cryptoRandomString = require('crypto-random-string');\n\nconst digits = cryptoRandomString({length: 10, type: 'numeric'});\n```\nAlternatively, the issue can be fixed by fixing the math in the original code. In the code below the random byte is discarded if the value is greater than or equal to 250. Thus the modulo operator is used on a uniformly random number between 0 and 249, which results in a uniformly random digit between 0 and 9.\n\n\n```javascript\nconst crypto = require('crypto');\n\nconst digits = [];\nwhile (digits.length < 10) {\n const byte = crypto.randomBytes(1)[0];\n if (byte >= 250) {\n continue;\n }\n digits.push(byte % 10); // OK\n}\n```\n\n## References\n* Stack Overflow: [Understanding “randomness”](https://stackoverflow.com/questions/3956478/understanding-randomness).\n* OWASP: [Insecure Randomness](https://owasp.org/www-community/vulnerabilities/Insecure_Randomness).\n* OWASP: [Rule - Use strong approved cryptographic algorithms](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#rule---use-strong-approved-authenticated-encryption).\n* Common Weakness Enumeration: [CWE-327](https://cwe.mitre.org/data/definitions/327.html).\n",
+ "markdown" : "# Creating biased random numbers from a cryptographically secure source\nGenerating secure random numbers can be an important part of creating a secure software system. This can be done using APIs that create cryptographically secure random numbers.\n\nHowever, using some mathematical operations on these cryptographically secure random numbers can create biased results, where some outcomes are more likely than others. Such biased results can make it easier for an attacker to guess the random numbers, and thereby break the security of the software system.\n\n\n## Recommendation\nBe very careful not to introduce bias when performing mathematical operations on cryptographically secure random numbers.\n\nIf possible, avoid performing mathematical operations on cryptographically secure random numbers at all, and use a preexisting library instead.\n\n\n## Example\nThe example below uses the modulo operator to create an array of 10 random digits using random bytes as the source for randomness.\n\n\n```javascript\nconst crypto = require('crypto');\n\nconst digits = [];\nfor (let i = 0; i < 10; i++) {\n digits.push(crypto.randomBytes(1)[0] % 10); // NOT OK\n}\n```\nThe random byte is a uniformly random value between 0 and 255, and thus the result from using the modulo operator is slightly more likely to be between 0 and 5 than between 6 and 9.\n\nThe issue has been fixed in the code below by using a library that correctly generates cryptographically secure random values.\n\n\n```javascript\nconst cryptoRandomString = require('crypto-random-string');\n\nconst digits = cryptoRandomString({length: 10, type: 'numeric'});\n```\nAlternatively, the issue can be fixed by fixing the math in the original code. In the code below the random byte is discarded if the value is greater than or equal to 250. Thus the modulo operator is used on a uniformly random number between 0 and 249, which results in a uniformly random digit between 0 and 9.\n\n\n```javascript\nconst crypto = require('crypto');\n\nconst digits = [];\nwhile (digits.length < 10) {\n const byte = crypto.randomBytes(1)[0];\n if (byte >= 250) {\n continue;\n }\n digits.push(byte % 10); // OK\n}\n```\n\n## References\n* Stack Overflow: [Understanding “randomness”](https://stackoverflow.com/questions/3956478/understanding-randomness).\n* OWASP: [Insecure Randomness](https://owasp.org/www-community/vulnerabilities/Insecure_Randomness).\n* OWASP: [Rule - Use strong approved cryptographic algorithms](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#rule---use-strong-approved-authenticated-encryption).\n* Common Weakness Enumeration: [CWE-327](https://cwe.mitre.org/data/definitions/327.html).\n"
},
"properties" : {
- "tags" : [ "correctness", "security", "external/cwe/cwe-020", "external/cwe/cwe-080", "external/cwe/cwe-116", "external/cwe/cwe-184", "external/cwe/cwe-185", "external/cwe/cwe-186" ],
- "description" : "Matching HTML tags using regular expressions is hard to do right, and can easily lead to security issues.",
- "id" : "js/bad-tag-filter",
+ "tags" : [ "security", "external/cwe/cwe-327" ],
+ "description" : "Some mathematical operations on random numbers can cause bias in\n the results and compromise security.",
+ "id" : "js/biased-cryptographic-random",
"kind" : "problem",
- "name" : "Bad HTML filtering regexp",
+ "name" : "Creating biased random numbers from a cryptographically secure source",
"precision" : "high",
"problem.severity" : "warning",
- "security-severity" : "7.8"
+ "security-severity" : "7.5"
}
}, {
- "id" : "js/incomplete-sanitization",
- "name" : "js/incomplete-sanitization",
+ "id" : "js/bad-code-sanitization",
+ "name" : "js/bad-code-sanitization",
"shortDescription" : {
- "text" : "Incomplete string escaping or encoding"
+ "text" : "Improper code sanitization"
},
"fullDescription" : {
- "text" : "A string transformer that does not replace or escape all occurrences of a meta-character may be ineffective."
+ "text" : "Escaping code as HTML does not provide protection against code injection."
},
"defaultConfiguration" : {
"enabled" : true,
- "level" : "warning"
+ "level" : "error"
},
"help" : {
- "text" : "# Incomplete string escaping or encoding\nSanitizing untrusted input is a common technique for preventing injection attacks such as SQL injection or cross-site scripting. Usually, this is done by escaping meta-characters such as quotes in a domain-specific way so that they are treated as normal characters.\n\nHowever, directly using the string `replace` method to perform escaping is notoriously error-prone. Common mistakes include only replacing the first occurrence of a meta-character, or backslash-escaping various meta-characters but not the backslash itself.\n\nIn the former case, later meta-characters are left undisturbed and can be used to subvert the sanitization. In the latter case, preceding a meta-character with a backslash leads to the backslash being escaped, but the meta-character appearing un-escaped, which again makes the sanitization ineffective.\n\nEven if the escaped string is not used in a security-critical context, incomplete escaping may still have undesirable effects, such as badly rendered or confusing output.\n\n\n## Recommendation\nUse a (well-tested) sanitization library if at all possible. These libraries are much more likely to handle corner cases correctly than a custom implementation.\n\nAn even safer alternative is to design the application so that sanitization is not needed, for instance by using prepared statements for SQL queries.\n\nOtherwise, make sure to use a regular expression with the `g` flag to ensure that all occurrences are replaced, and remember to escape backslashes if applicable.\n\n\n## Example\nFor example, assume that we want to embed a user-controlled string `accountNumber` into a SQL query as part of a string literal. To avoid SQL injection, we need to ensure that the string does not contain un-escaped single-quote characters. The following function attempts to ensure this by doubling single quotes, and thereby escaping them:\n\n\n```javascript\nfunction escapeQuotes(s) {\n return s.replace(\"'\", \"''\");\n}\n\n```\nAs written, this sanitizer is ineffective: if the first argument to `replace` is a string literal (as in this case), only the *first* occurrence of that string is replaced.\n\nAs mentioned above, the function `escapeQuotes` should be replaced with a purpose-built sanitization library, such as the npm module `sqlstring`. Many other sanitization libraries are available from npm and other sources.\n\nIf this is not an option, `escapeQuotes` should be rewritten to use a regular expression with the `g` (\"global\") flag instead:\n\n\n```javascript\nfunction escapeQuotes(s) {\n return s.replace(/'/g, \"''\");\n}\n\n```\nNote that it is very important to include the global flag: `s.replace(/'/, \"''\")` *without* the global flag is equivalent to the first example above and only replaces the first quote.\n\n\n## References\n* OWASP Top 10: [A1 Injection](https://www.owasp.org/index.php/Top_10-2017_A1-Injection).\n* npm: [sqlstring](https://www.npmjs.com/package/sqlstring) package.\n* Common Weakness Enumeration: [CWE-20](https://cwe.mitre.org/data/definitions/20.html).\n* Common Weakness Enumeration: [CWE-80](https://cwe.mitre.org/data/definitions/80.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n",
- "markdown" : "# Incomplete string escaping or encoding\nSanitizing untrusted input is a common technique for preventing injection attacks such as SQL injection or cross-site scripting. Usually, this is done by escaping meta-characters such as quotes in a domain-specific way so that they are treated as normal characters.\n\nHowever, directly using the string `replace` method to perform escaping is notoriously error-prone. Common mistakes include only replacing the first occurrence of a meta-character, or backslash-escaping various meta-characters but not the backslash itself.\n\nIn the former case, later meta-characters are left undisturbed and can be used to subvert the sanitization. In the latter case, preceding a meta-character with a backslash leads to the backslash being escaped, but the meta-character appearing un-escaped, which again makes the sanitization ineffective.\n\nEven if the escaped string is not used in a security-critical context, incomplete escaping may still have undesirable effects, such as badly rendered or confusing output.\n\n\n## Recommendation\nUse a (well-tested) sanitization library if at all possible. These libraries are much more likely to handle corner cases correctly than a custom implementation.\n\nAn even safer alternative is to design the application so that sanitization is not needed, for instance by using prepared statements for SQL queries.\n\nOtherwise, make sure to use a regular expression with the `g` flag to ensure that all occurrences are replaced, and remember to escape backslashes if applicable.\n\n\n## Example\nFor example, assume that we want to embed a user-controlled string `accountNumber` into a SQL query as part of a string literal. To avoid SQL injection, we need to ensure that the string does not contain un-escaped single-quote characters. The following function attempts to ensure this by doubling single quotes, and thereby escaping them:\n\n\n```javascript\nfunction escapeQuotes(s) {\n return s.replace(\"'\", \"''\");\n}\n\n```\nAs written, this sanitizer is ineffective: if the first argument to `replace` is a string literal (as in this case), only the *first* occurrence of that string is replaced.\n\nAs mentioned above, the function `escapeQuotes` should be replaced with a purpose-built sanitization library, such as the npm module `sqlstring`. Many other sanitization libraries are available from npm and other sources.\n\nIf this is not an option, `escapeQuotes` should be rewritten to use a regular expression with the `g` (\"global\") flag instead:\n\n\n```javascript\nfunction escapeQuotes(s) {\n return s.replace(/'/g, \"''\");\n}\n\n```\nNote that it is very important to include the global flag: `s.replace(/'/, \"''\")` *without* the global flag is equivalent to the first example above and only replaces the first quote.\n\n\n## References\n* OWASP Top 10: [A1 Injection](https://www.owasp.org/index.php/Top_10-2017_A1-Injection).\n* npm: [sqlstring](https://www.npmjs.com/package/sqlstring) package.\n* Common Weakness Enumeration: [CWE-20](https://cwe.mitre.org/data/definitions/20.html).\n* Common Weakness Enumeration: [CWE-80](https://cwe.mitre.org/data/definitions/80.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n"
+ "text" : "# Improper code sanitization\nUsing string concatenation to construct JavaScript code can be error-prone, or in the worst case, enable code injection if an input is constructed by an attacker.\n\n\n## Recommendation\nIf using `JSON.stringify` or an HTML sanitizer to sanitize a string inserted into JavaScript code, then make sure to perform additional sanitization or remove potentially dangerous characters.\n\n\n## Example\nThe example below constructs a function that assigns the number 42 to the property `key` on an object `obj`. However, if `key` contains ``, then the generated code will break out of a `` if inserted into a `` tag.\n\n\n```javascript\nfunction createObjectWrite() {\n const assignment = `obj[${JSON.stringify(key)}]=42`;\n return `(function(){${assignment}})` // NOT OK\n}\n```\nThe issue has been fixed by escaping potentially dangerous characters, as shown below.\n\n\n```javascript\nconst charMap = {\n '<': '\\\\u003C',\n '>' : '\\\\u003E',\n '/': '\\\\u002F',\n '\\\\': '\\\\\\\\',\n '\\b': '\\\\b',\n '\\f': '\\\\f',\n '\\n': '\\\\n',\n '\\r': '\\\\r',\n '\\t': '\\\\t',\n '\\0': '\\\\0',\n '\\u2028': '\\\\u2028',\n '\\u2029': '\\\\u2029'\n};\n\nfunction escapeUnsafeChars(str) {\n return str.replace(/[<>\\b\\f\\n\\r\\t\\0\\u2028\\u2029]/g, x => charMap[x])\n}\n\nfunction createObjectWrite() {\n const assignment = `obj[${escapeUnsafeChars(JSON.stringify(key))}]=42`;\n return `(function(){${assignment}})` // OK\n}\n```\n\n## References\n* OWASP: [Code Injection](https://www.owasp.org/index.php/Code_Injection).\n* Common Weakness Enumeration: [CWE-94](https://cwe.mitre.org/data/definitions/94.html).\n* Common Weakness Enumeration: [CWE-79](https://cwe.mitre.org/data/definitions/79.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n",
+ "markdown" : "# Improper code sanitization\nUsing string concatenation to construct JavaScript code can be error-prone, or in the worst case, enable code injection if an input is constructed by an attacker.\n\n\n## Recommendation\nIf using `JSON.stringify` or an HTML sanitizer to sanitize a string inserted into JavaScript code, then make sure to perform additional sanitization or remove potentially dangerous characters.\n\n\n## Example\nThe example below constructs a function that assigns the number 42 to the property `key` on an object `obj`. However, if `key` contains ``, then the generated code will break out of a `` if inserted into a `` tag.\n\n\n```javascript\nfunction createObjectWrite() {\n const assignment = `obj[${JSON.stringify(key)}]=42`;\n return `(function(){${assignment}})` // NOT OK\n}\n```\nThe issue has been fixed by escaping potentially dangerous characters, as shown below.\n\n\n```javascript\nconst charMap = {\n '<': '\\\\u003C',\n '>' : '\\\\u003E',\n '/': '\\\\u002F',\n '\\\\': '\\\\\\\\',\n '\\b': '\\\\b',\n '\\f': '\\\\f',\n '\\n': '\\\\n',\n '\\r': '\\\\r',\n '\\t': '\\\\t',\n '\\0': '\\\\0',\n '\\u2028': '\\\\u2028',\n '\\u2029': '\\\\u2029'\n};\n\nfunction escapeUnsafeChars(str) {\n return str.replace(/[<>\\b\\f\\n\\r\\t\\0\\u2028\\u2029]/g, x => charMap[x])\n}\n\nfunction createObjectWrite() {\n const assignment = `obj[${escapeUnsafeChars(JSON.stringify(key))}]=42`;\n return `(function(){${assignment}})` // OK\n}\n```\n\n## References\n* OWASP: [Code Injection](https://www.owasp.org/index.php/Code_Injection).\n* Common Weakness Enumeration: [CWE-94](https://cwe.mitre.org/data/definitions/94.html).\n* Common Weakness Enumeration: [CWE-79](https://cwe.mitre.org/data/definitions/79.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n"
},
"properties" : {
- "tags" : [ "correctness", "security", "external/cwe/cwe-020", "external/cwe/cwe-080", "external/cwe/cwe-116" ],
- "description" : "A string transformer that does not replace or escape all occurrences of a\n meta-character may be ineffective.",
- "id" : "js/incomplete-sanitization",
- "kind" : "problem",
- "name" : "Incomplete string escaping or encoding",
+ "tags" : [ "security", "external/cwe/cwe-094", "external/cwe/cwe-079", "external/cwe/cwe-116" ],
+ "description" : "Escaping code as HTML does not provide protection against code injection.",
+ "id" : "js/bad-code-sanitization",
+ "kind" : "path-problem",
+ "name" : "Improper code sanitization",
"precision" : "high",
- "problem.severity" : "warning",
- "security-severity" : "7.8"
+ "problem.severity" : "error",
+ "security-severity" : "6.1"
}
}, {
- "id" : "js/unsafe-html-expansion",
- "name" : "js/unsafe-html-expansion",
+ "id" : "js/actions/command-injection",
+ "name" : "js/actions/command-injection",
"shortDescription" : {
- "text" : "Unsafe expansion of self-closing HTML tag"
+ "text" : "Expression injection in Actions"
},
"fullDescription" : {
- "text" : "Using regular expressions to expand self-closing HTML tags may lead to cross-site scripting vulnerabilities."
+ "text" : "Using user-controlled GitHub Actions contexts like `run:` or `script:` may allow a malicious user to inject code into the GitHub action."
},
"defaultConfiguration" : {
"enabled" : true,
"level" : "warning"
},
"help" : {
- "text" : "# Unsafe expansion of self-closing HTML tag\nSanitizing untrusted input for HTML meta-characters is a common technique for preventing cross-site scripting attacks. But even a sanitized input can be dangerous to use if it is modified further before a browser treats it as HTML. A seemingly innocent transformation that expands a self-closing HTML tag from `
` to `
` may in fact cause cross-site scripting vulnerabilities.\n\n\n## Recommendation\nUse a well-tested sanitization library if at all possible, and avoid modifying sanitized values further before treating them as HTML.\n\nAn even safer alternative is to design the application so that sanitization is not needed, for instance by using HTML templates that are explicit about the values they treat as HTML.\n\n\n## Example\nThe following function transforms a self-closing HTML tag to a pair of open/close tags. It does so for all non-`img` and non-`area` tags, by using a regular expression with two capture groups. The first capture group corresponds to the name of the tag, and the second capture group to the content of the tag.\n\n\n```javascript\nfunction expandSelfClosingTags(html) {\n\tvar rxhtmlTag = /<(?!img|area)(([a-z][^\\w\\/>]*)[^>]*)\\/>/gi;\n\treturn html.replace(rxhtmlTag, \"<$1>$2>\"); // BAD\n}\n\n```\nWhile it is generally known regular expressions are ill-suited for parsing HTML, variants of this particular transformation pattern have long been considered safe.\n\nHowever, the function is not safe. As an example, consider the following string:\n\n\n```html\n
\n

\"/>\n\n```\nWhen the above function transforms the string, it becomes a string that results in an alert when a browser treats it as HTML.\n\n\n```html\n
\n

\"/>\n\n```\n\n## References\n* jQuery: [Security fixes in jQuery 3.5.0](https://blog.jquery.com/2020/04/10/jquery-3-5-0-released/)\n* OWASP: [DOM based XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html).\n* OWASP: [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html).\n* OWASP [Types of Cross-Site](https://owasp.org/www-community/Types_of_Cross-Site_Scripting).\n* Wikipedia: [Cross-site scripting](http://en.wikipedia.org/wiki/Cross-site_scripting).\n* Common Weakness Enumeration: [CWE-79](https://cwe.mitre.org/data/definitions/79.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n",
- "markdown" : "# Unsafe expansion of self-closing HTML tag\nSanitizing untrusted input for HTML meta-characters is a common technique for preventing cross-site scripting attacks. But even a sanitized input can be dangerous to use if it is modified further before a browser treats it as HTML. A seemingly innocent transformation that expands a self-closing HTML tag from `
` to `
` may in fact cause cross-site scripting vulnerabilities.\n\n\n## Recommendation\nUse a well-tested sanitization library if at all possible, and avoid modifying sanitized values further before treating them as HTML.\n\nAn even safer alternative is to design the application so that sanitization is not needed, for instance by using HTML templates that are explicit about the values they treat as HTML.\n\n\n## Example\nThe following function transforms a self-closing HTML tag to a pair of open/close tags. It does so for all non-`img` and non-`area` tags, by using a regular expression with two capture groups. The first capture group corresponds to the name of the tag, and the second capture group to the content of the tag.\n\n\n```javascript\nfunction expandSelfClosingTags(html) {\n\tvar rxhtmlTag = /<(?!img|area)(([a-z][^\\w\\/>]*)[^>]*)\\/>/gi;\n\treturn html.replace(rxhtmlTag, \"<$1>$2>\"); // BAD\n}\n\n```\nWhile it is generally known regular expressions are ill-suited for parsing HTML, variants of this particular transformation pattern have long been considered safe.\n\nHowever, the function is not safe. As an example, consider the following string:\n\n\n```html\n
\n

\"/>\n\n```\nWhen the above function transforms the string, it becomes a string that results in an alert when a browser treats it as HTML.\n\n\n```html\n
\n

\"/>\n\n```\n\n## References\n* jQuery: [Security fixes in jQuery 3.5.0](https://blog.jquery.com/2020/04/10/jquery-3-5-0-released/)\n* OWASP: [DOM based XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html).\n* OWASP: [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html).\n* OWASP [Types of Cross-Site](https://owasp.org/www-community/Types_of_Cross-Site_Scripting).\n* Wikipedia: [Cross-site scripting](http://en.wikipedia.org/wiki/Cross-site_scripting).\n* Common Weakness Enumeration: [CWE-79](https://cwe.mitre.org/data/definitions/79.html).\n* Common Weakness Enumeration: [CWE-116](https://cwe.mitre.org/data/definitions/116.html).\n"
+ "text" : "# Expression injection in Actions\nUsing user-controlled input in GitHub Actions may lead to code injection in contexts like *run:* or *script:*.\n\nCode injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token might have write access to the repository, allowing an attacker to use the token to make changes to the repository.\n\n\n## Recommendation\nThe best practice to avoid code injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable and then use the environment variable using the native syntax of the shell/script interpreter (that is, not *${{ env.VAR }}*).\n\nIt is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN.\n\n\n## Example\nThe following example lets a user inject an arbitrary shell command:\n\n\n```yaml\non: issue_comment\n\njobs:\n echo-body:\n runs-on: ubuntu-latest\n steps:\n - run: |\n echo '${{ github.event.comment.body }}'\n```\nThe following example uses an environment variable, but **still allows the injection** because of the use of expression syntax:\n\n\n```yaml\non: issue_comment\n\njobs:\n echo-body:\n runs-on: ubuntu-latest\n steps:\n - env:\n BODY: ${{ github.event.issue.body }}\n run: |\n echo '${{ env.BODY }}'\n```\nThe following example uses shell syntax to read the environment variable and will prevent the attack:\n\n\n```yaml\non: issue_comment\n\njobs:\n echo-body:\n runs-on: ubuntu-latest\n steps:\n - env:\n BODY: ${{ github.event.issue.body }}\n run: |\n echo \"$BODY\"\n\n```\n\n## References\n* GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure: Untrusted input](https://securitylab.github.com/research/github-actions-untrusted-input).\n* GitHub Docs: [Security hardening for GitHub Actions](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions).\n* GitHub Docs: [Permissions for the GITHUB_TOKEN](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token).\n* Common Weakness Enumeration: [CWE-94](https://cwe.mitre.org/data/definitions/94.html).\n",
+ "markdown" : "# Expression injection in Actions\nUsing user-controlled input in GitHub Actions may lead to code injection in contexts like *run:* or *script:*.\n\nCode injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token might have write access to the repository, allowing an attacker to use the token to make changes to the repository.\n\n\n## Recommendation\nThe best practice to avoid code injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable and then use the environment variable using the native syntax of the shell/script interpreter (that is, not *${{ env.VAR }}*).\n\nIt is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN.\n\n\n## Example\nThe following example lets a user inject an arbitrary shell command:\n\n\n```yaml\non: issue_comment\n\njobs:\n echo-body:\n runs-on: ubuntu-latest\n steps:\n - run: |\n echo '${{ github.event.comment.body }}'\n```\nThe following example uses an environment variable, but **still allows the injection** because of the use of expression syntax:\n\n\n```yaml\non: issue_comment\n\njobs:\n echo-body:\n runs-on: ubuntu-latest\n steps:\n - env:\n BODY: ${{ github.event.issue.body }}\n run: |\n echo '${{ env.BODY }}'\n```\nThe following example uses shell syntax to read the environment variable and will prevent the attack:\n\n\n```yaml\non: issue_comment\n\njobs:\n echo-body:\n runs-on: ubuntu-latest\n steps:\n - env:\n BODY: ${{ github.event.issue.body }}\n run: |\n echo \"$BODY\"\n\n```\n\n## References\n* GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure: Untrusted input](https://securitylab.github.com/research/github-actions-untrusted-input).\n* GitHub Docs: [Security hardening for GitHub Actions](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions).\n* GitHub Docs: [Permissions for the GITHUB_TOKEN](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token).\n* Common Weakness Enumeration: [CWE-94](https://cwe.mitre.org/data/definitions/94.html).\n"
},
"properties" : {
- "tags" : [ "correctness", "security", "external/cwe/cwe-079", "external/cwe/cwe-116" ],
- "description" : "Using regular expressions to expand self-closing HTML\n tags may lead to cross-site scripting vulnerabilities.",
- "id" : "js/unsafe-html-expansion",
+ "tags" : [ "actions", "security", "external/cwe/cwe-094" ],
+ "description" : "Using user-controlled GitHub Actions contexts like `run:` or `script:` may allow a malicious\n user to inject code into the GitHub action.",
+ "id" : "js/actions/command-injection",
"kind" : "problem",
- "name" : "Unsafe expansion of self-closing HTML tag",
- "precision" : "very-high",
+ "name" : "Expression injection in Actions",
+ "precision" : "high",
"problem.severity" : "warning",
- "security-severity" : "6.1"
+ "security-severity" : "9.3"
}
}, {
- "id" : "js/incomplete-multi-character-sanitization",
- "name" : "js/incomplete-multi-character-sanitization",
+ "id" : "js/unsafe-dynamic-method-access",
+ "name" : "js/unsafe-dynamic-method-access",
"shortDescription" : {
- "text" : "Incomplete multi-character sanitization"
+ "text" : "Unsafe dynamic method access"
},
"fullDescription" : {
- "text" : "A sanitizer that removes a sequence of characters may reintroduce the dangerous sequence."
+ "text" : "Invoking user-controlled methods on certain objects can lead to remote code execution."
},
"defaultConfiguration" : {
"enabled" : true,
- "level" : "warning"
+ "level" : "error"
},
"help" : {
- "text" : "# Incomplete multi-character sanitization\nSanitizing untrusted input is a common technique for preventing injection attacks and other security vulnerabilities. Regular expressions are often used to perform this sanitization. However, when the regular expression matches multiple consecutive characters, replacing it just once can result in the unsafe text reappearing in the sanitized input.\n\nAttackers can exploit this issue by crafting inputs that, when sanitized with an ineffective regular expression, still contain malicious code or content. This can lead to code execution, data exposure, or other vulnerabilities.\n\n\n## Recommendation\nTo prevent this issue, it is highly recommended to use a well-tested sanitization library whenever possible. These libraries are more likely to handle corner cases and ensure effective sanitization.\n\nIf a library is not an option, you can consider alternative strategies to fix the issue. For example, applying the regular expression replacement repeatedly until no more replacements can be performed, or rewriting the regular expression to match single characters instead of the entire unsafe text.\n\n\n## Example\nConsider the following JavaScript code that aims to remove all HTML comment start and end tags:\n\n```javascript\n\nstr.replace(/