Skip to content

Commit 1f46f57

Browse files
committed
Create Markup.qll
1 parent 85d95df commit 1f46f57

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the hypothetical `markup` PyPI package
3+
* (imported as `markup`)
4+
*
5+
* This models parsing functions that may process untrusted input.
6+
*/
7+
8+
private import python
9+
private import semmle.python.dataflow.new.DataFlow
10+
private import semmle.python.Concepts
11+
private import semmle.python.ApiGraphs
12+
13+
private module Markup {
14+
/**
15+
* A call to any of the parsing functions in `markup` (`parse`, `parse_document`,
16+
* `unsafe_parse`, `unsafe_parse_document`, `safe_parse`, `safe_parse_document`)
17+
*
18+
* These functions may be unsafe if they parse untrusted markup content.
19+
*/
20+
private class MarkupParseCall extends Decoding::Range, DataFlow::CallCfgNode {
21+
override CallNode node;
22+
string func_name;
23+
24+
MarkupParseCall() {
25+
func_name in [
26+
"parse", "parse_document", "unsafe_parse", "unsafe_parse_document",
27+
"safe_parse", "safe_parse_document", "div", "page"
28+
] and
29+
this = API::moduleImport("markup").getMember(func_name).getACall()
30+
}
31+
32+
/**
33+
* Determine whether this function call may unsafely execute input data.
34+
*
35+
* `unsafe_parse`, `unsafe_parse_document`, and `parse`, `parse_document` without secure settings
36+
* are considered unsafe.
37+
*/
38+
override predicate mayExecuteInput() {
39+
func_name in ["unsafe_parse", "unsafe_parse_document"]
40+
or
41+
func_name in ["parse", "parse_document"] and
42+
// If no safe mode argument is set, assume unsafe
43+
not exists(DataFlow::Node mode_arg |
44+
mode_arg in [this.getArg(1), this.getArgByName("mode")] |
45+
mode_arg =
46+
API::moduleImport("markup")
47+
.getMember(["SafeMode", "StrictMode"])
48+
.getAValueReachableFromSource()
49+
)
50+
}
51+
52+
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("input")] }
53+
54+
override DataFlow::Node getOutput() { result = this }
55+
56+
override string getFormat() { result = "Markup" }
57+
}
58+
}

0 commit comments

Comments
 (0)