Skip to content

Commit 8716cbd

Browse files
authored
Merge pull request github#5140 from erik-krogh/mark
Approved by asgerf
2 parents ebcecca + 4df85b4 commit 8716cbd

File tree

6 files changed

+329
-0
lines changed

6 files changed

+329
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
lgtm,codescanning
2+
* The security queries now track taint through markdown parsers.
3+
Affected packages are
4+
[marked](https://npmjs.com/package/marked),
5+
[markdown-table](https://npmjs.com/package/markdown-table),
6+
[showdown](https://npmjs.com/package/showdown),
7+
[snarkdown](https://npmjs.com/package/snarkdown),
8+
[unified](https://npmjs.com/package/unified), and
9+
[remark](https://npmjs.com/package/remark)

javascript/ql/src/javascript.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import semmle.javascript.frameworks.LazyCache
9494
import semmle.javascript.frameworks.LodashUnderscore
9595
import semmle.javascript.frameworks.Logging
9696
import semmle.javascript.frameworks.HttpFrameworks
97+
import semmle.javascript.frameworks.Markdown
9798
import semmle.javascript.frameworks.NoSQL
9899
import semmle.javascript.frameworks.PkgCloud
99100
import semmle.javascript.frameworks.PropertyProjection
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/**
2+
* Provides classes for modelling common markdown parsers and generators.
3+
*/
4+
5+
import javascript
6+
7+
/**
8+
* A taint step for the `marked` library, that converts markdown to HTML.
9+
*/
10+
private class MarkedStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
11+
MarkedStep() {
12+
this = DataFlow::globalVarRef("marked").getACall()
13+
or
14+
this = DataFlow::moduleImport("marked").getACall()
15+
}
16+
17+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
18+
succ = this and
19+
pred = this.getArgument(0)
20+
}
21+
}
22+
23+
/**
24+
* A taint step for the `markdown-table` library.
25+
*/
26+
private class MarkdownTableStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
27+
MarkdownTableStep() { this = DataFlow::moduleImport("markdown-table").getACall() }
28+
29+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
30+
succ = this and
31+
pred = this.getArgument(0)
32+
}
33+
}
34+
35+
/**
36+
* A taint step for the `showdown` library.
37+
*/
38+
private class ShowDownStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
39+
ShowDownStep() {
40+
this =
41+
[DataFlow::globalVarRef("showdown"), DataFlow::moduleImport("showdown")]
42+
.getAConstructorInvocation("Converter")
43+
.getAMemberCall(["makeHtml", "makeMd"])
44+
}
45+
46+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
47+
succ = this and
48+
pred = this.getArgument(0)
49+
}
50+
}
51+
52+
/**
53+
* Classes and predicates for modelling taint steps in `unified` and `remark`.
54+
*/
55+
private module Unified {
56+
/**
57+
* The creation of a parser from `unified`.
58+
* The `remark` module is a shorthand that initializes `unified` with a markdown parser.
59+
*/
60+
DataFlow::CallNode unified() { result = DataFlow::moduleImport(["unified", "remark"]).getACall() }
61+
62+
/**
63+
* A chain of method calls that process an input with `unified`.
64+
*/
65+
class UnifiedChain extends DataFlow::CallNode {
66+
DataFlow::CallNode root;
67+
68+
UnifiedChain() {
69+
root = unified() and
70+
this = root.getAChainedMethodCall(["process", "processSync"])
71+
}
72+
73+
/**
74+
* Gets a plugin that is used in this chain.
75+
*/
76+
DataFlow::Node getAUsedPlugin() { result = root.getAChainedMethodCall("use").getArgument(0) }
77+
78+
/**
79+
* Gets the input that is processed.
80+
*/
81+
DataFlow::Node getInput() { result = getArgument(0) }
82+
83+
/**
84+
* Gets the processed output.
85+
*/
86+
DataFlow::Node getOutput() {
87+
this.getCalleeName() = "process" and result = getABoundCallbackParameter(1, 1)
88+
or
89+
this.getCalleeName() = "processSync" and result = this
90+
}
91+
}
92+
93+
/**
94+
* A taint step for the `unified` library.
95+
*/
96+
class UnifiedStep extends TaintTracking::AdditionalTaintStep, UnifiedChain {
97+
UnifiedStep() {
98+
// sanitizer. Mostly looking for `rehype-sanitize`, but also other plugins with `sanitize` in their name.
99+
not this.getAUsedPlugin().getALocalSource() =
100+
DataFlow::moduleImport(any(string s | s.matches("%sanitize%")))
101+
}
102+
103+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
104+
pred = getInput() and
105+
succ = getOutput()
106+
}
107+
}
108+
}
109+
110+
/**
111+
* A taint step for the `snarkdown` library.
112+
*/
113+
private class SnarkdownStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
114+
SnarkdownStep() { this = DataFlow::moduleImport("snarkdown").getACall() }
115+
116+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
117+
this = succ and
118+
pred = this.getArgument(0)
119+
}
120+
}

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

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,65 @@ nodes
77
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
88
| ReflectedXss.js:17:31:17:39 | params.id |
99
| ReflectedXss.js:17:31:17:39 | params.id |
10+
| ReflectedXss.js:22:12:22:19 | req.body |
11+
| ReflectedXss.js:22:12:22:19 | req.body |
12+
| ReflectedXss.js:22:12:22:19 | req.body |
13+
| ReflectedXss.js:23:12:23:27 | marked(req.body) |
14+
| ReflectedXss.js:23:12:23:27 | marked(req.body) |
15+
| ReflectedXss.js:23:19:23:26 | req.body |
16+
| ReflectedXss.js:23:19:23:26 | req.body |
17+
| ReflectedXss.js:29:12:29:19 | req.body |
18+
| ReflectedXss.js:29:12:29:19 | req.body |
19+
| ReflectedXss.js:29:12:29:19 | req.body |
20+
| ReflectedXss.js:30:7:33:4 | mytable |
21+
| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) |
22+
| ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] |
23+
| ReflectedXss.js:32:5:32:22 | ['body', req.body] |
24+
| ReflectedXss.js:32:14:32:21 | req.body |
25+
| ReflectedXss.js:32:14:32:21 | req.body |
26+
| ReflectedXss.js:34:12:34:18 | mytable |
27+
| ReflectedXss.js:34:12:34:18 | mytable |
28+
| ReflectedXss.js:41:12:41:19 | req.body |
29+
| ReflectedXss.js:41:12:41:19 | req.body |
30+
| ReflectedXss.js:41:12:41:19 | req.body |
31+
| ReflectedXss.js:42:12:42:39 | convert ... q.body) |
32+
| ReflectedXss.js:42:12:42:39 | convert ... q.body) |
33+
| ReflectedXss.js:42:31:42:38 | req.body |
34+
| ReflectedXss.js:42:31:42:38 | req.body |
35+
| ReflectedXss.js:56:12:56:19 | req.body |
36+
| ReflectedXss.js:56:12:56:19 | req.body |
37+
| ReflectedXss.js:56:12:56:19 | req.body |
38+
| ReflectedXss.js:64:14:64:21 | req.body |
39+
| ReflectedXss.js:64:14:64:21 | req.body |
40+
| ReflectedXss.js:64:39:64:42 | file |
41+
| ReflectedXss.js:65:16:65:19 | file |
42+
| ReflectedXss.js:65:16:65:19 | file |
43+
| ReflectedXss.js:68:12:68:41 | remark( ... q.body) |
44+
| ReflectedXss.js:68:12:68:52 | remark( ... tring() |
45+
| ReflectedXss.js:68:12:68:52 | remark( ... tring() |
46+
| ReflectedXss.js:68:33:68:40 | req.body |
47+
| ReflectedXss.js:68:33:68:40 | req.body |
48+
| ReflectedXss.js:72:12:72:56 | unified ... q.body) |
49+
| ReflectedXss.js:72:12:72:65 | unified ... oString |
50+
| ReflectedXss.js:72:12:72:65 | unified ... oString |
51+
| ReflectedXss.js:72:48:72:55 | req.body |
52+
| ReflectedXss.js:72:48:72:55 | req.body |
53+
| ReflectedXss.js:74:20:74:27 | req.body |
54+
| ReflectedXss.js:74:20:74:27 | req.body |
55+
| ReflectedXss.js:74:34:74:34 | f |
56+
| ReflectedXss.js:75:14:75:14 | f |
57+
| ReflectedXss.js:75:14:75:14 | f |
58+
| ReflectedXss.js:83:12:83:19 | req.body |
59+
| ReflectedXss.js:83:12:83:19 | req.body |
60+
| ReflectedXss.js:83:12:83:19 | req.body |
61+
| ReflectedXss.js:84:12:84:30 | snarkdown(req.body) |
62+
| ReflectedXss.js:84:12:84:30 | snarkdown(req.body) |
63+
| ReflectedXss.js:84:22:84:29 | req.body |
64+
| ReflectedXss.js:84:22:84:29 | req.body |
65+
| ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) |
66+
| ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) |
67+
| ReflectedXss.js:85:23:85:30 | req.body |
68+
| ReflectedXss.js:85:23:85:30 | req.body |
1069
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
1170
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
1271
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id |
@@ -100,6 +159,50 @@ edges
100159
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
101160
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
102161
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
162+
| ReflectedXss.js:22:12:22:19 | req.body | ReflectedXss.js:22:12:22:19 | req.body |
163+
| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) |
164+
| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) |
165+
| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) |
166+
| ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) |
167+
| ReflectedXss.js:29:12:29:19 | req.body | ReflectedXss.js:29:12:29:19 | req.body |
168+
| ReflectedXss.js:30:7:33:4 | mytable | ReflectedXss.js:34:12:34:18 | mytable |
169+
| ReflectedXss.js:30:7:33:4 | mytable | ReflectedXss.js:34:12:34:18 | mytable |
170+
| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | ReflectedXss.js:30:7:33:4 | mytable |
171+
| ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] | ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) |
172+
| ReflectedXss.js:32:5:32:22 | ['body', req.body] | ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] |
173+
| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:32:5:32:22 | ['body', req.body] |
174+
| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:32:5:32:22 | ['body', req.body] |
175+
| ReflectedXss.js:41:12:41:19 | req.body | ReflectedXss.js:41:12:41:19 | req.body |
176+
| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) |
177+
| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) |
178+
| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) |
179+
| ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) |
180+
| ReflectedXss.js:56:12:56:19 | req.body | ReflectedXss.js:56:12:56:19 | req.body |
181+
| ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:64:39:64:42 | file |
182+
| ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:64:39:64:42 | file |
183+
| ReflectedXss.js:64:39:64:42 | file | ReflectedXss.js:65:16:65:19 | file |
184+
| ReflectedXss.js:64:39:64:42 | file | ReflectedXss.js:65:16:65:19 | file |
185+
| ReflectedXss.js:68:12:68:41 | remark( ... q.body) | ReflectedXss.js:68:12:68:52 | remark( ... tring() |
186+
| ReflectedXss.js:68:12:68:41 | remark( ... q.body) | ReflectedXss.js:68:12:68:52 | remark( ... tring() |
187+
| ReflectedXss.js:68:33:68:40 | req.body | ReflectedXss.js:68:12:68:41 | remark( ... q.body) |
188+
| ReflectedXss.js:68:33:68:40 | req.body | ReflectedXss.js:68:12:68:41 | remark( ... q.body) |
189+
| ReflectedXss.js:72:12:72:56 | unified ... q.body) | ReflectedXss.js:72:12:72:65 | unified ... oString |
190+
| ReflectedXss.js:72:12:72:56 | unified ... q.body) | ReflectedXss.js:72:12:72:65 | unified ... oString |
191+
| ReflectedXss.js:72:48:72:55 | req.body | ReflectedXss.js:72:12:72:56 | unified ... q.body) |
192+
| ReflectedXss.js:72:48:72:55 | req.body | ReflectedXss.js:72:12:72:56 | unified ... q.body) |
193+
| ReflectedXss.js:74:20:74:27 | req.body | ReflectedXss.js:74:34:74:34 | f |
194+
| ReflectedXss.js:74:20:74:27 | req.body | ReflectedXss.js:74:34:74:34 | f |
195+
| ReflectedXss.js:74:34:74:34 | f | ReflectedXss.js:75:14:75:14 | f |
196+
| ReflectedXss.js:74:34:74:34 | f | ReflectedXss.js:75:14:75:14 | f |
197+
| ReflectedXss.js:83:12:83:19 | req.body | ReflectedXss.js:83:12:83:19 | req.body |
198+
| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) |
199+
| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) |
200+
| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) |
201+
| ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) |
202+
| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) |
203+
| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) |
204+
| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) |
205+
| ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) |
103206
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
104207
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
105208
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
@@ -178,6 +281,20 @@ edges
178281
#select
179282
| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value |
180283
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:17:31:17:39 | params.id | user-provided value |
284+
| ReflectedXss.js:22:12:22:19 | req.body | ReflectedXss.js:22:12:22:19 | req.body | ReflectedXss.js:22:12:22:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:22:12:22:19 | req.body | user-provided value |
285+
| ReflectedXss.js:23:12:23:27 | marked(req.body) | ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:23:19:23:26 | req.body | user-provided value |
286+
| ReflectedXss.js:29:12:29:19 | req.body | ReflectedXss.js:29:12:29:19 | req.body | ReflectedXss.js:29:12:29:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:29:12:29:19 | req.body | user-provided value |
287+
| ReflectedXss.js:34:12:34:18 | mytable | ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:34:12:34:18 | mytable | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:32:14:32:21 | req.body | user-provided value |
288+
| ReflectedXss.js:41:12:41:19 | req.body | ReflectedXss.js:41:12:41:19 | req.body | ReflectedXss.js:41:12:41:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:41:12:41:19 | req.body | user-provided value |
289+
| ReflectedXss.js:42:12:42:39 | convert ... q.body) | ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:42:31:42:38 | req.body | user-provided value |
290+
| ReflectedXss.js:56:12:56:19 | req.body | ReflectedXss.js:56:12:56:19 | req.body | ReflectedXss.js:56:12:56:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:56:12:56:19 | req.body | user-provided value |
291+
| ReflectedXss.js:65:16:65:19 | file | ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:65:16:65:19 | file | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:64:14:64:21 | req.body | user-provided value |
292+
| ReflectedXss.js:68:12:68:52 | remark( ... tring() | ReflectedXss.js:68:33:68:40 | req.body | ReflectedXss.js:68:12:68:52 | remark( ... tring() | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:68:33:68:40 | req.body | user-provided value |
293+
| ReflectedXss.js:72:12:72:65 | unified ... oString | ReflectedXss.js:72:48:72:55 | req.body | ReflectedXss.js:72:12:72:65 | unified ... oString | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:72:48:72:55 | req.body | user-provided value |
294+
| ReflectedXss.js:75:14:75:14 | f | ReflectedXss.js:74:20:74:27 | req.body | ReflectedXss.js:75:14:75:14 | f | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:74:20:74:27 | req.body | user-provided value |
295+
| ReflectedXss.js:83:12:83:19 | req.body | ReflectedXss.js:83:12:83:19 | req.body | ReflectedXss.js:83:12:83:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:83:12:83:19 | req.body | user-provided value |
296+
| ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | ReflectedXss.js:84:22:84:29 | req.body | ReflectedXss.js:84:12:84:30 | snarkdown(req.body) | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:84:22:84:29 | req.body | user-provided value |
297+
| ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | ReflectedXss.js:85:23:85:30 | req.body | ReflectedXss.js:85:12:85:31 | snarkdown2(req.body) | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:85:23:85:30 | req.body | user-provided value |
181298
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | user-provided value |
182299
| ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | user-provided value |
183300
| ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | user-provided value |

javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,71 @@ app.get('/user/:id', function(req, res) {
1616
function moreBadStuff(params, res) {
1717
res.send("Unknown user: " + params.id); // NOT OK
1818
}
19+
20+
var marked = require("marked");
21+
app.get('/user/:id', function(req, res) {
22+
res.send(req.body); // NOT OK
23+
res.send(marked(req.body)); // NOT OK
24+
});
25+
26+
27+
var table = require('markdown-table')
28+
app.get('/user/:id', function(req, res) {
29+
res.send(req.body); // NOT OK
30+
var mytable = table([
31+
['Name', 'Content'],
32+
['body', req.body]
33+
]);
34+
res.send(mytable); // NOT OK
35+
});
36+
37+
var showdown = require('showdown');
38+
var converter = new showdown.Converter();
39+
40+
app.get('/user/:id', function(req, res) {
41+
res.send(req.body); // NOT OK
42+
res.send(converter.makeHtml(req.body)); // NOT OK
43+
});
44+
45+
var unified = require('unified');
46+
var markdown = require('remark-parse');
47+
var remark2rehype = require('remark-rehype');
48+
var doc = require('rehype-document');
49+
var format = require('rehype-format');
50+
var html = require('rehype-stringify');
51+
var remark = require("remark");
52+
var sanitize = require("rehype-sanitize");
53+
const { resetExtensions } = require('showdown');
54+
55+
app.get('/user/:id', function (req, res) {
56+
res.send(req.body); // NOT OK
57+
58+
unified()
59+
.use(markdown)
60+
.use(remark2rehype)
61+
.use(doc, { title: '👋🌍' })
62+
.use(format)
63+
.use(html)
64+
.process(req.body, function (err, file) {
65+
res.send(file); // NOT OK
66+
});
67+
68+
res.send(remark().processSync(req.body).toString()); // NOT OK
69+
70+
res.send(remark().use(sanitize).processSync(req.body).toString()); // OK
71+
72+
res.send(unified().use(markdown).processSync(req.body).toString); // NOT OK
73+
74+
remark().process(req.body, (e, f) => {
75+
res.send(f); // NOT OK
76+
})
77+
});
78+
79+
import snarkdown from 'snarkdown';
80+
var snarkdown2 = require("snarkdown");
81+
82+
app.get('/user/:id', function (req, res) {
83+
res.send(req.body); // NOT OK
84+
res.send(snarkdown(req.body)); // NOT OK
85+
res.send(snarkdown2(req.body)); // NOT OK
86+
});

0 commit comments

Comments
 (0)