Skip to content

Commit 6a03bd8

Browse files
authored
Merge pull request #300 from esben-semmle/js/http-file-access-polish
Approved by asger-semmle
2 parents e6e4502 + 6687dfd commit 6a03bd8

File tree

21 files changed

+378
-3605
lines changed

21 files changed

+378
-3605
lines changed

change-notes/1.19/analysis-javascript.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
| **Query** | **Tags** | **Purpose** |
1717
|-----------------------------------------------|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
1818
| Enabling Node.js integration for Electron web content renderers (`js/enabling-electron-renderer-node-integration`) | security, frameworks/electron, external/cwe/cwe-094 | Highlights Electron web content renderer preferences with Node.js integration enabled, indicating a violation of [CWE-94](https://cwe.mitre.org/data/definitions/94.html). Results are not shown on LGTM by default. |
19+
| File data in outbound network request | security, external/cwe/cwe-200 | Highlights locations where file data is sent in a network request. Results are not shown on LGTM by default. |
1920
| Host header poisoning in email generation | security, external/cwe/cwe-640 | Highlights code that generates emails with links that can be hijacked by HTTP host header poisoning, indicating a violation of [CWE-640](https://cwe.mitre.org/data/definitions/640.html). Results shown on LGTM by default. |
2021
| Replacement of a substring with itself (`js/identity-replacement`) | correctness, security, external/cwe/cwe-116 | Highlights string replacements that replace a string with itself, which usually indicates a mistake. Results shown on LGTM by default. |
2122
| Stored cross-site scripting (`js/stored-xss`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights uncontrolled stored values flowing into HTML content, indicating a violation of [CWE-079](https://cwe.mitre.org/data/definitions/79.html). Results shown on LGTM by default. |
2223
| Unclear precedence of nested operators (`js/unclear-operator-precedence`) | maintainability, correctness, external/cwe/cwe-783 | Highlights nested binary operators whose relative precedence is easy to misunderstand. Results shown on LGTM by default. |
24+
| User-controlled data in file | security, external/cwe/cwe-912 | Highlights locations where user-controlled data is written to a file. Results are not shown on LGTM by default. |
2325

2426
## Changes to existing queries
2527

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
2-
* @name File Access data flows to Http POST/PUT
3-
* @description Writing data from file directly to http body or request header can be an indication to data exfiltration or unauthorized information disclosure.
2+
* @name File data in outbound network request
3+
* @description Directly sending file data in an outbound network request can indicate unauthorized information disclosure.
44
* @kind problem
55
* @problem.severity warning
66
* @id js/file-access-to-http
@@ -11,6 +11,6 @@
1111
import javascript
1212
import semmle.javascript.security.dataflow.FileAccessToHttp
1313

14-
from FileAccessToHttpDataFlow::Configuration config, DataFlow::Node src, DataFlow::Node sink
14+
from FileAccessToHttp::Configuration config, DataFlow::Node src, DataFlow::Node sink
1515
where config.hasFlow (src, sink)
16-
select src, "$@ flows directly to Http request body", sink, "File access"
16+
select sink, "$@ flows directly to outbound network request", src, "File data"
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
2-
* @name Http response data flows to File Access
3-
* @description Writing data from an HTTP request directly to the file system allows arbitrary file upload and might indicate a backdoor.
2+
* @name User-controlled data written to file
3+
* @description Writing user-controlled data directly to the file system allows arbitrary file upload and might indicate a backdoor.
44
* @kind problem
55
* @problem.severity warning
66
* @id js/http-to-file-access
@@ -11,6 +11,6 @@
1111
import javascript
1212
import semmle.javascript.security.dataflow.HttpToFileAccess
1313

14-
from HttpToFileAccessFlow::Configuration configuration, DataFlow::Node src, DataFlow::Node sink
14+
from HttpToFileAccess::Configuration configuration, DataFlow::Node src, DataFlow::Node sink
1515
where configuration.hasFlow(src, sink)
16-
select sink, "$@ flows to file system", src, "Untrusted data received from Http response"
16+
select sink, "$@ flows to file system", src, "Untrusted data"

javascript/ql/src/Security/CWE-918/RequestForgery.qhelp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
<p>
2626

2727
To guard against request forgery, it is advisable to avoid
28-
putting user input directly into a remote request. If a flexible
29-
remote request mechanism is required, it is recommended to maintain a
28+
putting user input directly into a network request. If a flexible
29+
network request mechanism is required, it is recommended to maintain a
3030
list of authorized request targets and choose from that list based on
3131
the user input provided.
3232

javascript/ql/src/Security/CWE-918/RequestForgery.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
2-
* @name Uncontrolled data used in remote request
3-
* @description Sending remote requests with user-controlled data allows for request forgery attacks.
2+
* @name Uncontrolled data used in network request
3+
* @description Sending network requests with user-controlled data allows for request forgery attacks.
44
* @kind problem
55
* @problem.severity error
66
* @precision medium

javascript/ql/src/semmle/javascript/Concepts.qll

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,27 @@ abstract class FileSystemAccess extends DataFlow::Node {
2929
/** Gets an argument to this file system access that is interpreted as a path. */
3030
abstract DataFlow::Node getAPathArgument();
3131

32-
/** Gets a node that represents file system access data, such as buffer the data is copied to. */
33-
abstract DataFlow::Node getDataNode();
3432
}
3533

3634
/**
37-
* A data flow node that performs read file system access.
35+
* A data flow node that reads data from the file system.
3836
*/
39-
abstract class FileSystemReadAccess extends FileSystemAccess { }
37+
abstract class FileSystemReadAccess extends FileSystemAccess {
38+
39+
/** Gets a node that represents data from the file system. */
40+
abstract DataFlow::Node getADataNode();
41+
42+
}
4043

4144
/**
42-
* A data flow node that performs write file system access.
45+
* A data flow node that writes data to the file system.
4346
*/
44-
abstract class FileSystemWriteAccess extends FileSystemAccess { }
47+
abstract class FileSystemWriteAccess extends FileSystemAccess {
48+
49+
/** Gets a node that represents data to be written to the file system. */
50+
abstract DataFlow::Node getADataNode();
51+
52+
}
4553

4654
/**
4755
* A data flow node that contains a file name or an array of file names from the local file system.

javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,31 @@ import javascript
99

1010
/**
1111
* A call that performs a request to a URL.
12+
*
13+
* Example: An HTTP POST request is a client request that sends some
14+
* `data` to a `url`, where both the headers and the body of the request
15+
* contribute to the `data`.
1216
*/
1317
abstract class CustomClientRequest extends DataFlow::InvokeNode {
1418

1519
/**
1620
* Gets the URL of the request.
1721
*/
1822
abstract DataFlow::Node getUrl();
23+
24+
/**
25+
* Gets a node that contributes to the data-part this request.
26+
*/
27+
abstract DataFlow::Node getADataNode();
28+
1929
}
2030

2131
/**
2232
* A call that performs a request to a URL.
33+
*
34+
* Example: An HTTP POST request is client request that sends some
35+
* `data` to a `url`, where both the headers and the body of the request
36+
* contribute to the `data`.
2337
*/
2438
class ClientRequest extends DataFlow::InvokeNode {
2539

@@ -35,6 +49,14 @@ class ClientRequest extends DataFlow::InvokeNode {
3549
DataFlow::Node getUrl() {
3650
result = custom.getUrl()
3751
}
52+
53+
/**
54+
* Gets a node that contributes to the data-part this request.
55+
*/
56+
DataFlow::Node getADataNode() {
57+
result = custom.getADataNode()
58+
}
59+
3860
}
3961

4062
/**
@@ -83,6 +105,10 @@ private class RequestUrlRequest extends CustomClientRequest {
83105
result = url
84106
}
85107

108+
override DataFlow::Node getADataNode() {
109+
result = getArgument(1)
110+
}
111+
86112
}
87113

88114
/**
@@ -113,6 +139,10 @@ private class AxiosUrlRequest extends CustomClientRequest {
113139
result = url
114140
}
115141

142+
override DataFlow::Node getADataNode() {
143+
none()
144+
}
145+
116146
}
117147

118148
/**
@@ -144,6 +174,10 @@ private class FetchUrlRequest extends CustomClientRequest {
144174
result = url
145175
}
146176

177+
override DataFlow::Node getADataNode() {
178+
none()
179+
}
180+
147181
}
148182

149183
/**
@@ -169,6 +203,10 @@ private class GotUrlRequest extends CustomClientRequest {
169203
result = url
170204
}
171205

206+
override DataFlow::Node getADataNode() {
207+
none()
208+
}
209+
172210
}
173211

174212
/**
@@ -191,4 +229,8 @@ private class SuperAgentUrlRequest extends CustomClientRequest {
191229
result = url
192230
}
193231

232+
override DataFlow::Node getADataNode() {
233+
none()
234+
}
235+
194236
}

javascript/ql/src/semmle/javascript/frameworks/Electron.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ module Electron {
6363
result = getOptionArgument(0, "url")
6464
}
6565

66+
override DataFlow::Node getADataNode() {
67+
none()
68+
}
69+
6670
}
6771

6872
/**
@@ -78,6 +82,10 @@ module Electron {
7882
result = getOptionArgument(0, "url")
7983
}
8084

85+
override DataFlow::Node getADataNode() {
86+
none()
87+
}
88+
8189
}
8290

8391

javascript/ql/src/semmle/javascript/frameworks/Express.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -824,16 +824,16 @@ module Express {
824824
}
825825

826826
/** A call to `response.sendFile`, considered as a file system access. */
827-
private class ResponseSendFileAsFileSystemAccess extends FileSystemAccess, DataFlow::ValueNode {
827+
private class ResponseSendFileAsFileSystemAccess extends FileSystemReadAccess, DataFlow::ValueNode {
828828
override MethodCallExpr astNode;
829829

830830
ResponseSendFileAsFileSystemAccess() {
831831
exists (string name | name = "sendFile" or name = "sendfile" |
832832
asExpr().(MethodCallExpr).calls(any(ResponseExpr res), name))
833833
}
834834

835-
override DataFlow::Node getDataNode() {
836-
result = DataFlow::valueNode(astNode)
835+
override DataFlow::Node getADataNode() {
836+
none()
837837
}
838838

839839
override DataFlow::Node getAPathArgument() {

javascript/ql/src/semmle/javascript/frameworks/HTTP.qll

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,6 @@ module HTTP {
132132
result = "http" or result = "https"
133133
}
134134

135-
/**
136-
* An expression whose value is sent as (part of) the body of an HTTP request (POST, PUT).
137-
*/
138-
abstract class RequestBody extends DataFlow::Node {}
139-
140135
/**
141136
* An expression whose value is sent as (part of) the body of an HTTP response.
142137
*/

0 commit comments

Comments
 (0)