зеркало из https://github.com/github/codeql.git
C++: Rewrite `cpp/cgi-xss` to not use default taint tracking
Also add a test that demonstrates that we need to look at inidrect expressions and not direct ones.
This commit is contained in:
Родитель
5c44f8bbad
Коммит
3b777c2764
|
@ -13,15 +13,13 @@
|
|||
|
||||
import cpp
|
||||
import semmle.code.cpp.commons.Environment
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.ir.IR
|
||||
import Flow::PathGraph
|
||||
|
||||
/** A call that prints its arguments to `stdout`. */
|
||||
class PrintStdoutCall extends FunctionCall {
|
||||
PrintStdoutCall() {
|
||||
this.getTarget().hasGlobalOrStdName("puts") or
|
||||
this.getTarget().hasGlobalOrStdName("printf")
|
||||
}
|
||||
PrintStdoutCall() { this.getTarget().hasGlobalOrStdName(["puts", "printf"]) }
|
||||
}
|
||||
|
||||
/** A read of the QUERY_STRING environment variable */
|
||||
|
@ -29,19 +27,23 @@ class QueryString extends EnvironmentRead {
|
|||
QueryString() { this.getEnvironmentVariable() = "QUERY_STRING" }
|
||||
}
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSource(Expr source) { source instanceof QueryString }
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node.asIndirectExpr() instanceof QueryString }
|
||||
|
||||
override predicate isSink(Element tainted) {
|
||||
exists(PrintStdoutCall call | call.getAnArgument() = tainted)
|
||||
predicate isSink(DataFlow::Node node) {
|
||||
exists(PrintStdoutCall call | call.getAnArgument() = [node.asIndirectExpr(), node.asExpr()])
|
||||
}
|
||||
|
||||
override predicate isBarrier(Expr e) {
|
||||
super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node.asExpr().getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
}
|
||||
|
||||
from QueryString query, Element printedArg, PathNode sourceNode, PathNode sinkNode
|
||||
where taintedWithPath(query, printedArg, sourceNode, sinkNode)
|
||||
select printedArg, sourceNode, sinkNode, "Cross-site scripting vulnerability due to $@.", query,
|
||||
"this query data"
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from QueryString query, Flow::PathNode sourceNode, Flow::PathNode sinkNode
|
||||
where
|
||||
Flow::flowPath(sourceNode, sinkNode) and
|
||||
query = sourceNode.getNode().asIndirectExpr()
|
||||
select sinkNode.getNode(), sourceNode, sinkNode, "Cross-site scripting vulnerability due to $@.",
|
||||
query, "this query data"
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
edges
|
||||
| search.c:14:24:14:28 | query | search.c:17:8:17:12 | query |
|
||||
| search.c:14:24:14:28 | query | search.c:17:8:17:12 | query |
|
||||
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
|
||||
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:55:17:55:25 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:55:17:55:25 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:57:17:57:25 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:57:17:57:25 | raw_query |
|
||||
| search.c:55:17:55:25 | raw_query | search.c:14:24:14:28 | query |
|
||||
| search.c:57:17:57:25 | raw_query | search.c:22:24:22:28 | query |
|
||||
subpaths
|
||||
| search.c:14:24:14:28 | query indirection | search.c:17:8:17:12 | query indirection |
|
||||
| search.c:22:24:22:28 | query indirection | search.c:23:39:23:43 | query indirection |
|
||||
| search.c:55:24:55:28 | query indirection | search.c:62:8:62:17 | query_text indirection |
|
||||
| search.c:67:21:67:26 | call to getenv indirection | search.c:71:17:71:25 | raw_query indirection |
|
||||
| search.c:67:21:67:26 | call to getenv indirection | search.c:73:17:73:25 | raw_query indirection |
|
||||
| search.c:67:21:67:26 | call to getenv indirection | search.c:77:17:77:25 | raw_query indirection |
|
||||
| search.c:71:17:71:25 | raw_query indirection | search.c:14:24:14:28 | query indirection |
|
||||
| search.c:73:17:73:25 | raw_query indirection | search.c:22:24:22:28 | query indirection |
|
||||
| search.c:77:17:77:25 | raw_query indirection | search.c:55:24:55:28 | query indirection |
|
||||
nodes
|
||||
| search.c:14:24:14:28 | query | semmle.label | query |
|
||||
| search.c:17:8:17:12 | query | semmle.label | query |
|
||||
| search.c:17:8:17:12 | query | semmle.label | query |
|
||||
| search.c:22:24:22:28 | query | semmle.label | query |
|
||||
| search.c:23:39:23:43 | query | semmle.label | query |
|
||||
| search.c:23:39:23:43 | query | semmle.label | query |
|
||||
| search.c:51:21:51:26 | call to getenv | semmle.label | call to getenv |
|
||||
| search.c:51:21:51:26 | call to getenv | semmle.label | call to getenv |
|
||||
| search.c:55:17:55:25 | raw_query | semmle.label | raw_query |
|
||||
| search.c:57:17:57:25 | raw_query | semmle.label | raw_query |
|
||||
| search.c:14:24:14:28 | query indirection | semmle.label | query indirection |
|
||||
| search.c:17:8:17:12 | query indirection | semmle.label | query indirection |
|
||||
| search.c:22:24:22:28 | query indirection | semmle.label | query indirection |
|
||||
| search.c:23:39:23:43 | query indirection | semmle.label | query indirection |
|
||||
| search.c:55:24:55:28 | query indirection | semmle.label | query indirection |
|
||||
| search.c:62:8:62:17 | query_text indirection | semmle.label | query_text indirection |
|
||||
| search.c:67:21:67:26 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| search.c:71:17:71:25 | raw_query indirection | semmle.label | raw_query indirection |
|
||||
| search.c:73:17:73:25 | raw_query indirection | semmle.label | raw_query indirection |
|
||||
| search.c:77:17:77:25 | raw_query indirection | semmle.label | raw_query indirection |
|
||||
subpaths
|
||||
#select
|
||||
| search.c:17:8:17:12 | query | search.c:51:21:51:26 | call to getenv | search.c:17:8:17:12 | query | Cross-site scripting vulnerability due to $@. | search.c:51:21:51:26 | call to getenv | this query data |
|
||||
| search.c:23:39:23:43 | query | search.c:51:21:51:26 | call to getenv | search.c:23:39:23:43 | query | Cross-site scripting vulnerability due to $@. | search.c:51:21:51:26 | call to getenv | this query data |
|
||||
| search.c:17:8:17:12 | query indirection | search.c:67:21:67:26 | call to getenv indirection | search.c:17:8:17:12 | query indirection | Cross-site scripting vulnerability due to $@. | search.c:67:21:67:26 | call to getenv | this query data |
|
||||
| search.c:23:39:23:43 | query indirection | search.c:67:21:67:26 | call to getenv indirection | search.c:23:39:23:43 | query indirection | Cross-site scripting vulnerability due to $@. | search.c:67:21:67:26 | call to getenv | this query data |
|
||||
| search.c:62:8:62:17 | query_text indirection | search.c:67:21:67:26 | call to getenv indirection | search.c:62:8:62:17 | query_text indirection | Cross-site scripting vulnerability due to $@. | search.c:67:21:67:26 | call to getenv | this query data |
|
||||
|
|
|
@ -47,6 +47,22 @@ void good_server2(char* query) {
|
|||
printf("\n<p>%i</p>\n", i);
|
||||
}
|
||||
|
||||
typedef unsigned long size_t;
|
||||
size_t strlen(const char *s);
|
||||
char *strcpy(char *dst, const char *src);
|
||||
char *strcat(char *s1, const char *s2);
|
||||
|
||||
void bad_server3(char* query) {
|
||||
char query_text[strlen(query) + 8];
|
||||
strcpy(query_text, "query: ");
|
||||
strcat(query_text, query);
|
||||
|
||||
puts("<p>Query results for ");
|
||||
// BAD: Printing out an HTTP parameter with no escaping
|
||||
puts(query_text);
|
||||
puts("\n<p>\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char* raw_query = getenv("QUERY_STRING");
|
||||
if (strcmp("good1", argv[0]) == 0) {
|
||||
|
@ -57,5 +73,7 @@ int main(int argc, char** argv) {
|
|||
bad_server2(raw_query);
|
||||
} else if (strcmp("good2", argv[0]) == 0) {
|
||||
good_server2(raw_query);
|
||||
} else if (strcmp("bad3", argv[0]) == 0) {
|
||||
bad_server3(raw_query);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче