JS: Some fixes and address review comments

This commit is contained in:
Asger Feldthaus
2020-11-02 10:46:30 +00:00
parent 8a3fba05e9
commit 790526b529
2 changed files with 66 additions and 52 deletions

View File

@@ -1,61 +1,75 @@
/** Provides taint steps modeling flow through date-manipulation libraries. */
private import javascript
private API::Node formatFunction() {
result = API::moduleImport(["date-fns", "date-fns/utc"]).getMember(["format", "lightFormat"])
or
result =
API::moduleImport(["date-fns/format", "date-fns/lightFormat", "date-fns/utc/format",
"date-fns/utc/lightFormat"])
}
private module DateFns {
private API::Node formatFunction() {
result = API::moduleImport(["date-fns", "date-fns/esm"]).getMember(["format", "lightFormat"])
or
result =
API::moduleImport(["date-fns/format", "date-fns/lightFormat", "date-fns/esm/format",
"date-fns/esm/lightFormat"])
}
private API::Node formatFunctionCurried() {
result =
API::moduleImport(["date-fns/fp", "date-fns/fp/utc"]).getMember(["format", "lightFormat"])
or
result =
API::moduleImport(["date-fns/fp/format", "date-fns/fp/lightFormat", "date-fns/fp/utc/format",
"date-fns/fp/utc/lightFormat"])
}
private API::Node curriedFormatFunction() {
result =
API::moduleImport(["date-fns/fp", "date-fns/esm/fp"]).getMember(["format", "lightFormat"])
or
result =
API::moduleImport(["date-fns/fp/format", "date-fns/fp/lightFormat", "date-fns/esm/fp/format",
"date-fns/esm/fp/lightFormat"])
}
/**
* Taint step of form: `f -> format(date, f)`
*
* A format string can use single-quotes to include mostly arbitrary text.
*/
private class DateFnsFormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
DateFnsFormatStep() { this = formatFunction().getACall() }
/**
* Taint step of form: `f -> format(date, f)`
*
* A format string can use single-quotes to include mostly arbitrary text.
*/
private class FormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
FormatStep() { this = formatFunction().getACall() }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(1) and
succ = this
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(1) and
succ = this
}
}
/**
* Taint step of form: `f -> format(f)(date)`
*/
private class CurriedFormatStep extends TaintTracking::AdditionalTaintStep,
DataFlow::CallNode {
CurriedFormatStep() { this = curriedFormatFunction().getACall() }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(0) and
succ = getACall()
}
}
}
/**
* Taint step of form: `f -> format(f)(date)`
*/
private class DateFnsCurriedFormatStep extends TaintTracking::AdditionalTaintStep,
DataFlow::CallNode {
DateFnsCurriedFormatStep() { this = formatFunctionCurried().getACall() }
private module Moment {
/** Gets a reference to a `moment` object. */
private API::Node moment() {
result = API::moduleImport("moment")
or
result = moment().getReturn()
or
result = moment().getAMember()
}
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(0) and
succ = getACall()
}
}
/**
* Taint step of form: `f -> momentObj.format(f)`
*
* The format string can use backslash-escaping to include mostly arbitrary text.
*/
private class MomentFormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
MomentFormatStep() {
this = API::moduleImport("moment").getASuccessor*().getMember("format").getACall()
}
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(0) and
succ = this
/**
* Taint step of form: `f -> momentObj.format(f)`
*
* The format string can use backslash-escaping to include mostly arbitrary text.
*/
private class MomentFormatStep extends TaintTracking::AdditionalTaintStep, DataFlow::CallNode {
MomentFormatStep() {
this = moment().getMember("format").getACall()
}
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(0) and
succ = this
}
}
}

View File

@@ -1,6 +1,6 @@
import dateFns from 'date-fns';
import dateFnsFp from 'date-fns/fp';
import dateFnsUtc from 'date-fns/utc';
import dateFnsEsm from 'date-fns/esm';
import moment from 'moment';
function main() {
@@ -8,7 +8,7 @@ function main() {
let taint = decodeURIComponent(window.location.hash.substring(1));
document.body.innerHTML = `Time is ${dateFns.format(time, taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFnsUtc.format(time, taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFnsEsm.format(time, taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFnsFp.format(taint)(time)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFns.format(taint, time)}`; // OK - time arg is safe
document.body.innerHTML = `Time is ${dateFnsFp.format(time)(taint)}`; // OK - time arg is safe