Switch to inline test expectations; fix failing test outputs

This commit is contained in:
Joe Farebrother
2021-02-17 17:54:57 +00:00
parent 7b5961769a
commit a3b8d4ab2d
5 changed files with 96 additions and 143 deletions

View File

@@ -118,7 +118,7 @@ private class ApacheHttpGetter extends TaintPreservingCallable {
ApacheHttpGetter() {
exists(string pkg, string ty, string mtd, Method m |
this.(Method).overrides*(m) and
m.getDeclaringType().hasQualifiedName(pkg, ty) and
m.getDeclaringType().getSourceDeclaration().hasQualifiedName(pkg, ty) and
m.hasName(mtd)
|
pkg = "org.apache.http" and
@@ -165,7 +165,7 @@ private class ApacheHttpGetter extends TaintPreservingCallable {
mtd = ["getFirstHeader", "getHeader", "getHeaders", "getLastHeader", "headerIterator"]
or
ty = "HttpRequest" and
mtd = ["getAuthority", "getPath", "getRequestUri", "getScheme", "getUri"]
mtd = ["getAuthority", "getMethod", "getPath", "getRequestUri", "getUri"]
or
ty = "HttpEntityContainer" and
mtd = "getEntity"
@@ -177,10 +177,10 @@ private class ApacheHttpGetter extends TaintPreservingCallable {
mtd = ["getContent", "getTrailers"]
or
ty = "EntityDetails" and
mtd = ["getContentType", "getTrailerNames"]
mtd = ["getContentType", "getContentEncoding", "getTrailerNames"]
)
or
pkg = "org.apache.hc.core5.message" and
pkg = "org.apache.hc.core5.http.message" and
ty = "RequestLine" and
mtd = ["getMethod", "getUri", "toString"]
or
@@ -189,7 +189,7 @@ private class ApacheHttpGetter extends TaintPreservingCallable {
mtd = "get"
or
pkg = "org.apache.hc.core5.net" and
ty = "UriAuthority" and
ty = "URIAuthority" and
mtd = ["getHostName", "toString"]
)
}
@@ -204,7 +204,7 @@ private class UtilMethod extends TaintPreservingCallable {
this.getDeclaringType().hasQualifiedName(pkg, ty) and
this.hasName(mtd)
|
pkg = ["org.apache.http.util", "org.apache.hc.core5.io.entity"] and
pkg = ["org.apache.http.util", "org.apache.hc.core5.http.io.entity"] and
ty = "EntityUtils" and
mtd = ["toString", "toByteArray", "getContentCharSet", "getContentMimeType", "parse"]
or
@@ -216,7 +216,7 @@ private class UtilMethod extends TaintPreservingCallable {
ty = "Args" and
mtd = ["containsNoBlanks", "notBlank", "notEmpty", "notNull"]
or
pkg = "org.apache.hc.core5.io.entity" and
pkg = "org.apache.hc.core5.http.io.entity" and
ty = "HttpEntities" and
mtd = ["create", "createGziped", "createUrlEncoded", "gzip", "withTrailers"]
)
@@ -239,7 +239,7 @@ private class EntitySetter extends TaintPreservingCallable {
private class EntityConstructor extends TaintPreservingCallable, Constructor {
EntityConstructor() {
this.getDeclaringType()
.hasQualifiedName(["org.apache.http.entity", "org.apache.hc.core5.io.entity"],
.hasQualifiedName(["org.apache.http.entity", "org.apache.hc.core5.http.io.entity"],
[
"BasicHttpEntity", "BufferedHttpEntity", "ByteArrayEntity", "HttpEntityWrapper",
"InputStreamEntity", "StringEntity"

View File

@@ -12,54 +12,54 @@ class A {
class Test1 implements HttpRequestHandler {
public void handle(HttpRequest req, HttpResponse res, HttpContext ctx) throws IOException {
A.sink(req.getRequestLine());
A.sink(req.getRequestLine().getUri());
A.sink(req.getRequestLine().getMethod());
A.sink(req.getAllHeaders());
A.sink(req.getRequestLine()); //$hasTaintFlow=y
A.sink(req.getRequestLine().getUri()); //$hasTaintFlow=y
A.sink(req.getRequestLine().getMethod()); //$hasTaintFlow=y
A.sink(req.getAllHeaders()); //$hasTaintFlow=y
HeaderIterator it = req.headerIterator();
A.sink(it.next());
A.sink(it.nextHeader());
A.sink(it.next()); //$hasTaintFlow=y
A.sink(it.nextHeader()); //$hasTaintFlow=y
Header h = req.getHeaders("abc")[3];
A.sink(h.getName());
A.sink(h.getValue());
A.sink(h.getName()); //$hasTaintFlow=y
A.sink(h.getValue()); //$hasTaintFlow=y
HeaderElement el = h.getElements()[0];
A.sink(el.getName());
A.sink(el.getValue());
A.sink(el.getParameters());
A.sink(el.getParameterByName("abc").getValue());
A.sink(el.getParameter(0).getName());
A.sink(el.getName()); //$hasTaintFlow=y
A.sink(el.getValue()); //$hasTaintFlow=y
A.sink(el.getParameters()); //$hasTaintFlow=y
A.sink(el.getParameterByName("abc").getValue()); //$hasTaintFlow=y
A.sink(el.getParameter(0).getName()); //$hasTaintFlow=y
HttpEntity ent = ((HttpEntityEnclosingRequest)req).getEntity();
A.sink(ent.getContent());
A.sink(ent.getContentEncoding());
A.sink(ent.getContentType());
A.sink(EntityUtils.toString(ent));
A.sink(EntityUtils.toByteArray(ent));
A.sink(EntityUtils.getContentCharSet(ent));
A.sink(EntityUtils.getContentMimeType(ent));
res.setEntity(new StringEntity("<a href='" + req.getRequestLine().getUri() + "'>a</a>"));
EntityUtils.updateEntity(res, new ByteArrayEntity(EntityUtils.toByteArray(ent)));
res.setHeader("Location", req.getRequestLine().getUri());
res.setHeader(new BasicHeader("Location", req.getRequestLine().getUri()));
A.sink(ent.getContent()); //$hasTaintFlow=y
A.sink(ent.getContentEncoding()); //$hasTaintFlow=y
A.sink(ent.getContentType()); //$hasTaintFlow=y
A.sink(EntityUtils.toString(ent)); //$hasTaintFlow=y
A.sink(EntityUtils.toByteArray(ent)); //$hasTaintFlow=y
A.sink(EntityUtils.getContentCharSet(ent)); //$hasTaintFlow=y
A.sink(EntityUtils.getContentMimeType(ent)); //$hasTaintFlow=y
res.setEntity(new StringEntity("<a href='" + req.getRequestLine().getUri() + "'>a</a>")); //$hasTaintFlow=y
EntityUtils.updateEntity(res, new ByteArrayEntity(EntityUtils.toByteArray(ent))); //$hasTaintFlow=y
res.setHeader("Location", req.getRequestLine().getUri()); //$hasTaintFlow=y
res.setHeader(new BasicHeader("Location", req.getRequestLine().getUri())); //$hasTaintFlow=y
}
}
void test2() {
ByteArrayBuffer bbuf = new ByteArrayBuffer(42);
bbuf.append((byte[]) taint(), 0, 3);
sink(bbuf.buffer());
sink(bbuf.toByteArray());
sink(bbuf.buffer()); //$hasTaintFlow=y
sink(bbuf.toByteArray()); //$hasTaintFlow=y
CharArrayBuffer cbuf = new CharArrayBuffer(42);
cbuf.append(bbuf.toByteArray(), 0, 3);
sink(cbuf.toCharArray());
sink(cbuf.toString());
sink(cbuf.subSequence(0, 3));
sink(cbuf.substring(0, 3));
sink(cbuf.substringTrimmed(0, 3));
sink(cbuf.toCharArray()); //$hasTaintFlow=y
sink(cbuf.toString()); //$hasTaintFlow=y
sink(cbuf.subSequence(0, 3)); //$hasTaintFlow=y
sink(cbuf.substring(0, 3)); //$hasTaintFlow=y
sink(cbuf.substringTrimmed(0, 3)); //$hasTaintFlow=y
sink(Args.notNull(taint(), "x"));
sink(Args.notEmpty((String) taint(), "x"));
sink(Args.notBlank((String) taint(), "x"));
sink(Args.notNull(taint(), "x")); //$hasTaintFlow=y
sink(Args.notEmpty((String) taint(), "x")); //$hasTaintFlow=y
sink(Args.notBlank((String) taint(), "x")); //$hasTaintFlow=y
sink(Args.notNull("x", (String) taint())); // Good
}
}

View File

@@ -13,56 +13,56 @@ class B {
class Test1 implements HttpRequestHandler {
public void handle(ClassicHttpRequest req, ClassicHttpResponse res, HttpContext ctx) throws IOException, ParseException {
B.sink(req.getAuthority().getHostName());
B.sink(req.getAuthority().toString());
B.sink(req.getMethod());
B.sink(req.getPath());
B.sink(req.getScheme());
B.sink(req.getRequestUri());
B.sink(req.getAuthority().getHostName()); //$hasTaintFlow=y
B.sink(req.getAuthority().toString()); //$hasTaintFlow=y
B.sink(req.getMethod()); //$hasTaintFlow=y
B.sink(req.getPath()); //$hasTaintFlow=y
B.sink(req.getScheme());
B.sink(req.getRequestUri()); //$hasTaintFlow=y
RequestLine line = new RequestLine(req);
B.sink(line.getUri());
B.sink(line.getMethod());
B.sink(req.getHeaders());
B.sink(req.headerIterator());
B.sink(line.getUri()); //$hasTaintFlow=y
B.sink(line.getMethod()); //$hasTaintFlow=y
B.sink(req.getHeaders()); //$hasTaintFlow=y
B.sink(req.headerIterator()); //$hasTaintFlow=y
Header h = req.getHeaders("abc")[3];
B.sink(h.getName());
B.sink(h.getValue());
B.sink(req.getFirstHeader("abc"));
B.sink(req.getLastHeader("abc"));
B.sink(h.getName()); //$hasTaintFlow=y
B.sink(h.getValue()); //$hasTaintFlow=y
B.sink(req.getFirstHeader("abc")); //$hasTaintFlow=y
B.sink(req.getLastHeader("abc")); //$hasTaintFlow=y
HttpEntity ent = req.getEntity();
B.sink(ent.getContent());
B.sink(ent.getContentEncoding());
B.sink(ent.getContentType());
B.sink(ent.getTrailerNames());
B.sink(ent.getTrailers().get());
B.sink(EntityUtils.toString(ent));
B.sink(EntityUtils.toByteArray(ent));
B.sink(EntityUtils.parse(ent));
res.setEntity(new StringEntity("<a href='" + req.getRequestUri() + "'>a</a>"));
res.setEntity(new ByteArrayEntity(EntityUtils.toByteArray(ent), ContentType.TEXT_HTML));
res.setEntity(HttpEntities.create("<a href='" + req.getRequestUri() + "'>a</a>"));
res.setHeader("Location", req.getRequestUri());
res.setHeader(new BasicHeader("Location", req.getRequestUri()));
B.sink(ent.getContent()); //$hasTaintFlow=y
B.sink(ent.getContentEncoding()); //$hasTaintFlow=y
B.sink(ent.getContentType()); //$hasTaintFlow=y
B.sink(ent.getTrailerNames()); //$hasTaintFlow=y
B.sink(ent.getTrailers().get()); //$hasTaintFlow=y
B.sink(EntityUtils.toString(ent)); //$hasTaintFlow=y
B.sink(EntityUtils.toByteArray(ent)); //$hasTaintFlow=y
B.sink(EntityUtils.parse(ent)); //$hasTaintFlow=y
res.setEntity(new StringEntity("<a href='" + req.getRequestUri() + "'>a</a>")); //$hasTaintFlow=y
res.setEntity(new ByteArrayEntity(EntityUtils.toByteArray(ent), ContentType.TEXT_HTML)); //$hasTaintFlow=y
res.setEntity(HttpEntities.create("<a href='" + req.getRequestUri() + "'>a</a>")); //$hasTaintFlow=y
res.setHeader("Location", req.getRequestUri()); //$hasTaintFlow=y
res.setHeader(new BasicHeader("Location", req.getRequestUri())); //$hasTaintFlow=y
}
}
void test2() {
ByteArrayBuffer bbuf = new ByteArrayBuffer(42);
bbuf.append((byte[]) taint(), 0, 3);
sink(bbuf.array());
sink(bbuf.toByteArray());
bbuf.append((byte[]) taint(), 0, 3);
sink(bbuf.array()); //$hasTaintFlow=y
sink(bbuf.toByteArray()); //$hasTaintFlow=y
CharArrayBuffer cbuf = new CharArrayBuffer(42);
cbuf.append(bbuf.toByteArray(), 0, 3);
sink(cbuf.toCharArray());
sink(cbuf.toString());
sink(cbuf.subSequence(0, 3));
sink(cbuf.substring(0, 3));
sink(cbuf.substringTrimmed(0, 3));
cbuf.append(bbuf.toByteArray(), 0, 3);
sink(cbuf.toCharArray()); //$hasTaintFlow=y
sink(cbuf.toString()); //$hasTaintFlow=y
sink(cbuf.subSequence(0, 3)); //$hasTaintFlow=y
sink(cbuf.substring(0, 3)); //$hasTaintFlow=y
sink(cbuf.substringTrimmed(0, 3)); //$hasTaintFlow=y
sink(Args.notNull(taint(), "x"));
sink(Args.notEmpty((String) taint(), "x"));
sink(Args.notBlank((String) taint(), "x"));
sink(Args.notNull(taint(), "x")); //$hasTaintFlow=y
sink(Args.notEmpty((String) taint(), "x")); //$hasTaintFlow=y
sink(Args.notBlank((String) taint(), "x")); //$hasTaintFlow=y
sink(Args.notNull("x", (String) taint())); // Good
}
}

View File

@@ -1,59 +0,0 @@
| A.java:14:28:14:42 | req | A.java:15:20:15:39 | getRequestLine(...) |
| A.java:14:28:14:42 | req | A.java:16:20:16:48 | getUri(...) |
| A.java:14:28:14:42 | req | A.java:17:20:17:51 | getMethod(...) |
| A.java:14:28:14:42 | req | A.java:18:20:18:38 | getAllHeaders(...) |
| A.java:14:28:14:42 | req | A.java:20:20:20:28 | next(...) |
| A.java:14:28:14:42 | req | A.java:21:20:21:34 | nextHeader(...) |
| A.java:14:28:14:42 | req | A.java:23:20:23:30 | getName(...) |
| A.java:14:28:14:42 | req | A.java:24:20:24:31 | getValue(...) |
| A.java:14:28:14:42 | req | A.java:26:20:26:31 | getName(...) |
| A.java:14:28:14:42 | req | A.java:27:20:27:32 | getValue(...) |
| A.java:14:28:14:42 | req | A.java:28:20:28:37 | getParameters(...) |
| A.java:14:28:14:42 | req | A.java:29:20:29:58 | getValue(...) |
| A.java:14:28:14:42 | req | A.java:30:20:30:47 | getName(...) |
| A.java:14:28:14:42 | req | A.java:32:20:32:35 | getContent(...) |
| A.java:14:28:14:42 | req | A.java:33:20:33:43 | getContentEncoding(...) |
| A.java:14:28:14:42 | req | A.java:34:20:34:39 | getContentType(...) |
| A.java:14:28:14:42 | req | A.java:35:20:35:44 | toString(...) |
| A.java:14:28:14:42 | req | A.java:36:20:36:47 | toByteArray(...) |
| A.java:14:28:14:42 | req | A.java:37:20:37:53 | getContentCharSet(...) |
| A.java:14:28:14:42 | req | A.java:38:20:38:54 | getContentMimeType(...) |
| A.java:14:28:14:42 | req | A.java:39:27:39:99 | new StringEntity(...) |
| A.java:14:28:14:42 | req | A.java:40:43:40:91 | new ByteArrayEntity(...) |
| A.java:14:28:14:42 | req | A.java:41:39:41:67 | getUri(...) |
| A.java:14:28:14:42 | req | A.java:42:55:42:83 | getUri(...) |
| A.java:32:20:32:35 | getContent(...) | A.java:32:20:32:35 | getContent(...) |
| A.java:48:30:48:36 | taint(...) | A.java:49:14:49:26 | buffer(...) |
| A.java:48:30:48:36 | taint(...) | A.java:50:14:50:31 | toByteArray(...) |
| A.java:48:30:48:36 | taint(...) | A.java:54:14:54:31 | toCharArray(...) |
| A.java:48:30:48:36 | taint(...) | A.java:55:14:55:28 | toString(...) |
| A.java:48:30:48:36 | taint(...) | A.java:56:14:56:35 | subSequence(...) |
| A.java:48:30:48:36 | taint(...) | A.java:57:14:57:33 | substring(...) |
| A.java:48:30:48:36 | taint(...) | A.java:58:14:58:40 | substringTrimmed(...) |
| A.java:60:27:60:33 | taint(...) | A.java:60:14:60:39 | notNull(...) |
| A.java:61:37:61:43 | taint(...) | A.java:61:14:61:49 | notEmpty(...) |
| A.java:62:37:62:43 | taint(...) | A.java:62:14:62:49 | notBlank(...) |
| B.java:15:28:15:49 | req | B.java:19:20:19:32 | getPath(...) |
| B.java:15:28:15:49 | req | B.java:20:20:20:34 | getScheme(...) |
| B.java:15:28:15:49 | req | B.java:21:20:21:38 | getRequestUri(...) |
| B.java:15:28:15:49 | req | B.java:25:20:25:35 | getHeaders(...) |
| B.java:15:28:15:49 | req | B.java:26:20:26:39 | headerIterator(...) |
| B.java:15:28:15:49 | req | B.java:28:20:28:30 | getName(...) |
| B.java:15:28:15:49 | req | B.java:29:20:29:31 | getValue(...) |
| B.java:15:28:15:49 | req | B.java:30:20:30:44 | getFirstHeader(...) |
| B.java:15:28:15:49 | req | B.java:31:20:31:43 | getLastHeader(...) |
| B.java:15:28:15:49 | req | B.java:33:20:33:35 | getContent(...) |
| B.java:15:28:15:49 | req | B.java:35:20:35:39 | getContentType(...) |
| B.java:15:28:15:49 | req | B.java:36:20:36:40 | getTrailerNames(...) |
| B.java:15:28:15:49 | req | B.java:44:39:44:57 | getRequestUri(...) |
| B.java:15:28:15:49 | req | B.java:45:55:45:73 | getRequestUri(...) |
| B.java:51:30:51:36 | taint(...) | B.java:52:14:52:25 | array(...) |
| B.java:51:30:51:36 | taint(...) | B.java:53:14:53:31 | toByteArray(...) |
| B.java:51:30:51:36 | taint(...) | B.java:57:14:57:31 | toCharArray(...) |
| B.java:51:30:51:36 | taint(...) | B.java:58:14:58:28 | toString(...) |
| B.java:51:30:51:36 | taint(...) | B.java:59:14:59:35 | subSequence(...) |
| B.java:51:30:51:36 | taint(...) | B.java:60:14:60:33 | substring(...) |
| B.java:51:30:51:36 | taint(...) | B.java:61:14:61:40 | substringTrimmed(...) |
| B.java:63:27:63:33 | taint(...) | B.java:63:14:63:39 | notNull(...) |
| B.java:64:37:64:43 | taint(...) | B.java:64:14:64:49 | notEmpty(...) |
| B.java:65:37:65:43 | taint(...) | B.java:65:14:65:49 | notBlank(...) |

View File

@@ -3,6 +3,7 @@ import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.XSS
import semmle.code.java.security.UrlRedirect
import TestUtilities.InlineExpectationsTest
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:frameworks:apache-http" }
@@ -22,6 +23,17 @@ class Conf extends TaintTracking::Configuration {
}
}
from DataFlow::Node src, DataFlow::Node sink, Conf conf
where conf.hasFlow(src, sink)
select src, sink
class HasFlowTest extends InlineExpectationsTest {
HasFlowTest() { this = "HasFlowTest" }
override string getARelevantTag() { result = "hasTaintFlow" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasTaintFlow" and
exists(DataFlow::Node src, DataFlow::Node sink, Conf conf | conf.hasFlow(src, sink) |
sink.getLocation() = location and
element = sink.toString() and
value = "y"
)
}
}