Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8a3fba0

Browse files
committed
JS: Add steps through date-formatting functions
1 parent cb77e46 commit 8a3fba0

3 files changed

Lines changed: 79 additions & 0 deletions

File tree

javascript/ql/src/javascript.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ import semmle.javascript.frameworks.ClosureLibrary
7979
import semmle.javascript.frameworks.CookieLibraries
8080
import semmle.javascript.frameworks.Credentials
8181
import semmle.javascript.frameworks.CryptoLibraries
82+
import semmle.javascript.frameworks.DateFunctions
8283
import semmle.javascript.frameworks.DigitalOcean
8384
import semmle.javascript.frameworks.Electron
8485
import semmle.javascript.frameworks.EventEmitter
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
private import javascript
2+
3+
private API::Node formatFunction() {
4+
result = API::moduleImport(["date-fns", "date-fns/utc"]).getMember(["format", "lightFormat"])
5+
or
6+
result =
7+
API::moduleImport(["date-fns/format", "date-fns/lightFormat", "date-fns/utc/format",
8+
"date-fns/utc/lightFormat"])
9+
}
10+
11+
private API::Node formatFunctionCurried() {
12+
result =
13+
API::moduleImport(["date-fns/fp", "date-fns/fp/utc"]).getMember(["format", "lightFormat"])
14+
or
15+
result =
16+
API::moduleImport(["date-fns/fp/format", "date-fns/fp/lightFormat", "date-fns/fp/utc/format",
17+
"date-fns/fp/utc/lightFormat"])
18+
}
19+
20+
/**
21+
* Taint step of form: `f -> format(date, f)`
22+
*
23+
* A format string can use single-quotes to include mostly arbitrary text.
24+
*/
25+
private class DateFnsFormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
26+
DateFnsFormatStep() { this = formatFunction().getACall() }
27+
28+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
29+
pred = getArgument(1) and
30+
succ = this
31+
}
32+
}
33+
34+
/**
35+
* Taint step of form: `f -> format(f)(date)`
36+
*/
37+
private class DateFnsCurriedFormatStep extends TaintTracking::AdditionalTaintStep,
38+
DataFlow::CallNode {
39+
DateFnsCurriedFormatStep() { this = formatFunctionCurried().getACall() }
40+
41+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
42+
pred = getArgument(0) and
43+
succ = getACall()
44+
}
45+
}
46+
47+
/**
48+
* Taint step of form: `f -> momentObj.format(f)`
49+
*
50+
* The format string can use backslash-escaping to include mostly arbitrary text.
51+
*/
52+
private class MomentFormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
53+
MomentFormatStep() {
54+
this = API::moduleImport("moment").getASuccessor*().getMember("format").getACall()
55+
}
56+
57+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
58+
pred = getArgument(0) and
59+
succ = this
60+
}
61+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import dateFns from 'date-fns';
2+
import dateFnsFp from 'date-fns/fp';
3+
import dateFnsUtc from 'date-fns/utc';
4+
import moment from 'moment';
5+
6+
function main() {
7+
let time = new Date();
8+
let taint = decodeURIComponent(window.location.hash.substring(1));
9+
10+
document.body.innerHTML = `Time is ${dateFns.format(time, taint)}`; // NOT OK
11+
document.body.innerHTML = `Time is ${dateFnsUtc.format(time, taint)}`; // NOT OK
12+
document.body.innerHTML = `Time is ${dateFnsFp.format(taint)(time)}`; // NOT OK
13+
document.body.innerHTML = `Time is ${dateFns.format(taint, time)}`; // OK - time arg is safe
14+
document.body.innerHTML = `Time is ${dateFnsFp.format(time)(taint)}`; // OK - time arg is safe
15+
document.body.innerHTML = `Time is ${moment(time).format(taint)}`; // NOT OK
16+
document.body.innerHTML = `Time is ${moment(taint).format()}`; // OK
17+
}

0 commit comments

Comments
 (0)