Merge pull request #10347 from erik-krogh/mermaid

JS: add a markdown step through the `mermaid` library
This commit is contained in:
Erik Krogh Kristensen
2022-09-08 12:41:58 +02:00
committed by GitHub
4 changed files with 101 additions and 1 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* A model for the `mermaid` library has been added. XSS queries can now detect flow through the `render` method of the `mermaid` library.

View File

@@ -78,6 +78,32 @@ module Markdown {
}
}
/** A taint step for the `mermaid` library. */
private class MermaidStep extends MarkdownStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(API::CallNode call |
call =
[API::moduleImport("mermaid"), API::moduleImport("mermaid").getMember("mermaidAPI")]
.getMember("render")
.getACall()
|
succ = [call, call.getParameter(2).getParameter(0).asSource()] and
pred = call.getArgument(1)
)
or
exists(DataFlow::CallNode call |
call =
[
DataFlow::globalVarRef("mermaid"),
DataFlow::globalVarRef("mermaid").getAPropertyRead("mermaidAPI")
].getAMemberCall("render")
|
succ = [call.(DataFlow::Node), call.getABoundCallbackParameter(2, 0)] and
pred = call.getArgument(1)
)
}
}
/**
* Classes and predicates for modeling taint steps in `unified` and `remark`.
*/

View File

@@ -56,6 +56,22 @@ nodes
| main.js:93:43:93:43 | x |
| main.js:93:43:93:43 | x |
| main.js:94:31:94:31 | x |
| main.js:98:43:98:43 | x |
| main.js:98:43:98:43 | x |
| main.js:99:28:99:28 | x |
| main.js:99:28:99:28 | x |
| main.js:103:43:103:43 | x |
| main.js:103:43:103:43 | x |
| main.js:105:26:105:26 | x |
| main.js:105:26:105:26 | x |
| main.js:109:41:109:41 | x |
| main.js:109:41:109:41 | x |
| main.js:111:37:111:37 | x |
| main.js:111:37:111:37 | x |
| main.js:116:47:116:47 | s |
| main.js:116:47:116:47 | s |
| main.js:117:34:117:34 | s |
| main.js:117:34:117:34 | s |
| typed.ts:1:39:1:39 | s |
| typed.ts:1:39:1:39 | s |
| typed.ts:2:29:2:29 | s |
@@ -126,6 +142,30 @@ edges
| main.js:93:43:93:43 | x | main.js:94:31:94:31 | x |
| main.js:93:43:93:43 | x | main.js:94:31:94:31 | x |
| main.js:94:31:94:31 | x | main.js:89:21:89:21 | x |
| main.js:98:43:98:43 | x | main.js:99:28:99:28 | x |
| main.js:98:43:98:43 | x | main.js:99:28:99:28 | x |
| main.js:98:43:98:43 | x | main.js:99:28:99:28 | x |
| main.js:98:43:98:43 | x | main.js:99:28:99:28 | x |
| main.js:98:43:98:43 | x | main.js:103:43:103:43 | x |
| main.js:98:43:98:43 | x | main.js:103:43:103:43 | x |
| main.js:98:43:98:43 | x | main.js:103:43:103:43 | x |
| main.js:98:43:98:43 | x | main.js:103:43:103:43 | x |
| main.js:98:43:98:43 | x | main.js:105:26:105:26 | x |
| main.js:98:43:98:43 | x | main.js:105:26:105:26 | x |
| main.js:98:43:98:43 | x | main.js:105:26:105:26 | x |
| main.js:98:43:98:43 | x | main.js:105:26:105:26 | x |
| main.js:98:43:98:43 | x | main.js:109:41:109:41 | x |
| main.js:98:43:98:43 | x | main.js:109:41:109:41 | x |
| main.js:98:43:98:43 | x | main.js:109:41:109:41 | x |
| main.js:98:43:98:43 | x | main.js:109:41:109:41 | x |
| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x |
| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x |
| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x |
| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x |
| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s |
| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s |
| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s |
| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s |
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
@@ -153,5 +193,11 @@ edges
| main.js:67:63:67:69 | attrVal | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | $@ based on $@ might later cause $@. | main.js:67:63:67:69 | attrVal | HTML construction | main.js:66:35:66:41 | attrVal | library input | main.js:67:47:67:78 | "<img a ... "\\"/>" | cross-site scripting |
| main.js:81:35:81:37 | val | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | $@ based on $@ might later cause $@. | main.js:81:35:81:37 | val | HTML construction | main.js:79:34:79:36 | val | library input | main.js:81:24:81:49 | "<span> ... /span>" | cross-site scripting |
| main.js:90:23:90:23 | x | main.js:93:43:93:43 | x | main.js:90:23:90:23 | x | $@ based on $@ might later cause $@. | main.js:90:23:90:23 | x | HTML construction | main.js:93:43:93:43 | x | library input | main.js:94:20:94:32 | createHTML(x) | cross-site scripting |
| main.js:99:28:99:28 | x | main.js:98:43:98:43 | x | main.js:99:28:99:28 | x | $@ based on $@ might later cause $@. | main.js:99:28:99:28 | x | Markdown rendering | main.js:98:43:98:43 | x | library input | main.js:100:24:100:26 | svg | cross-site scripting |
| main.js:103:43:103:43 | x | main.js:98:43:98:43 | x | main.js:103:43:103:43 | x | $@ based on $@ might later cause $@. | main.js:103:43:103:43 | x | Markdown rendering | main.js:98:43:98:43 | x | library input | main.js:103:20:103:44 | myMerma ... id", x) | cross-site scripting |
| main.js:105:26:105:26 | x | main.js:98:43:98:43 | x | main.js:105:26:105:26 | x | $@ based on $@ might later cause $@. | main.js:105:26:105:26 | x | Markdown rendering | main.js:98:43:98:43 | x | library input | main.js:106:24:106:26 | svg | cross-site scripting |
| main.js:109:41:109:41 | x | main.js:98:43:98:43 | x | main.js:109:41:109:41 | x | $@ based on $@ might later cause $@. | main.js:109:41:109:41 | x | Markdown rendering | main.js:98:43:98:43 | x | library input | main.js:109:20:109:42 | mermaid ... id", x) | cross-site scripting |
| main.js:111:37:111:37 | x | main.js:98:43:98:43 | x | main.js:111:37:111:37 | x | $@ based on $@ might later cause $@. | main.js:111:37:111:37 | x | Markdown rendering | main.js:98:43:98:43 | x | library input | main.js:112:24:112:26 | svg | cross-site scripting |
| main.js:117:34:117:34 | s | main.js:116:47:116:47 | s | main.js:117:34:117:34 | s | $@ based on $@ might later cause $@. | main.js:117:34:117:34 | s | Markdown rendering | main.js:116:47:116:47 | s | library input | main.js:118:53:118:56 | html | cross-site scripting |
| 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 |
| 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 |

View File

@@ -92,4 +92,28 @@ function createHTML(x) {
module.exports.usesCreateHTML = function (x) {
$("#foo").html(createHTML(x));
}
}
const myMermaid = require('mermaid');
module.exports.usesCreateHTML = function (x) {
myMermaid.render("id", x, function (svg) { // NOT OK
$("#foo").html(svg);
});
$("#foo").html(myMermaid.render("id", x)); // NOT OK
mermaid.render("id", x, function (svg) {// NOT OK
$("#foo").html(svg);
});
$("#foo").html(mermaid.render("id", x)); // NOT OK
mermaid.mermaidAPI.render("id", x, function (svg) {// NOT OK
$("#foo").html(svg);
});
}
module.exports.xssThroughMarkdown = function (s) {
const html = markdown.render(s); // NOT OK
document.querySelector("#markdown").innerHTML = html;
}