|
13 | 13 |
|
14 | 14 | import cpp
|
15 | 15 | import semmle.code.cpp.security.Security
|
16 |
| -// import semmle.code.cpp.security.FunctionWithWrappers |
17 |
| -// import semmle.code.cpp.security.TaintTracking |
18 |
| -// import TaintedWithPath |
19 | 16 | import semmle.code.cpp.dataflow.TaintTracking
|
20 | 17 | import DataFlow::PathGraph
|
21 | 18 |
|
@@ -69,102 +66,74 @@ predicate pqxxTransactionSqlArgument(string function, int arg) {
|
69 | 66 | function = "stream" and arg = 0
|
70 | 67 | }
|
71 | 68 |
|
72 |
| -predicate pqxxConnectionSqlArgument(string function, int arg) { |
73 |
| - function = "prepare" and arg = 1 |
74 |
| -} |
| 69 | +predicate pqxxConnectionSqlArgument(string function, int arg) { function = "prepare" and arg = 1 } |
75 | 70 |
|
76 | 71 | Expr getPqxxSqlArgument() {
|
77 | 72 | exists(FunctionCall fc, Expr e, int argIndex, Type t |
|
78 |
| - // examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'. |
79 |
| - e = fc.getQualifier() and |
80 |
| - // to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior |
81 |
| - // and return pointer to a connection/transation object |
82 |
| - e.getType().refersTo(t) and |
83 |
| - // transation exec and connection prepare variations |
84 |
| - ( |
85 |
| - pqxxTransationClassNames(t.getName(), _) and pqxxTransactionSqlArgument(fc.getTarget().getName(), argIndex) |
86 |
| - or |
87 |
| - pqxxConnectionClassNames(t.getName(), _) and pqxxConnectionSqlArgument(fc.getTarget().getName(), argIndex) |
88 |
| - ) |
89 |
| - and |
90 |
| - result = fc.getArgument(argIndex) |
| 73 | + // examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'. |
| 74 | + e = fc.getQualifier() and |
| 75 | + // to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior |
| 76 | + // and return pointer to a connection/transation object |
| 77 | + e.getType().refersTo(t) and |
| 78 | + // transation exec and connection prepare variations |
| 79 | + ( |
| 80 | + pqxxTransationClassNames(t.getName(), _) and |
| 81 | + pqxxTransactionSqlArgument(fc.getTarget().getName(), argIndex) |
| 82 | + or |
| 83 | + pqxxConnectionClassNames(t.getName(), _) and |
| 84 | + pqxxConnectionSqlArgument(fc.getTarget().getName(), argIndex) |
| 85 | + ) and |
| 86 | + result = fc.getArgument(argIndex) |
91 | 87 | )
|
92 | 88 | }
|
93 | 89 |
|
94 | 90 | predicate pqxxEscapeArgument(string function, int arg) {
|
95 | 91 | arg = 0 and
|
96 | 92 | (
|
97 |
| - function = "esc" |
98 |
| - or |
99 |
| - function = "esc_raw" |
100 |
| - or |
101 |
| - function = "quote" |
102 |
| - or |
103 |
| - function = "quote_raw" |
104 |
| - or |
105 |
| - function = "quote_name" |
106 |
| - or |
107 |
| - function = "quote_table" |
108 |
| - or |
109 |
| - function = "esc_like" |
| 93 | + function = "esc" |
| 94 | + or |
| 95 | + function = "esc_raw" |
| 96 | + or |
| 97 | + function = "quote" |
| 98 | + or |
| 99 | + function = "quote_raw" |
| 100 | + or |
| 101 | + function = "quote_name" |
| 102 | + or |
| 103 | + function = "quote_table" |
| 104 | + or |
| 105 | + function = "esc_like" |
110 | 106 | )
|
111 | 107 | }
|
112 | 108 |
|
113 | 109 | predicate isEscapedPqxxArgument(Expr argExpr) {
|
114 | 110 | exists(FunctionCall fc, Expr e, int argIndex, Type t |
|
115 |
| - // examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'. |
116 |
| - e = fc.getQualifier() and |
117 |
| - // to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior |
118 |
| - // and return pointer to a connection/transation object |
119 |
| - e.getType().refersTo(t) and |
120 |
| - // transation and connection escape functions |
121 |
| - (pqxxTransationClassNames(t.getName(), _) or pqxxConnectionClassNames(t.getName(), _)) |
122 |
| - and |
123 |
| - pqxxEscapeArgument(fc.getTarget().getName(), argIndex) |
124 |
| - and |
125 |
| - // eval is escaped |
126 |
| - argExpr = fc.getArgument(argIndex) |
| 111 | + // examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'. |
| 112 | + e = fc.getQualifier() and |
| 113 | + // to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior |
| 114 | + // and return pointer to a connection/transation object |
| 115 | + e.getType().refersTo(t) and |
| 116 | + // transation and connection escape functions |
| 117 | + (pqxxTransationClassNames(t.getName(), _) or pqxxConnectionClassNames(t.getName(), _)) and |
| 118 | + pqxxEscapeArgument(fc.getTarget().getName(), argIndex) and |
| 119 | + // eval is escaped |
| 120 | + argExpr = fc.getArgument(argIndex) |
127 | 121 | )
|
128 | 122 | }
|
129 | 123 |
|
130 |
| -// class Configuration extends TaintTrackingConfiguration { |
131 |
| -// override predicate isSink(Element tainted) { |
132 |
| -// tainted = getPqxxSqlArgument() |
133 |
| -// } |
134 |
| -// override predicate isBarrier(Expr e) { |
135 |
| -// super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType |
136 |
| -// } |
137 |
| -// } |
138 |
| -// from |
139 |
| -// Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode, string taintCause |
140 |
| -// where |
141 |
| -// taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and |
142 |
| -// isUserInput(taintSource, taintCause) |
143 |
| -// select taintedArg, sourceNode, sinkNode, |
144 |
| -// "This argument to a SQL query function is derived from $@", taintSource, "user input (" + taintCause + ")" |
145 |
| - |
146 |
| - |
147 | 124 | class Configuration extends TaintTracking::Configuration {
|
148 | 125 | Configuration() { this = "SqlPqxxTainted" }
|
149 | 126 |
|
150 |
| - override predicate isSource(DataFlow::Node source) { |
151 |
| - isUserInput(source.asExpr(), _) |
152 |
| - } |
| 127 | + override predicate isSource(DataFlow::Node source) { isUserInput(source.asExpr(), _) } |
153 | 128 |
|
154 |
| - override predicate isSink(DataFlow::Node sink) { |
155 |
| - sink.asExpr() = getPqxxSqlArgument() |
156 |
| - } |
| 129 | + override predicate isSink(DataFlow::Node sink) { sink.asExpr() = getPqxxSqlArgument() } |
157 | 130 |
|
158 |
| - override predicate isSanitizer(DataFlow::Node node) { |
159 |
| - isEscapedPqxxArgument(node.asExpr()) |
160 |
| - } |
| 131 | + override predicate isSanitizer(DataFlow::Node node) { isEscapedPqxxArgument(node.asExpr()) } |
161 | 132 | }
|
162 | 133 |
|
163 |
| -from |
164 |
| - DataFlow::PathNode source, DataFlow::PathNode sink, Configuration config, string taintCause |
165 |
| -where |
| 134 | +from DataFlow::PathNode source, DataFlow::PathNode sink, Configuration config, string taintCause |
| 135 | +where |
166 | 136 | config.hasFlowPath(source, sink) and
|
167 | 137 | isUserInput(source.getNode().asExpr(), taintCause)
|
168 |
| -select |
169 |
| - sink, source, sink, |
170 |
| - "This argument to a SQL query function is derived from $@", source, "user input (" + taintCause + ")" |
| 138 | +select sink, source, sink, "This argument to a SQL query function is derived from $@", source, |
| 139 | + "user input (" + taintCause + ")" |
0 commit comments