JavaScript: Recognise JSON.stringify and JSON.parse as escaper/unescaper.

This commit is contained in:
Max Schaefer
2019-10-30 09:35:49 +00:00
parent 63f24476e9
commit bd1c99d8a4
3 changed files with 68 additions and 0 deletions

View File

@@ -167,6 +167,52 @@ class GlobalStringReplacement extends Replacement, DataFlow::MethodCallNode {
}
}
/**
* A call to `JSON.stringify`, viewed as a string replacement.
*/
class JsonStringifyReplacement extends Replacement, DataFlow::CallNode {
JsonStringifyReplacement() {
this = DataFlow::globalVarRef("JSON").getAMemberCall("stringify")
}
override predicate replaces(string input, string output) {
input = "\\" and output = "\\\\"
// the other replacements are not relevant for this query
}
override DataFlow::Node getInput() {
result = this.getArgument(0)
}
override DataFlow::SourceNode getOutput() {
result = this
}
}
/**
* A call to `JSON.parse`, viewed as a string replacement.
*/
class JsonParseReplacement extends Replacement {
JsonParserCall self;
JsonParseReplacement() {
this = self
}
override predicate replaces(string input, string output) {
input = "\\\\" and output = "\\"
// the other replacements are not relevant for this query
}
override DataFlow::Node getInput() {
result = self.getInput()
}
override DataFlow::SourceNode getOutput() {
result = self.getOutput()
}
}
from Replacement primary, Replacement supplementary, string message, string metachar
where
primary.escapes(metachar, _) and

View File

@@ -5,3 +5,5 @@
| tst.js:53:10:53:33 | s.repla ... , '\\\\') | This replacement may produce '\\' characters that are double-unescaped $@. | tst.js:53:10:54:33 | s.repla ... , '\\'') | here |
| tst.js:60:7:60:28 | s.repla ... '%25') | This replacement may double-escape '%' characters from $@. | tst.js:59:7:59:28 | s.repla ... '%26') | here |
| tst.js:68:10:70:38 | s.repla ... &") | This replacement may double-escape '&' characters from $@. | tst.js:68:10:69:39 | s.repla ... apos;") | here |
| tst.js:74:10:77:10 | JSON.st ... ) | This replacement may double-escape '\\' characters from $@. | tst.js:75:12:76:37 | s.repla ... u003E") | here |
| tst.js:86:10:86:22 | JSON.parse(s) | This replacement may produce '\\' characters that are double-unescaped $@. | tst.js:86:10:86:47 | JSON.pa ... g, "<") | here |

View File

@@ -69,3 +69,23 @@ function badEncode(s) {
.replace(indirect2, "&apos;")
.replace(indirect3, "&amp;");
}
function badEscape1(s) {
return JSON.stringify(
s.replace(/</g, "\\u003C")
.replace(/>/g, "\\u003E")
);
}
function goodEscape1(s) {
return JSON.stringify(s)
.replace(/</g, "\\u003C").replace(/>/g, "\\u003E");
}
function badUnescape2(s) {
return JSON.parse(s).replace(/\\u003C/g, "<").replace(/\\u003E/g, ">");
}
function goodUnescape2(s) {
return JSON.parse(s.replace(/\\u003C/g, "<").replace(/\\u003E/g, ">"));
}