-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathUnicodeBypassValidationQuery.qll
More file actions
73 lines (66 loc) · 2.79 KB
/
UnicodeBypassValidationQuery.qll
File metadata and controls
73 lines (66 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* Provides a taint-tracking configuration for detecting "Unicode transformation mishandling" vulnerabilities.
*/
private import python
import semmle.python.ApiGraphs
import semmle.python.Concepts
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.internal.DataFlowPublic
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.internal.TaintTrackingPrivate
import semmle.python.dataflow.new.RemoteFlowSources
import UnicodeBypassValidationCustomizations::UnicodeBypassValidation
/** A state signifying that a logical validation has not been performed. */
class PreValidation extends DataFlow::FlowState {
PreValidation() { this = "PreValidation" }
}
/** A state signifying that a logical validation has been performed. */
class PostValidation extends DataFlow::FlowState {
PostValidation() { this = "PostValidation" }
}
/**
* A taint-tracking configuration for detecting "Unicode transformation mishandling" vulnerabilities.
*
* This configuration uses two flow states, `PreValidation` and `PostValidation`,
* to track the requirement that a logical validation has been performed before the Unicode Transformation.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "UnicodeBypassValidation" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
source instanceof RemoteFlowSource and state instanceof PreValidation
}
override predicate isAdditionalTaintStep(
DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo,
DataFlow::FlowState stateTo
) {
(
exists(Escaping escaping | nodeFrom = escaping.getAnInput() and nodeTo = escaping.getOutput())
or
exists(RegexExecution re | nodeFrom = re.getString() and nodeTo = re)
or
stringManipulation(nodeFrom, nodeTo)
) and
stateFrom instanceof PreValidation and
stateTo instanceof PostValidation
}
/* A Unicode Tranformation (Unicode tranformation) is considered a sink when the algorithm used is either NFC or NFKC. */
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
exists(API::CallNode cn |
cn = API::moduleImport("unicodedata").getMember("normalize").getACall() and
sink = cn.getArg(1)
or
cn = API::moduleImport("unidecode").getMember("unidecode").getACall() and
sink = cn.getArg(0)
or
cn = API::moduleImport("pyunormalize").getMember(["NFC", "NFD", "NFKC", "NFKD"]).getACall() and
sink = cn.getArg(0)
or
cn = API::moduleImport("pyunormalize").getMember("normalize").getACall() and
sink = cn.getArg(1)
or
cn = API::moduleImport("textnorm").getMember("normalize_unicode").getACall() and
sink = cn.getArg(0)
) and
state instanceof PostValidation
}
}