Skip to content

Commit 45b207c

Browse files
author
Esben Sparre Andreasen
committed
JS: introduce models of three cookie libraries
1 parent 28b4a78 commit 45b207c

File tree

9 files changed

+134
-0
lines changed

9 files changed

+134
-0
lines changed

javascript/ql/src/javascript.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import semmle.javascript.frameworks.Azure
6060
import semmle.javascript.frameworks.Babel
6161
import semmle.javascript.frameworks.ComposedFunctions
6262
import semmle.javascript.frameworks.ClientRequests
63+
import semmle.javascript.frameworks.CookieLibraries
6364
import semmle.javascript.frameworks.Credentials
6465
import semmle.javascript.frameworks.CryptoLibraries
6566
import semmle.javascript.frameworks.DigitalOcean
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
2+
/**
3+
* Provides classes for reasoning about cookies.
4+
*/
5+
6+
import javascript
7+
8+
/**
9+
* A model of the `js-cookie` library (https://github.com/js-cookie/js-cookie).
10+
*/
11+
private module JsCookie {
12+
/**
13+
* Gets a function call that invokes method `name` of the `js-cookie` library.
14+
*/
15+
DataFlow::CallNode libMemberCall(string name) {
16+
result = DataFlow::globalVarRef("Cookie").getAMemberCall(name) or
17+
result = DataFlow::globalVarRef("Cookie").getAMemberCall("noConflict").getAMemberCall(name) or
18+
result = DataFlow::moduleMember("js-cookie", name).getACall()
19+
}
20+
21+
class ReadAccess extends PersistentReadAccess, DataFlow::CallNode {
22+
ReadAccess() { this = libMemberCall("get") }
23+
24+
override PersistentWriteAccess getAWrite() {
25+
getArgument(0).mayHaveStringValue(result.(WriteAccess).getKey())
26+
}
27+
}
28+
29+
class WriteAccess extends PersistentWriteAccess, DataFlow::CallNode {
30+
WriteAccess() { this = libMemberCall("set") }
31+
32+
string getKey() { getArgument(0).mayHaveStringValue(result) }
33+
34+
override DataFlow::Node getValue() { result = getArgument(1) }
35+
}
36+
}
37+
38+
/**
39+
* A model of the `browser-cookies` library (https://github.com/voltace/browser-cookies).
40+
*/
41+
private module BrowserCookies {
42+
/**
43+
* Gets a function call that invokes method `name` of the `browser-cookies` library.
44+
*/
45+
DataFlow::CallNode libMemberCall(string name) {
46+
result = DataFlow::moduleMember("browser-cookies", name).getACall()
47+
}
48+
49+
class ReadAccess extends PersistentReadAccess, DataFlow::CallNode {
50+
ReadAccess() { this = libMemberCall("get") }
51+
52+
override PersistentWriteAccess getAWrite() {
53+
getArgument(0).mayHaveStringValue(result.(WriteAccess).getKey())
54+
}
55+
}
56+
57+
class WriteAccess extends PersistentWriteAccess, DataFlow::CallNode {
58+
WriteAccess() { this = libMemberCall("set") }
59+
60+
string getKey() { getArgument(0).mayHaveStringValue(result) }
61+
62+
override DataFlow::Node getValue() { result = getArgument(1) }
63+
}
64+
}
65+
66+
/**
67+
* A model of the `cookie` library (https://github.com/jshttp/cookie).
68+
*/
69+
private module LibCookie {
70+
/**
71+
* Gets a function call that invokes method `name` of the `cookie` library.
72+
*/
73+
DataFlow::CallNode libMemberCall(string name) {
74+
result = DataFlow::moduleMember("cookie", name).getACall()
75+
}
76+
77+
class ReadAccess extends PersistentReadAccess {
78+
string key;
79+
ReadAccess() { this = libMemberCall("parse").getAPropertyRead(key) }
80+
81+
override PersistentWriteAccess getAWrite() {
82+
key = result.(WriteAccess).getKey()
83+
}
84+
}
85+
86+
class WriteAccess extends PersistentWriteAccess, DataFlow::CallNode {
87+
WriteAccess() { this = libMemberCall("serialize") }
88+
89+
string getKey() { getArgument(0).mayHaveStringValue(result) }
90+
91+
override DataFlow::Node getValue() { result = getArgument(1) }
92+
}
93+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| tst.js:7:2:7:21 | js_cookie.get('key') |
2+
| tst.js:12:2:12:27 | browser ... ('key') |
3+
| tst.js:18:2:18:22 | cookie. ... ['key'] |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from PersistentReadAccess read
4+
select read
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| tst.js:7:2:7:21 | js_cookie.get('key') | tst.js:6:2:6:30 | js_cook ... value') |
2+
| tst.js:12:2:12:27 | browser ... ('key') | tst.js:11:2:11:36 | browser ... value') |
3+
| tst.js:18:2:18:22 | cookie. ... ['key'] | tst.js:17:2:17:33 | cookie. ... value') |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from PersistentReadAccess read
4+
select read, read.getAWrite()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| tst.js:6:2:6:30 | js_cook ... value') | tst.js:6:23:6:29 | 'value' |
2+
| tst.js:11:2:11:36 | browser ... value') | tst.js:11:29:11:35 | 'value' |
3+
| tst.js:17:2:17:33 | cookie. ... value') | tst.js:17:26:17:32 | 'value' |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from PersistentWriteAccess write
4+
select write, write.getValue()
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const js_cookie = require('js-cookie'),
2+
browser_cookies = require('browser-cookies'),
3+
cookie = require('cookie');
4+
5+
(function() {
6+
js_cookie.set('key', 'value');
7+
js_cookie.get('key');
8+
});
9+
10+
(function() {
11+
browser_cookies.set('key', 'value');
12+
browser_cookies.get('key');
13+
});
14+
15+
16+
(function() {
17+
cookie.serialize('key', 'value');
18+
cookie.parse()['key'];
19+
});

0 commit comments

Comments
 (0)