Skip to content

Commit 6e754c7

Browse files
committed
add test for js/html-constructed-from-input
1 parent e86a3b5 commit 6e754c7

File tree

9 files changed

+164
-0
lines changed

9 files changed

+164
-0
lines changed

javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/ConsistencyUnsafeHtmlConstruction.expected

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import javascript
2+
import testUtilities.ConsistencyChecking
3+
import semmle.javascript.security.dataflow.UnsafeHtmlConstruction as UnsafeHtmlConstruction
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
nodes
2+
| main.js:1:55:1:55 | s |
3+
| main.js:1:55:1:55 | s |
4+
| main.js:2:29:2:29 | s |
5+
| main.js:2:29:2:29 | s |
6+
| main.js:6:49:6:49 | s |
7+
| main.js:6:49:6:49 | s |
8+
| main.js:7:49:7:49 | s |
9+
| main.js:7:49:7:49 | s |
10+
| main.js:11:60:11:60 | s |
11+
| main.js:11:60:11:60 | s |
12+
| main.js:12:49:12:49 | s |
13+
| main.js:12:49:12:49 | s |
14+
| main.js:21:47:21:47 | s |
15+
| main.js:21:47:21:47 | s |
16+
| main.js:22:34:22:34 | s |
17+
| main.js:22:34:22:34 | s |
18+
| typed.ts:1:39:1:39 | s |
19+
| typed.ts:1:39:1:39 | s |
20+
| typed.ts:2:29:2:29 | s |
21+
| typed.ts:2:29:2:29 | s |
22+
| typed.ts:6:43:6:43 | s |
23+
| typed.ts:6:43:6:43 | s |
24+
| typed.ts:8:40:8:40 | s |
25+
| typed.ts:8:40:8:40 | s |
26+
| typed.ts:11:20:11:20 | s |
27+
| typed.ts:11:20:11:20 | s |
28+
| typed.ts:12:12:12:12 | s |
29+
| typed.ts:16:11:16:21 | s |
30+
| typed.ts:16:15:16:21 | id("x") |
31+
| typed.ts:17:29:17:29 | s |
32+
| typed.ts:17:29:17:29 | s |
33+
edges
34+
| main.js:1:55:1:55 | s | main.js:2:29:2:29 | s |
35+
| main.js:1:55:1:55 | s | main.js:2:29:2:29 | s |
36+
| main.js:1:55:1:55 | s | main.js:2:29:2:29 | s |
37+
| main.js:1:55:1:55 | s | main.js:2:29:2:29 | s |
38+
| main.js:6:49:6:49 | s | main.js:7:49:7:49 | s |
39+
| main.js:6:49:6:49 | s | main.js:7:49:7:49 | s |
40+
| main.js:6:49:6:49 | s | main.js:7:49:7:49 | s |
41+
| main.js:6:49:6:49 | s | main.js:7:49:7:49 | s |
42+
| main.js:11:60:11:60 | s | main.js:12:49:12:49 | s |
43+
| main.js:11:60:11:60 | s | main.js:12:49:12:49 | s |
44+
| main.js:11:60:11:60 | s | main.js:12:49:12:49 | s |
45+
| main.js:11:60:11:60 | s | main.js:12:49:12:49 | s |
46+
| main.js:21:47:21:47 | s | main.js:22:34:22:34 | s |
47+
| main.js:21:47:21:47 | s | main.js:22:34:22:34 | s |
48+
| main.js:21:47:21:47 | s | main.js:22:34:22:34 | s |
49+
| main.js:21:47:21:47 | s | main.js:22:34:22:34 | s |
50+
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
51+
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
52+
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
53+
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
54+
| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s |
55+
| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s |
56+
| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s |
57+
| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s |
58+
| typed.ts:11:20:11:20 | s | typed.ts:12:12:12:12 | s |
59+
| typed.ts:11:20:11:20 | s | typed.ts:12:12:12:12 | s |
60+
| typed.ts:12:12:12:12 | s | typed.ts:16:15:16:21 | id("x") |
61+
| typed.ts:16:11:16:21 | s | typed.ts:17:29:17:29 | s |
62+
| typed.ts:16:11:16:21 | s | typed.ts:17:29:17:29 | s |
63+
| typed.ts:16:15:16:21 | id("x") | typed.ts:16:11:16:21 | s |
64+
#select
65+
| main.js:2:29:2:29 | s | main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | $@ based on $@ might later cause $@. | main.js:2:29:2:29 | s | HTML construction | main.js:1:55:1:55 | s | library input | main.js:3:49:3:52 | html | cross-site scripting |
66+
| main.js:7:49:7:49 | s | main.js:6:49:6:49 | s | main.js:7:49:7:49 | s | $@ based on $@ might later cause $@. | main.js:7:49:7:49 | s | XML parsing | main.js:6:49:6:49 | s | library input | main.js:8:48:8:66 | doc.documentElement | cross-site scripting |
67+
| main.js:12:49:12:49 | s | main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | $@ based on $@ might later cause $@. | main.js:12:49:12:49 | s | XML parsing | main.js:11:60:11:60 | s | library input | main.js:16:21:16:35 | xml.cloneNode() | cross-site scripting |
68+
| main.js:12:49:12:49 | s | main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | $@ based on $@ might later cause $@. | main.js:12:49:12:49 | s | XML parsing | main.js:11:60:11:60 | s | library input | main.js:17:48:17:50 | tmp | cross-site scripting |
69+
| main.js:22:34:22:34 | s | main.js:21:47:21:47 | s | main.js:22:34:22:34 | s | $@ based on $@ might later cause $@. | main.js:22:34:22:34 | s | Markdown rendering | main.js:21:47:21:47 | s | library input | main.js:23:53:23:56 | html | cross-site scripting |
70+
| typed.ts:2:29:2:29 | s | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | $@ based on $@ might later cause $@. | typed.ts:2:29:2:29 | s | HTML construction | typed.ts:1:39:1:39 | s | library input | typed.ts:3:31:3:34 | html | cross-site scripting |
71+
| typed.ts:8:40:8:40 | s | typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | $@ based on $@ might later cause $@. | typed.ts:8:40:8:40 | s | HTML construction | typed.ts:6:43:6:43 | s | library input | typed.ts:8:29:8:52 | "<span> ... /span>" | cross-site scripting |
72+
| typed.ts:17:29:17:29 | s | typed.ts:11:20:11:20 | s | typed.ts:17:29:17:29 | s | $@ based on $@ might later cause $@. | typed.ts:17:29:17:29 | s | HTML construction | typed.ts:11:20:11:20 | s | library input | typed.ts:18:31:18:34 | html | cross-site scripting |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security/CWE-079/UnsafeHtmlConstruction.ql
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(function (factory) {
2+
if (typeof define === 'function' && define.amd) {
3+
define(['jquery', 'jquery-ui'], factory);
4+
} else {
5+
factory(jQuery);
6+
}
7+
}(function ($) {
8+
$("<span>" + $.trim("foo") + "</span>"); // OK
9+
}));
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
module.exports.xssThroughHTMLConstruction = function (s) {
2+
const html = "<span>" + s + "</span>";// NOT OK
3+
document.querySelector("#html").innerHTML = html;
4+
}
5+
6+
module.exports.xssThroughXMLParsing = function (s) {
7+
const doc = new DOMParser().parseFromString(s, "text/xml"); // NOT OK
8+
document.querySelector("#xml").appendChild(doc.documentElement);
9+
}
10+
11+
module.exports.xssThroughMoreComplexXMLParsing = function (s) {
12+
const doc = new DOMParser().parseFromString(s, "text/xml"); // NOT OK
13+
const xml = doc.documentElement;
14+
15+
const tmp = document.createElement('span');
16+
tmp.appendChild(xml.cloneNode());
17+
document.querySelector("#xml").appendChild(tmp);
18+
}
19+
20+
const markdown = require('markdown-it')({html: true});
21+
module.exports.xssThroughMarkdown = function (s) {
22+
const html = markdown.render(s); // NOT OK
23+
document.querySelector("#markdown").innerHTML = html;
24+
}
25+
26+
const striptags = require('striptags');
27+
module.exports.sanitizedHTML = function (s) {
28+
const html = striptags("<span>" + s + "</span>"); // OK
29+
document.querySelector("#sanitized").innerHTML = html;
30+
}
31+
32+
module.exports.ts = require("./typed");
33+
34+
module.exports.jquery = require("./jquery-plugin");
35+
36+
module.exports.plainDOMXMLParsing = function (s) {
37+
const doc = new DOMParser().parseFromString(s, "text/xml"); // OK - is never added to the DOM.
38+
}
39+
40+
class Foo {
41+
constructor(s) {
42+
this.step = s;
43+
}
44+
45+
doXss() {
46+
// not called here, but still bad.
47+
document.querySelector("#class").innerHTML = "<span>" + this.step + "</span>"; // NOT OK - but not flagged [INCONSISTENCY]
48+
}
49+
50+
}
51+
52+
module.exports.createsClass = function (s) {
53+
return new Foo(s);
54+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "my-unsafe-library",
3+
"main": "./main.js"
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export function basicHtmlConstruction(s: string) {
2+
const html = "<span>" + s + "</span>"; // NOT OK
3+
document.body.innerHTML = html;
4+
}
5+
6+
export function insertIntoCreatedDocument(s: string) {
7+
const newDoc = document.implementation.createHTMLDocument("");
8+
newDoc.body.innerHTML = "<span>" + s + "</span>"; // OK - inserted into document disconnected from the main DOM. [INCONSISTENCY]
9+
}
10+
11+
export function id(s: string) {
12+
return s;
13+
}
14+
15+
export function notVulnerable() {
16+
const s = id("x");
17+
const html = "<span>" + s + "</span>"; // OK - but flagged due to step with unmatched call [INCONSISTENCY]
18+
document.body.innerHTML = html;
19+
}
20+

0 commit comments

Comments
 (0)