Skip to content

Commit 1da828f

Browse files
authored
Merge pull request #1195 from esben-semmle/js/firebase-express-requests
Approved by xiemaisi
2 parents 5379c6e + f23a5a5 commit 1da828f

File tree

9 files changed

+52
-0
lines changed

9 files changed

+52
-0
lines changed

change-notes/1.21/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Support for the following frameworks and libraries has been improved:
66
- [koa](https://github.com/koajs/koa)
77
- [socket.io](http://socket.io)
8+
- [Firebase](https://firebase.google.com/)
89

910
* The security queries now track data flow through Base64 decoders such as the Node.js `Buffer` class, the DOM function `atob`, and a number of npm packages intcluding [`abab`](https://www.npmjs.com/package/abab), [`atob`](https://www.npmjs.com/package/atob), [`btoa`](https://www.npmjs.com/package/btoa), [`base-64`](https://www.npmjs.com/package/base-64), [`js-base64`](https://www.npmjs.com/package/js-base64), [`Base64.js`](https://www.npmjs.com/package/Base64) and [`base64-js`](https://www.npmjs.com/package/base64-js).
1011

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,40 @@ module Firebase {
215215
result = getArgument(0)
216216
}
217217
}
218+
219+
/**
220+
* A call to a Firebase method that sets up a route.
221+
*/
222+
private class RouteSetup extends HTTP::Servers::StandardRouteSetup, CallExpr {
223+
RouteSetup() { this = namespace().getAPropertyRead("https").getAMemberCall("onRequest").asExpr() }
224+
225+
override DataFlow::SourceNode getARouteHandler() {
226+
result = getARouteHandler(DataFlow::TypeBackTracker::end())
227+
}
228+
229+
private DataFlow::SourceNode getARouteHandler(DataFlow::TypeBackTracker t) {
230+
t.start() and
231+
result = getArgument(0).flow().getALocalSource()
232+
or
233+
exists(DataFlow::TypeBackTracker t2 | result = getARouteHandler(t2).backtrack(t2, t))
234+
}
235+
236+
override Expr getServer() { none() }
237+
}
238+
239+
/**
240+
* A function used as a route handler.
241+
*/
242+
private class RouteHandler extends Express::RouteHandler, HTTP::Servers::StandardRouteHandler,
243+
DataFlow::ValueNode {
244+
RouteHandler() { this = any(RouteSetup setup).getARouteHandler() }
245+
246+
override SimpleParameter getRouteHandlerParameter(string kind) {
247+
kind = "request" and result = this.(DataFlow::FunctionNode).getParameter(0).getParameter() or
248+
kind = "response" and result = this.(DataFlow::FunctionNode).getParameter(1).getParameter()
249+
}
250+
}
251+
218252
}
219253

220254
/**
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| tst.js:72:52:72:65 | req.params.foo |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from HTTP::RequestInputAccess ria
4+
select ria
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| tst.js:72:52:72:65 | req.params.foo |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from HTTP::ResponseSendArgument send
4+
select send
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| tst.js:72:27:72:69 | (req, r ... foo); } |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from HTTP::RouteHandler rh
4+
select rh

javascript/ql/test/library-tests/frameworks/Firebase/tst.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,5 @@ class Box {
6868
let box1 = new Box(fb.database());
6969
let box2 = new Box(whatever());
7070
box2.x.ref(); // not a firebase ref
71+
72+
functions.https.onRequest((req, res) => { res.send(req.params.foo); });

0 commit comments

Comments
 (0)