Skip to content

Commit 09d969a

Browse files
committed
recognize sensitive files by file-system writes
1 parent 8f5a3e9 commit 09d969a

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

javascript/ql/src/semmle/javascript/security/dataflow/InsecureDownloadCustomizations.qll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,32 @@ module InsecureDownload {
112112
result instanceof Label::InsecureURL
113113
}
114114
}
115+
116+
/**
117+
* Gets a node for the response from `request`, type-tracked using `t`.
118+
*/
119+
DataFlow::SourceNode clientRequestResponse(DataFlow::TypeTracker t, ClientRequest request) {
120+
t.start() and
121+
result = request.getAResponseDataNode()
122+
or
123+
exists(DataFlow::TypeTracker t2 | result = clientRequestResponse(t2, request).track(t2, t))
124+
}
125+
126+
/**
127+
* A url that is downloaded through an insecure connection, where the result ends up being saved to a sensitive location.
128+
*/
129+
class FileWriteSink extends Sink {
130+
ClientRequest request;
131+
FileSystemWriteAccess write;
132+
133+
FileWriteSink() {
134+
this = request.getUrl() and
135+
clientRequestResponse(DataFlow::TypeTracker::end(), request).flowsTo(write.getADataNode()) and
136+
hasUnsafeExtension(write.getAPathArgument().getStringValue())
137+
}
138+
139+
override DataFlow::FlowLabel getALabel() { result instanceof Label::InsecureURL }
140+
141+
override DataFlow::Node getDownloadCall() { result = request }
142+
}
115143
}

javascript/ql/test/query-tests/Security/CWE-829/InsecureDownload.expected

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ nodes
1717
| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" |
1818
| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" |
1919
| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" |
20-
| insecure-download.js:46:12:46:38 | "http:/ ... unsafe" |
21-
| insecure-download.js:46:12:46:38 | "http:/ ... unsafe" |
22-
| insecure-download.js:46:12:46:38 | "http:/ ... unsafe" |
20+
| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" |
21+
| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" |
22+
| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" |
23+
| insecure-download.js:52:11:52:45 | "http:/ ... nknown" |
24+
| insecure-download.js:52:11:52:45 | "http:/ ... nknown" |
25+
| insecure-download.js:52:11:52:45 | "http:/ ... nknown" |
2326
edges
2427
| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:15:18:15:40 | buildTo ... llerUrl |
2528
| insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:15:18:15:40 | buildTo ... llerUrl |
@@ -33,11 +36,13 @@ edges
3336
| insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:36:9:36:45 | url |
3437
| insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:36:9:36:45 | url |
3538
| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" |
36-
| insecure-download.js:46:12:46:38 | "http:/ ... unsafe" | insecure-download.js:46:12:46:38 | "http:/ ... unsafe" |
39+
| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | insecure-download.js:48:12:48:38 | "http:/ ... unsafe" |
40+
| insecure-download.js:52:11:52:45 | "http:/ ... nknown" | insecure-download.js:52:11:52:45 | "http:/ ... nknown" |
3741
#select
3842
| insecure-download.js:5:16:5:28 | installer.url | insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | insecure-download.js:5:16:5:28 | installer.url | $@ of sensitive file from $@. | insecure-download.js:5:9:5:44 | nugget( ... => { }) | Download | insecure-download.js:9:27:9:138 | 'http:/ ... ll.exe' | HTTP source |
3943
| insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | $@ of sensitive file from $@. | insecure-download.js:30:5:30:43 | nugget( ... e.APK") | Download | insecure-download.js:30:12:30:42 | "http:/ ... fe.APK" | HTTP source |
4044
| insecure-download.js:37:23:37:25 | url | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:37:23:37:25 | url | $@ of sensitive file from $@. | insecure-download.js:37:5:37:42 | cp.exec ... () {}) | Download | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | HTTP source |
4145
| insecure-download.js:39:26:39:28 | url | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | insecure-download.js:39:26:39:28 | url | $@ of sensitive file from $@. | insecure-download.js:39:5:39:46 | cp.exec ... () {}) | Download | insecure-download.js:36:15:36:45 | "http:/ ... fe.APK" | HTTP source |
4246
| insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | $@ of sensitive file from $@. | insecure-download.js:41:5:41:42 | nugget( ... e.APK") | Download | insecure-download.js:41:12:41:41 | "ftp:// ... fe.APK" | HTTP source |
43-
| insecure-download.js:46:12:46:38 | "http:/ ... unsafe" | insecure-download.js:46:12:46:38 | "http:/ ... unsafe" | insecure-download.js:46:12:46:38 | "http:/ ... unsafe" | $@ of sensitive file from $@. | insecure-download.js:46:5:46:71 | nugget( ... => { }) | Download | insecure-download.js:46:12:46:38 | "http:/ ... unsafe" | HTTP source |
47+
| insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | $@ of sensitive file from $@. | insecure-download.js:48:5:48:71 | nugget( ... => { }) | Download | insecure-download.js:48:12:48:38 | "http:/ ... unsafe" | HTTP source |
48+
| insecure-download.js:52:11:52:45 | "http:/ ... nknown" | insecure-download.js:52:11:52:45 | "http:/ ... nknown" | insecure-download.js:52:11:52:45 | "http:/ ... nknown" | $@ of sensitive file from $@. | insecure-download.js:52:5:54:6 | $.get(" ... \\n }) | Download | insecure-download.js:52:11:52:45 | "http:/ ... nknown" | HTTP source |

javascript/ql/test/query-tests/Security/CWE-829/insecure-download.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,12 @@ function test() {
4848
nugget("http://example.org/unsafe", {target: "foo.exe"}, () => { }) // NOT OK
4949

5050
nugget("http://example.org/unsafe", {target: "foo.safe"}, () => { }) // OK
51+
52+
$.get("http://example.org/unsafe.unknown", function( data ) {
53+
writeFileAtomic('unsafe.exe', data, {}, function (err) {}); // NOT OK
54+
});
55+
56+
$.get("http://example.org/unsafe.unknown", function( data ) {
57+
writeFileAtomic('foo.safe', data, {}, function (err) {}); // OK
58+
});
5159
}

0 commit comments

Comments
 (0)