Merge pull request #3876 from erik-krogh/CWE078-Correctness

Approved by esbena
This commit is contained in:
CodeQL CI
2020-08-03 15:38:51 +01:00
committed by GitHub
57 changed files with 1693 additions and 1661 deletions

View File

@@ -29,30 +29,32 @@ nodes
| child_process-test.js:39:26:39:28 | cmd |
| child_process-test.js:43:15:43:17 | cmd |
| child_process-test.js:43:15:43:17 | cmd |
| child_process-test.js:50:15:50:17 | cmd |
| child_process-test.js:50:15:50:17 | cmd |
| child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
| child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
| child_process-test.js:53:46:53:57 | ["bar", cmd] |
| child_process-test.js:53:46:53:57 | ["bar", cmd] |
| child_process-test.js:53:54:53:56 | cmd |
| child_process-test.js:53:54:53:56 | cmd |
| child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
| child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
| child_process-test.js:54:46:54:48 | cmd |
| child_process-test.js:70:9:70:49 | cmd |
| child_process-test.js:70:15:70:38 | url.par ... , true) |
| child_process-test.js:70:15:70:44 | url.par ... ).query |
| child_process-test.js:70:15:70:49 | url.par ... ry.path |
| child_process-test.js:70:25:70:31 | req.url |
| child_process-test.js:70:25:70:31 | req.url |
| child_process-test.js:72:29:72:31 | cmd |
| child_process-test.js:72:29:72:31 | cmd |
| child_process-test.js:80:19:80:36 | req.query.fileName |
| child_process-test.js:80:19:80:36 | req.query.fileName |
| child_process-test.js:80:19:80:36 | req.query.fileName |
| child_process-test.js:82:37:82:54 | req.query.fileName |
| child_process-test.js:82:37:82:54 | req.query.fileName |
| child_process-test.js:48:15:48:17 | cmd |
| child_process-test.js:48:15:48:17 | cmd |
| child_process-test.js:53:15:53:17 | cmd |
| child_process-test.js:53:15:53:17 | cmd |
| child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) |
| child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) |
| child_process-test.js:56:46:56:57 | ["bar", cmd] |
| child_process-test.js:56:46:56:57 | ["bar", cmd] |
| child_process-test.js:56:54:56:56 | cmd |
| child_process-test.js:56:54:56:56 | cmd |
| child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) |
| child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) |
| child_process-test.js:57:46:57:48 | cmd |
| child_process-test.js:73:9:73:49 | cmd |
| child_process-test.js:73:15:73:38 | url.par ... , true) |
| child_process-test.js:73:15:73:44 | url.par ... ).query |
| child_process-test.js:73:15:73:49 | url.par ... ry.path |
| child_process-test.js:73:25:73:31 | req.url |
| child_process-test.js:73:25:73:31 | req.url |
| child_process-test.js:75:29:75:31 | cmd |
| child_process-test.js:75:29:75:31 | cmd |
| child_process-test.js:83:19:83:36 | req.query.fileName |
| child_process-test.js:83:19:83:36 | req.query.fileName |
| child_process-test.js:83:19:83:36 | req.query.fileName |
| child_process-test.js:85:37:85:54 | req.query.fileName |
| child_process-test.js:85:37:85:54 | req.query.fileName |
| execSeries.js:3:20:3:22 | arr |
| execSeries.js:6:14:6:16 | arr |
| execSeries.js:6:14:6:21 | arr[i++] |
@@ -139,11 +141,13 @@ edges
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:39:26:39:28 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:50:15:50:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:50:15:50:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:54:53:56 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:54:53:56 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:54:46:54:48 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:48:15:48:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:48:15:48:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:15:53:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:15:53:17 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:56:54:56:56 | cmd |
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:57:46:57:48 | cmd |
| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:44 | url.par ... ).query |
| child_process-test.js:6:15:6:44 | url.par ... ).query | child_process-test.js:6:15:6:49 | url.par ... ry.path |
| child_process-test.js:6:15:6:44 | url.par ... ).query | child_process-test.js:6:15:6:49 | url.par ... ry.path |
@@ -154,22 +158,22 @@ edges
| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" |
| child_process-test.js:39:26:39:28 | cmd | child_process-test.js:39:18:39:30 | [ flag, cmd ] |
| child_process-test.js:39:26:39:28 | cmd | child_process-test.js:39:18:39:30 | [ flag, cmd ] |
| child_process-test.js:53:46:53:57 | ["bar", cmd] | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
| child_process-test.js:53:46:53:57 | ["bar", cmd] | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
| child_process-test.js:53:54:53:56 | cmd | child_process-test.js:53:46:53:57 | ["bar", cmd] |
| child_process-test.js:53:54:53:56 | cmd | child_process-test.js:53:46:53:57 | ["bar", cmd] |
| child_process-test.js:54:46:54:48 | cmd | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
| child_process-test.js:54:46:54:48 | cmd | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
| child_process-test.js:70:9:70:49 | cmd | child_process-test.js:72:29:72:31 | cmd |
| child_process-test.js:70:9:70:49 | cmd | child_process-test.js:72:29:72:31 | cmd |
| child_process-test.js:70:15:70:38 | url.par ... , true) | child_process-test.js:70:15:70:44 | url.par ... ).query |
| child_process-test.js:70:15:70:44 | url.par ... ).query | child_process-test.js:70:15:70:49 | url.par ... ry.path |
| child_process-test.js:70:15:70:49 | url.par ... ry.path | child_process-test.js:70:9:70:49 | cmd |
| child_process-test.js:70:25:70:31 | req.url | child_process-test.js:70:15:70:38 | url.par ... , true) |
| child_process-test.js:70:25:70:31 | req.url | child_process-test.js:70:15:70:38 | url.par ... , true) |
| child_process-test.js:80:19:80:36 | req.query.fileName | child_process-test.js:80:19:80:36 | req.query.fileName |
| child_process-test.js:82:37:82:54 | req.query.fileName | lib/subLib/index.js:7:32:7:35 | name |
| child_process-test.js:82:37:82:54 | req.query.fileName | lib/subLib/index.js:7:32:7:35 | name |
| child_process-test.js:56:46:56:57 | ["bar", cmd] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) |
| child_process-test.js:56:46:56:57 | ["bar", cmd] | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) |
| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] |
| child_process-test.js:56:54:56:56 | cmd | child_process-test.js:56:46:56:57 | ["bar", cmd] |
| child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) |
| child_process-test.js:57:46:57:48 | cmd | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) |
| child_process-test.js:73:9:73:49 | cmd | child_process-test.js:75:29:75:31 | cmd |
| child_process-test.js:73:9:73:49 | cmd | child_process-test.js:75:29:75:31 | cmd |
| child_process-test.js:73:15:73:38 | url.par ... , true) | child_process-test.js:73:15:73:44 | url.par ... ).query |
| child_process-test.js:73:15:73:44 | url.par ... ).query | child_process-test.js:73:15:73:49 | url.par ... ry.path |
| child_process-test.js:73:15:73:49 | url.par ... ry.path | child_process-test.js:73:9:73:49 | cmd |
| child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) |
| child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) |
| child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName |
| child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib/index.js:7:32:7:35 | name |
| child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib/index.js:7:32:7:35 | name |
| execSeries.js:3:20:3:22 | arr | execSeries.js:6:14:6:16 | arr |
| execSeries.js:6:14:6:16 | arr | execSeries.js:6:14:6:21 | arr[i++] |
| execSeries.js:6:14:6:21 | arr[i++] | execSeries.js:14:24:14:30 | command |
@@ -246,18 +250,18 @@ edges
| child_process-test.js:39:5:39:31 | cp.spaw ... cmd ]) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:39:18:39:30 | [ flag, cmd ] | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:39:5:39:31 | cp.spaw ... cmd ]) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:39:26:39:28 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:44:5:44:34 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:43:15:43:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:51:5:51:39 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:50:15:50:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:46:53:57 | ["bar", cmd] | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:54:53:56 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:54:5:54:50 | cp.spaw ... t(cmd)) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:49 | url.par ... ry.path | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:54:5:54:50 | cp.spaw ... t(cmd)) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:59:5:59:39 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:50:15:50:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:64:3:64:21 | cp.spawn(cmd, args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:43:15:43:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:72:29:72:31 | cmd | child_process-test.js:70:25:70:31 | req.url | child_process-test.js:72:29:72:31 | cmd | This command depends on $@. | child_process-test.js:70:25:70:31 | req.url | a user-provided value |
| child_process-test.js:80:19:80:36 | req.query.fileName | child_process-test.js:80:19:80:36 | req.query.fileName | child_process-test.js:80:19:80:36 | req.query.fileName | This command depends on $@. | child_process-test.js:80:19:80:36 | req.query.fileName | a user-provided value |
| child_process-test.js:54:5:54:39 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:15:53:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:56:5:56:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:56:5:56:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:56:46:56:57 | ["bar", cmd] | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:56:5:56:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:56:54:56:56 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:57:5:57:50 | cp.spaw ... t(cmd)) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:49 | url.par ... ry.path | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:57:5:57:50 | cp.spaw ... t(cmd)) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:62:5:62:39 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:15:53:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:67:3:67:21 | cp.spawn(cmd, args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:48:15:48:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
| child_process-test.js:75:29:75:31 | cmd | child_process-test.js:73:25:73:31 | req.url | child_process-test.js:75:29:75:31 | cmd | This command depends on $@. | child_process-test.js:73:25:73:31 | req.url | a user-provided value |
| child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | This command depends on $@. | child_process-test.js:83:19:83:36 | req.query.fileName | a user-provided value |
| execSeries.js:14:41:14:47 | command | execSeries.js:18:34:18:40 | req.url | execSeries.js:14:41:14:47 | command | This command depends on $@. | execSeries.js:18:34:18:40 | req.url | a user-provided value |
| lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | child_process-test.js:82:37:82:54 | req.query.fileName | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | This command depends on $@. | child_process-test.js:82:37:82:54 | req.query.fileName | a user-provided value |
| lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | This command depends on $@. | child_process-test.js:85:37:85:54 | req.query.fileName | a user-provided value |
| other.js:7:33:7:35 | cmd | other.js:5:25:5:31 | req.url | other.js:7:33:7:35 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value |
| other.js:8:28:8:30 | cmd | other.js:5:25:5:31 | req.url | other.js:8:28:8:30 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value |
| other.js:9:32:9:34 | cmd | other.js:5:25:5:31 | req.url | other.js:9:32:9:34 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value |

View File

@@ -0,0 +1,22 @@
import javascript
import testUtilities.ConsistencyChecking
import semmle.javascript.security.dataflow.CommandInjection
import semmle.javascript.security.dataflow.IndirectCommandInjection
import semmle.javascript.security.dataflow.ShellCommandInjectionFromEnvironment
import semmle.javascript.security.dataflow.UnsafeShellCommandConstruction
class CommandInjectionConsistency extends ConsistencyConfiguration {
CommandInjectionConsistency() { this = "ComandInjection" }
override File getAFile() { not result.getBaseName() = "uselesscat.js" }
}
import semmle.javascript.security.UselessUseOfCat
class UselessCatConsistency extends ConsistencyConfiguration {
UselessCatConsistency() { this = "Cat" }
override DataFlow::Node getAnAlert() { result instanceof UselessCat }
override File getAFile() { result.getBaseName() = "uselesscat.js" }
}

View File

@@ -91,9 +91,9 @@ syncCommand
| uselesscat.js:158:16:158:46 | cspawn. ... /bar']) |
| uselesscat.js:159:16:159:68 | cspawn. ... tf8' }) |
options
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
| child_process-test.js:54:5:54:50 | cp.spaw ... t(cmd)) | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
| child_process-test.js:64:3:64:21 | cp.spawn(cmd, args) | child_process-test.js:64:17:64:20 | args |
| child_process-test.js:56:5:56:59 | cp.spaw ... cmd])) | child_process-test.js:56:25:56:58 | ['/C', ... , cmd]) |
| child_process-test.js:57:5:57:50 | cp.spaw ... t(cmd)) | child_process-test.js:57:25:57:49 | ['/C', ... at(cmd) |
| child_process-test.js:67:3:67:21 | cp.spawn(cmd, args) | child_process-test.js:67:17:67:20 | args |
| lib/lib.js:152:2:152:23 | cp.spaw ... gs, cb) | lib/lib.js:152:21:152:22 | cb |
| lib/lib.js:159:2:159:23 | cp.spaw ... gs, cb) | lib/lib.js:159:21:159:22 | cb |
| lib/lib.js:163:2:167:2 | cp.spaw ... t' }\\n\\t) | lib/lib.js:166:3:166:22 | { stdio: 'inherit' } |
@@ -115,6 +115,3 @@ options
| uselesscat.js:156:1:156:35 | cspawn( ... tf8' }) | uselesscat.js:156:15:156:34 | { encoding: 'utf8' } |
| uselesscat.js:159:16:159:68 | cspawn. ... tf8' }) | uselesscat.js:159:48:159:67 | { encoding: 'utf8' } |
| uselesscat.js:164:1:164:76 | execmod ... (out)}) | uselesscat.js:164:24:164:41 | {encoding: 'utf8'} |
#select
| False negative | uselesscat.js:54:42:54:69 | // NOT ... lagged] |
| False positive | uselesscat.js:44:37:44:85 | // OK [ ... le read |

View File

@@ -1,22 +1,6 @@
import javascript
import semmle.javascript.security.UselessUseOfCat
from LineComment comment, string msg
where
comment.getFile().getAbsolutePath().regexpMatch(".*/uselesscat.js") and
(
comment.getText().regexpMatch(".*NOT OK.*") and
not any(UselessCat cat).asExpr().getLocation().getStartLine() =
comment.getLocation().getStartLine() and
msg = "False negative"
or
comment.getText().regexpMatch(".* OK.*") and
not comment.getText().regexpMatch(".*NOT OK.*") and
any(UselessCat cat).asExpr().getLocation().getStartLine() = comment.getLocation().getStartLine() and
msg = "False positive"
)
select msg, comment
query string readFile(UselessCat cat) { result = PrettyPrintCatCall::createReadFileCall(cat) }
query SystemCommandExecution syncCommand() { result.isSync() }

View File

@@ -40,15 +40,18 @@ var server = http.createServer(function(req, res) {
let args = [];
args[0] = "-c";
args[1] = cmd;
cp.execFile("/bin/bash", args); // NOT OK
args[1] = cmd; // NOT OK
cp.execFile("/bin/bash", args);
let args = [];
args[0] = "-c";
args[1] = cmd; // NOT OK
run("sh", args);
let args = [];
args[0] = `-` + "c";
args[1] = cmd;
cp.execFile(`/bin` + "/bash", args); // NOT OK
args[1] = cmd; // NOT OK
cp.execFile(`/bin` + "/bash", args);
cp.spawn('cmd.exe', ['/C', 'foo'].concat(["bar", cmd])); // NOT OK
cp.spawn('cmd.exe', ['/C', 'foo'].concat(cmd)); // NOT OK
@@ -56,12 +59,12 @@ var server = http.createServer(function(req, res) {
let myArgs = [];
myArgs.push(`-` + "c");
myArgs.push(cmd);
cp.execFile(`/bin` + "/bash", args); // NOT OK
cp.execFile(`/bin` + "/bash", args); // NOT OK - but no support for `[].push()` for indirect arguments [INCONSISTENCY]
});
function run(cmd, args) {
cp.spawn(cmd, args); // NOT OK
cp.spawn(cmd, args); // OK - the alert happens where `args` is build.
}
var util = require("util")

View File

@@ -16,7 +16,7 @@ var cp = require("child_process");
cp.execSync("cmd.sh " + fewerArgs[0]); // NOT OK
var arg0 = fewerArgs[0];
cp.execSync(arg0); // OK
cp.execSync(arg0); // NOT OK
cp.execSync("cmd.sh " + arg0); // NOT OK
});

View File

@@ -11,10 +11,10 @@ function asyncEach(arr, iterator) {
}
function execEach(commands) {
asyncEach(commands, (command) => exec(command));
asyncEach(commands, (command) => exec(command)); // NOT OK
};
require('http').createServer(function(req, res) {
let cmd = require('url').parse(req.url, true).query.path;
execEach([cmd]); // NOT OK
execEach([cmd]);
});

View File

@@ -51,12 +51,12 @@ module.exports.mz = function (name) {
}
module.exports.flow = function (name) {
var cmd1 = "rm -rf " + name;
cp.exec(cmd1); // NOT OK.
var cmd1 = "rm -rf " + name; // NOT OK.
cp.exec(cmd1);
var cmd2 = "rm -rf " + name;
var cmd2 = "rm -rf " + name; // NOT OK.
function myExec(cmd) {
cp.exec(cmd); // NOT OK.
cp.exec(cmd);
}
myExec(cmd2);
}
@@ -83,8 +83,8 @@ module.exports.arrays = function (name) {
cp.exec("rm -rf " + name); // NOT OK.
var args1 = ["node"];
args1.push(name);
cp.exec(args1.join(" ")); // NOT OK.
args1.push(name); // NOT OK.
cp.exec(args1.join(" "));
cp.exec(["rm -rf", name].join(" ")); // NOT OK.
@@ -146,10 +146,10 @@ function Cla5(name) {
module.exports.cla5 = new Cla5();
module.exports.indirect = function (name) {
let cmd = "rm -rf " + name;
let cmd = "rm -rf " + name; // NOT OK
let sh = "sh";
let args = ["-c", cmd];
cp.spawn(sh, args, cb); // NOT OK
cp.spawn(sh, args, cb);
}
module.exports.indirect2 = function (name) {
@@ -221,7 +221,7 @@ module.exports.blackList2 = function (name) {
process.exit(-1);
}
cp.exec("rm -rf " + name); // OK - but FP due to tracking flow through `process.exit()`.
cp.exec("rm -rf " + name); // OK - but FP due to tracking flow through `process.exit()`. [INCONSISTENCY]
}
module.exports.accessSync = function (name) {
@@ -233,7 +233,7 @@ module.exports.accessSync = function (name) {
return;
}
cp.exec("rm -rf " + name); // OK - but FP due to `path.accessSync` not being recognized as a sanitizer.
cp.exec("rm -rf " + name); // OK - but FP due to `path.accessSync` not being recognized as a sanitizer. [INCONSISTENCY]
}
var cleanInput = function (s) {
@@ -278,7 +278,7 @@ module.exports.Foo = class Foo {
this.opts = {};
this.opts.bla = opts.bla
cp.exec("rm -rf " + this.opts.bla); // NOT OK - but FN
cp.exec("rm -rf " + this.opts.bla); // NOT OK - but FN [INCONSISTENCY]
}
}

View File

@@ -41,7 +41,7 @@ execSync(`cat ${newpath} > ${destpath}`).toString(); // OK.
execSync(`cat ${files.join(' ')} > ${outFile}`); // OK
execSync(`cat ${files.join(' ')}`); // OK [but flagged] - not just a simple file read
execSync(`cat ${files.join(' ')}`); // OK - but flagged - not just a simple file read [INCONSISTENCY]
exec("cat /proc/cpuinfo | grep name"); // OK - pipes
@@ -51,7 +51,7 @@ function cat(file) {
return execSync('cat ' + file).toString(); // NOT OK
}
execSync("sh -c 'cat " + newpath + "'"); // NOT OK. [but not flagged]
execSync("sh -c 'cat " + newpath + "'"); // NOT OK - but not flagged [INCONSISTENCY]
var execFile = child_process.execFile;
var execFileSync = child_process.execFileSync;

View File

@@ -0,0 +1,8 @@
import javascript
import testUtilities.ConsistencyChecking
import semmle.javascript.security.dataflow.DomBasedXss as DomXss
import semmle.javascript.security.dataflow.ReflectedXss as ReflectedXss
import semmle.javascript.security.dataflow.StoredXss as StoredXss
import semmle.javascript.security.dataflow.XssThroughDom as ThroughDomXss
import semmle.javascript.security.dataflow.ExceptionXss as ExceptionXss
import semmle.javascript.security.dataflow.UnsafeJQueryPlugin as UnsafeJqueryPlugin

View File

@@ -86,16 +86,16 @@ nodes
| exception-xss.js:180:26:180:30 | error |
| exception-xss.js:182:19:182:23 | error |
| exception-xss.js:182:19:182:23 | error |
| tst.js:304:9:304:16 | location |
| tst.js:304:9:304:16 | location |
| tst.js:305:10:305:10 | e |
| tst.js:306:20:306:20 | e |
| tst.js:306:20:306:20 | e |
| tst.js:311:10:311:17 | location |
| tst.js:311:10:311:17 | location |
| tst.js:313:10:313:10 | e |
| tst.js:314:20:314:20 | e |
| tst.js:314:20:314:20 | e |
| tst.js:301:9:301:16 | location |
| tst.js:301:9:301:16 | location |
| tst.js:302:10:302:10 | e |
| tst.js:303:20:303:20 | e |
| tst.js:303:20:303:20 | e |
| tst.js:308:10:308:17 | location |
| tst.js:308:10:308:17 | location |
| tst.js:310:10:310:10 | e |
| tst.js:311:20:311:20 | e |
| tst.js:311:20:311:20 | e |
edges
| exception-xss.js:2:6:2:28 | foo | exception-xss.js:9:11:9:13 | foo |
| exception-xss.js:2:6:2:28 | foo | exception-xss.js:15:9:15:11 | foo |
@@ -178,14 +178,14 @@ edges
| exception-xss.js:180:10:180:22 | req.params.id | exception-xss.js:180:26:180:30 | error |
| exception-xss.js:180:26:180:30 | error | exception-xss.js:182:19:182:23 | error |
| exception-xss.js:180:26:180:30 | error | exception-xss.js:182:19:182:23 | error |
| tst.js:304:9:304:16 | location | tst.js:305:10:305:10 | e |
| tst.js:304:9:304:16 | location | tst.js:305:10:305:10 | e |
| tst.js:305:10:305:10 | e | tst.js:306:20:306:20 | e |
| tst.js:305:10:305:10 | e | tst.js:306:20:306:20 | e |
| tst.js:311:10:311:17 | location | tst.js:313:10:313:10 | e |
| tst.js:311:10:311:17 | location | tst.js:313:10:313:10 | e |
| tst.js:313:10:313:10 | e | tst.js:314:20:314:20 | e |
| tst.js:313:10:313:10 | e | tst.js:314:20:314:20 | e |
| tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e |
| tst.js:301:9:301:16 | location | tst.js:302:10:302:10 | e |
| tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e |
| tst.js:302:10:302:10 | e | tst.js:303:20:303:20 | e |
| tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e |
| tst.js:308:10:308:17 | location | tst.js:310:10:310:10 | e |
| tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e |
| tst.js:310:10:310:10 | e | tst.js:311:20:311:20 | e |
#select
| exception-xss.js:11:18:11:18 | e | exception-xss.js:2:12:2:28 | document.location | exception-xss.js:11:18:11:18 | e | $@ is reinterpreted as HTML without escaping meta-characters. | exception-xss.js:2:12:2:28 | document.location | Exception text |
| exception-xss.js:17:18:17:18 | e | exception-xss.js:2:12:2:28 | document.location | exception-xss.js:17:18:17:18 | e | $@ is reinterpreted as HTML without escaping meta-characters. | exception-xss.js:2:12:2:28 | document.location | Exception text |
@@ -203,5 +203,5 @@ edges
| exception-xss.js:155:18:155:18 | e | exception-xss.js:146:12:146:28 | document.location | exception-xss.js:155:18:155:18 | e | $@ is reinterpreted as HTML without escaping meta-characters. | exception-xss.js:146:12:146:28 | document.location | Exception text |
| exception-xss.js:175:18:175:18 | e | exception-xss.js:146:12:146:28 | document.location | exception-xss.js:175:18:175:18 | e | $@ is reinterpreted as HTML without escaping meta-characters. | exception-xss.js:146:12:146:28 | document.location | Exception text |
| exception-xss.js:182:19:182:23 | error | exception-xss.js:180:10:180:22 | req.params.id | exception-xss.js:182:19:182:23 | error | $@ is reinterpreted as HTML without escaping meta-characters. | exception-xss.js:180:10:180:22 | req.params.id | Exception text |
| tst.js:306:20:306:20 | e | tst.js:304:9:304:16 | location | tst.js:306:20:306:20 | e | $@ is reinterpreted as HTML without escaping meta-characters. | tst.js:304:9:304:16 | location | Exception text |
| tst.js:314:20:314:20 | e | tst.js:311:10:311:17 | location | tst.js:314:20:314:20 | e | $@ is reinterpreted as HTML without escaping meta-characters. | tst.js:311:10:311:17 | location | Exception text |
| tst.js:303:20:303:20 | e | tst.js:301:9:301:16 | location | tst.js:303:20:303:20 | e | $@ is reinterpreted as HTML without escaping meta-characters. | tst.js:301:9:301:16 | location | Exception text |
| tst.js:311:20:311:20 | e | tst.js:308:10:308:17 | location | tst.js:311:20:311:20 | e | $@ is reinterpreted as HTML without escaping meta-characters. | tst.js:308:10:308:17 | location | Exception text |

View File

@@ -136,7 +136,7 @@ app.get('/user/:id', function (req, res) {
res.send(escapeHtml1(url)); // OK
res.send(escapeHtml2(url)); // OK
res.send(escapeHtml3(url)); // OK - but FP
res.send(escapeHtml3(url)); // OK - but FP [INCONSISTENCY]
res.send(escapeHtml4(url)); // OK
});

View File

@@ -238,6 +238,6 @@ edges
| unsafe-jquery-plugin.js:127:6:127:19 | options.target | unsafe-jquery-plugin.js:126:33:126:39 | options | unsafe-jquery-plugin.js:127:6:127:19 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:126:14:128:3 | functio ... OK\\n\\t\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:132:5:132:18 | options.target | unsafe-jquery-plugin.js:131:34:131:40 | options | unsafe-jquery-plugin.js:132:5:132:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:131:15:133:2 | functio ... T OK\\n\\t} | '$.fn.affix' plugin |
| unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | unsafe-jquery-plugin.js:135:36:135:42 | options | unsafe-jquery-plugin.js:136:5:136:29 | options ... elector | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:135:17:137:2 | functio ... T OK\\n\\t} | '$.fn.tooltip' plugin |
| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... gged\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | unsafe-jquery-plugin.js:153:38:153:44 | options | unsafe-jquery-plugin.js:157:44:157:59 | options.target.a | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:153:19:158:2 | functio ... NCY]\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:170:6:170:11 | target | unsafe-jquery-plugin.js:160:38:160:44 | options | unsafe-jquery-plugin.js:170:6:170:11 | target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:160:19:173:2 | functio ... \\t\\t}\\n\\n\\t} | '$.fn.my_plugin' plugin |
| unsafe-jquery-plugin.js:179:5:179:18 | options.target | unsafe-jquery-plugin.js:178:27:178:33 | options | unsafe-jquery-plugin.js:179:5:179:18 | options.target | Potential XSS vulnerability in the $@. | unsafe-jquery-plugin.js:178:18:180:2 | functio ... T OK\\n\\t} | '$.fn.my_plugin' plugin |

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,7 @@
try {
unknown({ prop: foo });
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // NOT OK! - but not detected due to not tainting object that have a tainted propety. [INCONSISTENCY]
}
try {
@@ -179,9 +179,9 @@ app.get('/user/:id', function (req, res) {
app.get('/user/:id', function (req, res) {
unknown(req.params.id, (error, res) => {
if (error) {
$('myId').html(error); // OK (falls through to the next statement)
$('myId').html(error); // NOT OK
}
$('myId').html(res); // NOT OK!
$('myId').html(res); // OK - does not contain an error, and `res` is otherwise unknown.
});
});

View File

@@ -49,7 +49,7 @@ app.get("/return", (req, res) => {
let callback = getFirst.bind(null, req.url);
res.send(callback); // OK - the callback itself is not tainted
res.send(callback()); // NOT OK - but not currently detected
res.send(callback()); // NOT OK - but not currently detected [INCONSISTENCY]
res.send(getFirst("Hello")); // OK - argument is not tainted from this call site
});

View File

@@ -16,7 +16,7 @@ function test() {
var tainted = window.name;
var elt = document.createElement();
elt.innerHTML = "<a href=\"" + escapeAttr(tainted) + "\">" + escapeHtml(tainted) + "</a>"; // OK
elt.innerHTML = "<div>" + escapeAttr(tainted) + "</div>"; // NOT OK, but not flagged
elt.innerHTML = "<div>" + escapeAttr(tainted) + "</div>"; // NOT OK, but not flagged - [INCONSISTENCY]
const regex = /[<>'"&]/;
if (regex.test(tainted)) {

View File

@@ -11,17 +11,14 @@ function test() {
// NOT OK
$('<div style="width:' + target + 'px">');
// OK
$('<div style="width:' + +target + 'px">');
$('<div style="width:' + parseInt(target) + 'px">');
$('<div style="width:' + +target + 'px">'); // OK
$('<div style="width:' + parseInt(target) + 'px">'); // OK
// NOT OK
let params = (new URL(document.location)).searchParams;
$('name').html(params.get('name'));
$('name').html(params.get('name')); // NOT OK
// NOT OK
var searchParams = new URLSearchParams(target.substring(1));
$('name').html(searchParams.get('name'));
$('name').html(searchParams.get('name')); // NOT OK
}
function foo(target) {
@@ -331,14 +328,11 @@ function getTaintedUrl() {
}
function URLPseudoProperties() {
// NOT OK
let params = getTaintedUrl().searchParams;
$('name').html(params.get('name'));
$('name').html(params.get('name')); // NOT OK
// OK (.get is not defined on a URL)
let myUrl = getTaintedUrl();
$('name').html(myUrl.get('name'));
$('name').html(myUrl.get('name')); // OK (.get is not defined on a URL)
}

View File

@@ -7,7 +7,7 @@
source: autocompleter.ttAdapter(),
templates: {
suggestion: function(loc) {
return loc; // NOT OK!
return loc; // NOT OK! - but not flagged due to not connecting the Bloodhound source with this sink [INCONSISTENCY]
}
}
})

View File

@@ -65,7 +65,7 @@
$.fn.my_plugin = function my_plugin(element, options) {
this.$element = $(element);
this.options = $.extend({}, options);
if (this.options.parent) this.$parent = $(this.options.parent) // NOT OK
if (this.options.parent) this.$parent = $(this.options.parent) // NOT OK - but not flagged [INCONSISTENCY]
};
$.fn.my_plugin = function my_plugin(options) {
@@ -103,7 +103,7 @@
menu: '<div></div>',
target: '.my_plugin'
}, options);
$(options.menu); // OK
$(options.menu); // OK - but is flagged [INCONSISTENCY]
$(options.target); // NOT OK
};
@@ -113,7 +113,7 @@
};
$.fn.my_plugin = function my_plugin(options) {
options = $.extend({}, $.fn.my_plugin.defaults, options);
$(options.menu); // OK
$(options.menu); // OK - but is flagged [INCONSISTENCY]
$(options.target); // NOT OK
};
@@ -152,9 +152,9 @@
$.fn.my_plugin = function my_plugin(options) {
let target = options.target;
target === DEFAULTS.target? $(target): $(document).find(target); // NOT OK
options.target === DEFAULTS.target? $(options.target): $(document).find(options.target); // NOT OK
options.targets.a === DEFAULTS.target? $(options.target.a): $(document).find(options.target.a); // OK - but still flagged
target === DEFAULTS.target? $(target): $(document).find(target); // OK
options.target === DEFAULTS.target? $(options.target): $(document).find(options.target); // OK
options.targets.a === DEFAULTS.target? $(options.target.a): $(document).find(options.target.a); // OK - but still flagged [INCONSISTENCY]
}
$.fn.my_plugin = function my_plugin(options) {

View File

@@ -0,0 +1,4 @@
import javascript
import testUtilities.ConsistencyChecking
import semmle.javascript.security.dataflow.SqlInjection
import semmle.javascript.security.dataflow.NosqlInjection

View File

@@ -18,24 +18,24 @@
| mongoose.js:63:2:63:34 | Documen ... then(X) |
| mongoose.js:65:2:65:51 | Documen ... on(){}) |
| mongoose.js:67:2:68:27 | new Mon ... on(){}) |
| mongoose.js:71:2:77:9 | Documen ... .exec() |
| mongoose.js:84:2:84:52 | Documen ... query)) |
| mongoose.js:71:5:78:9 | Documen ... .exec() |
| mongoose.js:85:2:85:52 | Documen ... query)) |
| mongoose.js:86:2:86:57 | Documen ... query)) |
| mongoose.js:86:2:86:52 | Documen ... query)) |
| mongoose.js:87:2:87:57 | Documen ... query)) |
| mongoose.js:88:2:88:52 | Documen ... query)) |
| mongoose.js:89:2:89:55 | Documen ... query)) |
| mongoose.js:91:2:91:52 | Documen ... query)) |
| mongoose.js:92:2:92:49 | Documen ... query)) |
| mongoose.js:93:2:93:57 | Documen ... query)) |
| mongoose.js:94:2:94:54 | Documen ... query)) |
| mongoose.js:95:2:95:52 | Documen ... query)) |
| mongoose.js:88:2:88:57 | Documen ... query)) |
| mongoose.js:89:2:89:52 | Documen ... query)) |
| mongoose.js:90:2:90:55 | Documen ... query)) |
| mongoose.js:92:2:92:52 | Documen ... query)) |
| mongoose.js:93:2:93:49 | Documen ... query)) |
| mongoose.js:94:2:94:57 | Documen ... query)) |
| mongoose.js:95:2:95:54 | Documen ... query)) |
| mongoose.js:96:2:96:52 | Documen ... query)) |
| mongoose.js:98:2:98:50 | Documen ... query)) |
| mongoose.js:97:2:97:52 | Documen ... query)) |
| mongoose.js:99:2:99:50 | Documen ... query)) |
| socketio.js:11:5:11:54 | db.run( ... ndle}`) |
| tst2.js:7:3:7:62 | sql.que ... ms.id}` |
| tst2.js:9:3:9:85 | new sql ... + "'") |
| tst3.js:10:3:12:4 | pool.qu ... ts\\n }) |
| tst3.js:17:3:19:4 | pool.qu ... ts\\n }) |
| tst3.js:9:3:11:4 | pool.qu ... ts\\n }) |
| tst3.js:16:3:18:4 | pool.qu ... ts\\n }) |
| tst4.js:8:3:8:67 | db.get( ... + '"') |
| tst.js:10:3:10:65 | db.get( ... + '"') |

View File

@@ -108,30 +108,34 @@ nodes
| mongoose.js:67:27:67:31 | query |
| mongoose.js:68:8:68:12 | query |
| mongoose.js:68:8:68:12 | query |
| mongoose.js:72:8:72:12 | query |
| mongoose.js:72:8:72:12 | query |
| mongoose.js:73:7:73:11 | query |
| mongoose.js:73:7:73:11 | query |
| mongoose.js:74:16:74:20 | query |
| mongoose.js:74:16:74:20 | query |
| mongoose.js:76:10:76:14 | query |
| mongoose.js:76:10:76:14 | query |
| mongoose.js:81:46:81:50 | query |
| mongoose.js:81:46:81:50 | query |
| mongoose.js:82:47:82:51 | query |
| mongoose.js:82:47:82:51 | query |
| mongoose.js:84:46:84:50 | query |
| mongoose.js:84:46:84:50 | query |
| mongoose.js:86:51:86:55 | query |
| mongoose.js:86:51:86:55 | query |
| mongoose.js:88:46:88:50 | query |
| mongoose.js:88:46:88:50 | query |
| mongoose.js:91:46:91:50 | query |
| mongoose.js:91:46:91:50 | query |
| mongoose.js:93:51:93:55 | query |
| mongoose.js:93:51:93:55 | query |
| mongoose.js:95:46:95:50 | query |
| mongoose.js:95:46:95:50 | query |
| mongoose.js:71:20:71:24 | query |
| mongoose.js:71:20:71:24 | query |
| mongoose.js:72:16:72:20 | query |
| mongoose.js:72:16:72:20 | query |
| mongoose.js:73:8:73:12 | query |
| mongoose.js:73:8:73:12 | query |
| mongoose.js:74:7:74:11 | query |
| mongoose.js:74:7:74:11 | query |
| mongoose.js:75:16:75:20 | query |
| mongoose.js:75:16:75:20 | query |
| mongoose.js:77:10:77:14 | query |
| mongoose.js:77:10:77:14 | query |
| mongoose.js:82:46:82:50 | query |
| mongoose.js:82:46:82:50 | query |
| mongoose.js:83:47:83:51 | query |
| mongoose.js:83:47:83:51 | query |
| mongoose.js:85:46:85:50 | query |
| mongoose.js:85:46:85:50 | query |
| mongoose.js:87:51:87:55 | query |
| mongoose.js:87:51:87:55 | query |
| mongoose.js:89:46:89:50 | query |
| mongoose.js:89:46:89:50 | query |
| mongoose.js:92:46:92:50 | query |
| mongoose.js:92:46:92:50 | query |
| mongoose.js:94:51:94:55 | query |
| mongoose.js:94:51:94:55 | query |
| mongoose.js:96:46:96:50 | query |
| mongoose.js:96:46:96:50 | query |
| mongooseJsonParse.js:19:11:19:20 | query |
| mongooseJsonParse.js:19:19:19:20 | {} |
| mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) |
@@ -162,12 +166,12 @@ nodes
| tst2.js:9:27:9:84 | "select ... d + "'" |
| tst2.js:9:66:9:78 | req.params.id |
| tst2.js:9:66:9:78 | req.params.id |
| tst3.js:8:7:9:55 | query1 |
| tst3.js:8:16:9:55 | "SELECT ... PRICE" |
| tst3.js:9:16:9:34 | req.params.category |
| tst3.js:9:16:9:34 | req.params.category |
| tst3.js:10:14:10:19 | query1 |
| tst3.js:10:14:10:19 | query1 |
| tst3.js:7:7:8:55 | query1 |
| tst3.js:7:16:8:55 | "SELECT ... PRICE" |
| tst3.js:8:16:8:34 | req.params.category |
| tst3.js:8:16:8:34 | req.params.category |
| tst3.js:9:14:9:19 | query1 |
| tst3.js:9:14:9:19 | query1 |
| tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
| tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
| tst4.js:8:46:8:60 | $routeParams.id |
@@ -305,30 +309,34 @@ edges
| mongoose.js:20:11:20:20 | query | mongoose.js:67:27:67:31 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:68:8:68:12 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:68:8:68:12 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:72:8:72:12 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:72:8:72:12 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:73:7:73:11 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:73:7:73:11 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:74:16:74:20 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:74:16:74:20 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:76:10:76:14 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:76:10:76:14 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:81:46:81:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:81:46:81:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:82:47:82:51 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:82:47:82:51 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:84:46:84:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:84:46:84:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:86:51:86:55 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:86:51:86:55 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:88:46:88:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:88:46:88:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:91:46:91:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:91:46:91:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:93:51:93:55 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:93:51:93:55 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:95:46:95:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:95:46:95:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:71:20:71:24 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:71:20:71:24 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:72:16:72:20 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:72:16:72:20 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:73:8:73:12 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:73:8:73:12 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:74:7:74:11 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:74:7:74:11 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:75:16:75:20 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:75:16:75:20 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:77:10:77:14 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:77:10:77:14 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:82:46:82:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:82:46:82:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:83:47:83:51 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:83:47:83:51 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:85:46:85:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:85:46:85:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:87:51:87:55 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:87:51:87:55 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:89:46:89:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:89:46:89:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:92:46:92:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:92:46:92:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:94:51:94:55 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:94:51:94:55 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:96:46:96:50 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:96:46:96:50 | query |
| mongoose.js:20:19:20:20 | {} | mongoose.js:20:11:20:20 | query |
| mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title |
| mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title |
@@ -367,30 +375,34 @@ edges
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:67:27:67:31 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:68:8:68:12 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:68:8:68:12 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:8:72:12 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:8:72:12 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:7:73:11 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:7:73:11 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:16:74:20 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:16:74:20 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:76:10:76:14 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:76:10:76:14 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:81:46:81:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:81:46:81:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:47:82:51 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:47:82:51 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:84:46:84:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:84:46:84:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:86:51:86:55 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:86:51:86:55 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:88:46:88:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:88:46:88:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:91:46:91:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:91:46:91:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:93:51:93:55 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:93:51:93:55 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:95:46:95:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:95:46:95:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:71:20:71:24 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:71:20:71:24 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:16:72:20 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:16:72:20 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:8:73:12 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:8:73:12 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:7:74:11 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:7:74:11 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:75:16:75:20 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:75:16:75:20 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:77:10:77:14 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:77:10:77:14 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:46:82:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:46:82:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:83:47:83:51 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:83:47:83:51 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:85:46:85:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:85:46:85:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:87:51:87:55 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:87:51:87:55 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:89:46:89:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:89:46:89:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:92:46:92:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:92:46:92:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:94:51:94:55 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:94:51:94:55 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:96:46:96:50 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:96:46:96:50 | query |
| mongoose.js:24:25:24:29 | query | mongoose.js:24:24:24:30 | [query] |
| mongoose.js:24:25:24:29 | query | mongoose.js:24:24:24:30 | [query] |
| mongooseJsonParse.js:19:11:19:20 | query | mongooseJsonParse.js:23:19:23:23 | query |
@@ -422,11 +434,11 @@ edges
| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" |
| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" |
| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" |
| tst3.js:8:7:9:55 | query1 | tst3.js:10:14:10:19 | query1 |
| tst3.js:8:7:9:55 | query1 | tst3.js:10:14:10:19 | query1 |
| tst3.js:8:16:9:55 | "SELECT ... PRICE" | tst3.js:8:7:9:55 | query1 |
| tst3.js:9:16:9:34 | req.params.category | tst3.js:8:16:9:55 | "SELECT ... PRICE" |
| tst3.js:9:16:9:34 | req.params.category | tst3.js:8:16:9:55 | "SELECT ... PRICE" |
| tst3.js:7:7:8:55 | query1 | tst3.js:9:14:9:19 | query1 |
| tst3.js:7:7:8:55 | query1 | tst3.js:9:14:9:19 | query1 |
| tst3.js:7:16:8:55 | "SELECT ... PRICE" | tst3.js:7:7:8:55 | query1 |
| tst3.js:8:16:8:34 | req.params.category | tst3.js:7:16:8:55 | "SELECT ... PRICE" |
| tst3.js:8:16:8:34 | req.params.category | tst3.js:7:16:8:55 | "SELECT ... PRICE" |
| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
@@ -464,23 +476,25 @@ edges
| mongoose.js:65:32:65:36 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:65:32:65:36 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:67:27:67:31 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:67:27:67:31 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:68:8:68:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:68:8:68:12 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:72:8:72:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:72:8:72:12 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:73:7:73:11 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:73:7:73:11 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:74:16:74:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:74:16:74:20 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:76:10:76:14 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:76:10:76:14 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:81:46:81:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:81:46:81:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:82:47:82:51 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:82:47:82:51 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:84:46:84:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:84:46:84:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:86:51:86:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:86:51:86:55 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:88:46:88:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:88:46:88:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:91:46:91:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:91:46:91:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:93:51:93:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:93:51:93:55 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:95:46:95:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:95:46:95:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:71:20:71:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:71:20:71:24 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:72:16:72:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:72:16:72:20 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:73:8:73:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:73:8:73:12 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:74:7:74:11 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:74:7:74:11 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:75:16:75:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:75:16:75:20 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:77:10:77:14 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:77:10:77:14 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:82:46:82:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:82:46:82:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:83:47:83:51 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:83:47:83:51 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:85:46:85:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:85:46:85:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:87:51:87:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:87:51:87:55 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:89:46:89:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:89:46:89:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:92:46:92:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:92:46:92:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:94:51:94:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:94:51:94:55 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:96:46:96:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:96:46:96:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongooseJsonParse.js:23:19:23:23 | query | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:23:19:23:23 | query | This query depends on $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | a user-provided value |
| mongooseModelClient.js:11:16:11:24 | { id: v } | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:11:16:11:24 | { id: v } | This query depends on $@. | mongooseModelClient.js:10:22:10:29 | req.body | a user-provided value |
| mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | This query depends on $@. | mongooseModelClient.js:12:22:12:29 | req.body | a user-provided value |
| socketio.js:11:12:11:53 | `INSERT ... andle}` | socketio.js:10:25:10:30 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | This query depends on $@. | socketio.js:10:25:10:30 | handle | a user-provided value |
| tst2.js:9:27:9:84 | "select ... d + "'" | tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | This query depends on $@. | tst2.js:9:66:9:78 | req.params.id | a user-provided value |
| tst3.js:10:14:10:19 | query1 | tst3.js:9:16:9:34 | req.params.category | tst3.js:10:14:10:19 | query1 | This query depends on $@. | tst3.js:9:16:9:34 | req.params.category | a user-provided value |
| tst3.js:9:14:9:19 | query1 | tst3.js:8:16:8:34 | req.params.category | tst3.js:9:14:9:19 | query1 | This query depends on $@. | tst3.js:8:16:8:34 | req.params.category | a user-provided value |
| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | This query depends on $@. | tst4.js:8:46:8:60 | $routeParams.id | a user-provided value |
| tst.js:10:10:10:64 | 'SELECT ... d + '"' | tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | This query depends on $@. | tst.js:10:46:10:58 | req.params.id | a user-provided value |

View File

@@ -68,7 +68,8 @@ app.post('/documents/find', (req, res) => {
.and(query, function(){}) // NOT OK
;
Document.where(query) // NOT OK
Document.where(query) // NOT OK - `.where()` on a Model.
.where(query) // NOT OK - `.where()` on a Query.
.and(query) // NOT OK
.or(query) // NOT OK
.distinct(X, query) // NOT OK

View File

@@ -4,10 +4,9 @@ const pg = require('pg');
const pool = new pg.Pool(config);
function handler(req, res) {
// BAD: the category might have SQL special characters in it
var query1 = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ req.params.category + "' ORDER BY PRICE";
pool.query(query1, [], function(err, results) {
pool.query(query1, [], function(err, results) { // BAD: the category might have SQL special characters in it
// process results
});

View File

@@ -14,7 +14,7 @@ app.post("/documents/find", (req, res) => {
MongoClient.connect("mongodb://localhost:27017/test", (err, db) => {
let doc = db.collection("doc");
doc.find(query); // NOT OK, but that is flagged by js/sql-injection
doc.find(query); // NOT OK, but that is flagged by js/sql-injection [INCONSISTENCY]
doc.find({ $where: req.body.query }); // NOT OK
doc.find({ $where: "name = " + req.body.name }); // NOT OK
});

View File

@@ -26,8 +26,8 @@
console.log(obj2); // NOT OK
var obj3 = {};
console.log(obj3);
obj3.x = password; // NOT OK
console.log(obj3); // OK - but still flagged due to flow-insensitive field-analysis. [INCONSISTENCY]
obj3.x = password;
var fixed_password = "123";
console.log(fixed_password); // OK
@@ -90,12 +90,12 @@
console.log("Password is: " + redact('password', password));
if (environment.isTestEnv()) {
console.log("Password is: " + password); // OK, but still flagged
console.log("Password is: " + password); // OK, but still flagged [INCONSISTENCY]
}
if (environment.is(TEST)) {
// NB: for security reasons, we only log passwords in test environments
console.log("Password is: " + password); // OK, but still flagged
console.log("Password is: " + password); // OK, but still flagged [INCONSISTENCY]
}
@@ -107,7 +107,7 @@
}
if (environment.isTestEnv())
console.log("Password is: " + password); // OK, but still flagged
console.log("Password is: " + password); // OK, but still flagged [INCONSISTENCY]
if (x.test(y)) {
if (f()) {
@@ -116,7 +116,7 @@
}
if (!environment.isProduction()) {
console.log("Password is: " + password); // OK, but still flagged
console.log("Password is: " + password); // OK, but still flagged [INCONSISTENCY]
}
console.log(name + ", " + password.toString()); // NOT OK

View File

@@ -21,7 +21,7 @@ function f4() {
}
function f5() {
var pw = Math.random(); // NOT OK, but our naming heuristic does not identify `pw` as sensitive
var pw = Math.random(); // NOT OK, but our naming heuristic does not identify `pw` as sensitive [INCONSISTENCY]
}
function f6() {

View File

@@ -48,7 +48,7 @@ server.on('request', (req, res) => {
// syntactic header defintion
probalyAServer.on('request', (req, res) => {
res.setHeader("Access-Control-Allow-Origin", null); // NOT OK (but not detected)
res.setHeader("Access-Control-Allow-Origin", null); // NOT OK (but not detected) [INCONSISTENCY]
res.setHeader("Access-Control-Allow-Credentials", true);
});

View File

@@ -4,7 +4,7 @@ eval(totallyHarmlessString); // OK: throws parse
var test = "0123456789";
try {
eval(test+"n"); // OK, but currently flagged
eval(test+"n"); // OK, but currently flagged [INCONSISTENCY]
console.log("Bigints supported.");
} catch(e) {
console.log("Bigints not supported.");

View File

@@ -56,32 +56,32 @@ nodes
| koa.js:14:16:14:18 | url |
| koa.js:20:16:20:18 | url |
| koa.js:20:16:20:18 | url |
| node.js:6:7:6:52 | target |
| node.js:6:16:6:39 | url.par ... , true) |
| node.js:6:16:6:45 | url.par ... ).query |
| node.js:6:16:6:52 | url.par ... .target |
| node.js:6:26:6:32 | req.url |
| node.js:6:26:6:32 | req.url |
| node.js:7:34:7:39 | target |
| node.js:7:34:7:39 | target |
| node.js:11:7:11:52 | target |
| node.js:11:16:11:39 | url.par ... , true) |
| node.js:11:16:11:45 | url.par ... ).query |
| node.js:11:16:11:52 | url.par ... .target |
| node.js:11:26:11:32 | req.url |
| node.js:11:26:11:32 | req.url |
| node.js:15:34:15:45 | '/' + target |
| node.js:15:34:15:45 | '/' + target |
| node.js:15:40:15:45 | target |
| node.js:29:7:29:52 | target |
| node.js:29:16:29:39 | url.par ... , true) |
| node.js:29:16:29:45 | url.par ... ).query |
| node.js:29:16:29:52 | url.par ... .target |
| node.js:29:26:29:32 | req.url |
| node.js:29:26:29:32 | req.url |
| node.js:32:34:32:39 | target |
| node.js:32:34:32:55 | target ... =" + me |
| node.js:32:34:32:55 | target ... =" + me |
| node.js:5:7:5:52 | target |
| node.js:5:16:5:39 | url.par ... , true) |
| node.js:5:16:5:45 | url.par ... ).query |
| node.js:5:16:5:52 | url.par ... .target |
| node.js:5:26:5:32 | req.url |
| node.js:5:26:5:32 | req.url |
| node.js:6:34:6:39 | target |
| node.js:6:34:6:39 | target |
| node.js:10:7:10:52 | target |
| node.js:10:16:10:39 | url.par ... , true) |
| node.js:10:16:10:45 | url.par ... ).query |
| node.js:10:16:10:52 | url.par ... .target |
| node.js:10:26:10:32 | req.url |
| node.js:10:26:10:32 | req.url |
| node.js:14:34:14:45 | '/' + target |
| node.js:14:34:14:45 | '/' + target |
| node.js:14:40:14:45 | target |
| node.js:28:7:28:52 | target |
| node.js:28:16:28:39 | url.par ... , true) |
| node.js:28:16:28:45 | url.par ... ).query |
| node.js:28:16:28:52 | url.par ... .target |
| node.js:28:26:28:32 | req.url |
| node.js:28:26:28:32 | req.url |
| node.js:31:34:31:39 | target |
| node.js:31:34:31:55 | target ... =" + me |
| node.js:31:34:31:55 | target ... =" + me |
| react-native.js:7:7:7:33 | tainted |
| react-native.js:7:17:7:33 | req.param("code") |
| react-native.js:7:17:7:33 | req.param("code") |
@@ -139,29 +139,29 @@ edges
| koa.js:6:12:6:27 | ctx.query.target | koa.js:6:6:6:27 | url |
| koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` |
| koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` |
| node.js:6:7:6:52 | target | node.js:7:34:7:39 | target |
| node.js:6:7:6:52 | target | node.js:7:34:7:39 | target |
| node.js:6:16:6:39 | url.par ... , true) | node.js:6:16:6:45 | url.par ... ).query |
| node.js:6:16:6:45 | url.par ... ).query | node.js:6:16:6:52 | url.par ... .target |
| node.js:6:16:6:52 | url.par ... .target | node.js:6:7:6:52 | target |
| node.js:6:26:6:32 | req.url | node.js:6:16:6:39 | url.par ... , true) |
| node.js:6:26:6:32 | req.url | node.js:6:16:6:39 | url.par ... , true) |
| node.js:11:7:11:52 | target | node.js:15:40:15:45 | target |
| node.js:11:16:11:39 | url.par ... , true) | node.js:11:16:11:45 | url.par ... ).query |
| node.js:11:16:11:45 | url.par ... ).query | node.js:11:16:11:52 | url.par ... .target |
| node.js:11:16:11:52 | url.par ... .target | node.js:11:7:11:52 | target |
| node.js:11:26:11:32 | req.url | node.js:11:16:11:39 | url.par ... , true) |
| node.js:11:26:11:32 | req.url | node.js:11:16:11:39 | url.par ... , true) |
| node.js:15:40:15:45 | target | node.js:15:34:15:45 | '/' + target |
| node.js:15:40:15:45 | target | node.js:15:34:15:45 | '/' + target |
| node.js:29:7:29:52 | target | node.js:32:34:32:39 | target |
| node.js:29:16:29:39 | url.par ... , true) | node.js:29:16:29:45 | url.par ... ).query |
| node.js:29:16:29:45 | url.par ... ).query | node.js:29:16:29:52 | url.par ... .target |
| node.js:29:16:29:52 | url.par ... .target | node.js:29:7:29:52 | target |
| node.js:29:26:29:32 | req.url | node.js:29:16:29:39 | url.par ... , true) |
| node.js:29:26:29:32 | req.url | node.js:29:16:29:39 | url.par ... , true) |
| node.js:32:34:32:39 | target | node.js:32:34:32:55 | target ... =" + me |
| node.js:32:34:32:39 | target | node.js:32:34:32:55 | target ... =" + me |
| node.js:5:7:5:52 | target | node.js:6:34:6:39 | target |
| node.js:5:7:5:52 | target | node.js:6:34:6:39 | target |
| node.js:5:16:5:39 | url.par ... , true) | node.js:5:16:5:45 | url.par ... ).query |
| node.js:5:16:5:45 | url.par ... ).query | node.js:5:16:5:52 | url.par ... .target |
| node.js:5:16:5:52 | url.par ... .target | node.js:5:7:5:52 | target |
| node.js:5:26:5:32 | req.url | node.js:5:16:5:39 | url.par ... , true) |
| node.js:5:26:5:32 | req.url | node.js:5:16:5:39 | url.par ... , true) |
| node.js:10:7:10:52 | target | node.js:14:40:14:45 | target |
| node.js:10:16:10:39 | url.par ... , true) | node.js:10:16:10:45 | url.par ... ).query |
| node.js:10:16:10:45 | url.par ... ).query | node.js:10:16:10:52 | url.par ... .target |
| node.js:10:16:10:52 | url.par ... .target | node.js:10:7:10:52 | target |
| node.js:10:26:10:32 | req.url | node.js:10:16:10:39 | url.par ... , true) |
| node.js:10:26:10:32 | req.url | node.js:10:16:10:39 | url.par ... , true) |
| node.js:14:40:14:45 | target | node.js:14:34:14:45 | '/' + target |
| node.js:14:40:14:45 | target | node.js:14:34:14:45 | '/' + target |
| node.js:28:7:28:52 | target | node.js:31:34:31:39 | target |
| node.js:28:16:28:39 | url.par ... , true) | node.js:28:16:28:45 | url.par ... ).query |
| node.js:28:16:28:45 | url.par ... ).query | node.js:28:16:28:52 | url.par ... .target |
| node.js:28:16:28:52 | url.par ... .target | node.js:28:7:28:52 | target |
| node.js:28:26:28:32 | req.url | node.js:28:16:28:39 | url.par ... , true) |
| node.js:28:26:28:32 | req.url | node.js:28:16:28:39 | url.par ... , true) |
| node.js:31:34:31:39 | target | node.js:31:34:31:55 | target ... =" + me |
| node.js:31:34:31:39 | target | node.js:31:34:31:55 | target ... =" + me |
| react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted |
| react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted |
| react-native.js:7:7:7:33 | tainted | react-native.js:9:26:9:32 | tainted |
@@ -185,8 +185,8 @@ edges
| koa.js:8:15:8:26 | `${url}${x}` | koa.js:6:12:6:27 | ctx.query.target | koa.js:8:15:8:26 | `${url}${x}` | Untrusted URL redirection due to $@. | koa.js:6:12:6:27 | ctx.query.target | user-provided value |
| koa.js:14:16:14:18 | url | koa.js:6:12:6:27 | ctx.query.target | koa.js:14:16:14:18 | url | Untrusted URL redirection due to $@. | koa.js:6:12:6:27 | ctx.query.target | user-provided value |
| koa.js:20:16:20:18 | url | koa.js:6:12:6:27 | ctx.query.target | koa.js:20:16:20:18 | url | Untrusted URL redirection due to $@. | koa.js:6:12:6:27 | ctx.query.target | user-provided value |
| node.js:7:34:7:39 | target | node.js:6:26:6:32 | req.url | node.js:7:34:7:39 | target | Untrusted URL redirection due to $@. | node.js:6:26:6:32 | req.url | user-provided value |
| node.js:15:34:15:45 | '/' + target | node.js:11:26:11:32 | req.url | node.js:15:34:15:45 | '/' + target | Untrusted URL redirection due to $@. | node.js:11:26:11:32 | req.url | user-provided value |
| node.js:32:34:32:55 | target ... =" + me | node.js:29:26:29:32 | req.url | node.js:32:34:32:55 | target ... =" + me | Untrusted URL redirection due to $@. | node.js:29:26:29:32 | req.url | user-provided value |
| node.js:6:34:6:39 | target | node.js:5:26:5:32 | req.url | node.js:6:34:6:39 | target | Untrusted URL redirection due to $@. | node.js:5:26:5:32 | req.url | user-provided value |
| node.js:14:34:14:45 | '/' + target | node.js:10:26:10:32 | req.url | node.js:14:34:14:45 | '/' + target | Untrusted URL redirection due to $@. | node.js:10:26:10:32 | req.url | user-provided value |
| node.js:31:34:31:55 | target ... =" + me | node.js:28:26:28:32 | req.url | node.js:31:34:31:55 | target ... =" + me | Untrusted URL redirection due to $@. | node.js:28:26:28:32 | req.url | user-provided value |
| react-native.js:8:17:8:23 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:17:8:23 | tainted | Untrusted URL redirection due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
| react-native.js:9:26:9:32 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:9:26:9:32 | tainted | Untrusted URL redirection due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |

View File

@@ -135,6 +135,6 @@ app.get('/redirect/:user', function(req, res) {
res.redirect('//' + req.params.user); // BAD - could go to //evil.com
res.redirect('u' + req.params.user); // BAD - could go to u.evil.com
res.redirect('/' + ('/u' + req.params.user)); // BAD - could go to //u.evil.com, but not flagged
res.redirect('/' + ('/u' + req.params.user)); // BAD - could go to //u.evil.com, but not flagged [INCONSISTENCY]
res.redirect('/u' + req.params.user); // GOOD
});

View File

@@ -2,9 +2,8 @@ var https = require('https');
var url = require('url');
var server = https.createServer(function(req, res) {
// BAD: a request parameter is incorporated without validation into a URL redirect
let target = url.parse(req.url, true).query.target;
res.writeHead(302, { Location: target });
res.writeHead(302, { Location: target }); // BAD: a request parameter is incorporated without validation into a URL redirect
})
server.on('request', (req, res) => {

View File

@@ -10,12 +10,12 @@ nodes
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
edges
| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src |
| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src |
@@ -25,11 +25,11 @@ edges
| domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search |
| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
#select
| domparser.js:11:55:11:57 | src | domparser.js:2:13:2:29 | document.location | domparser.js:11:55:11:57 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
| domparser.js:14:57:14:59 | src | domparser.js:2:13:2:29 | document.location | domparser.js:14:57:14:59 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | user-provided value |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | user-provided value |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | user-provided value |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | user-provided value |

View File

@@ -2,7 +2,6 @@ const express = require('express');
const libxmljs = require('libxmljs');
express().get('/some/path', function(req) {
// NOT OK: the SAX parser expands external entities by default
const parser = new libxmljs.SaxParser();
parser.parseString(req.param("some-xml"));
parser.parseString(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
});

View File

@@ -2,7 +2,6 @@ const express = require('express');
const libxmljs = require('libxmljs');
express().get('/some/path', function(req) {
// NOT OK: the SAX parser expands external entities by default
const parser = new libxmljs.SaxPushParser();
parser.push(req.param("some-xml"));
parser.push(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
});

View File

@@ -47,7 +47,7 @@ app.get('/findKey', function(req, res) {
maybeString.search(input); // NOT OK
notString.search(input); // OK
URI(`${protocol}://${host}${path}`).search(input); // OK, but still flagged
URI(`${protocol}://${host}${path}`).search(input); // OK, but still flagged [INCONSISTENCY]
URI(`${protocol}://${host}${path}`).search(input).href(); // OK
unknown.search(input).unknown; // OK

View File

@@ -4,15 +4,15 @@ let obj = {};
window.addEventListener('message', (ev) => {
let message = JSON.parse(ev.data);
window[message.name](message.payload); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql
new window[message.name](message.payload); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql
window[message.name](message.payload); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql [INCONSISTENCY]
new window[message.name](message.payload); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql [INCONSISTENCY]
window["HTMLElement" + message.name](message.payload); // OK - concatenation restricts choice of methods
window[`HTMLElement${message.name}`](message.payload); // OK - concatenation restricts choice of methods
function f() {}
f[message.name](message.payload)(); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql
f[message.name](message.payload)(); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql [INCONSISTENCY]
obj[message.name](message.payload); // NOT OK
window[ev](ev); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql
window[ev](ev); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql [INCONSISTENCY]
});

View File

@@ -28,13 +28,13 @@
obj[name](); // NOT OK
if (obj.hasOwnProperty(name)) {
obj[name](); // NOT OK, but not flagged
obj[name](); // NOT OK, but not flagged [INCONSISTENCY]
}
let key = "$" + name;
obj[key](); // NOT OK
if (typeof obj[key] === 'function')
obj[key](); // OK - but still flagged
obj[key](); // OK - but still flagged [INCONSISTENCY]
if (typeof fn === 'function') {
fn.apply(obj); // OK

View File

@@ -15,9 +15,9 @@ nodes
| domparser.js:11:55:11:57 | src |
| domparser.js:14:57:14:59 | src |
| domparser.js:14:57:14:59 | src |
| expat.js:7:16:7:36 | req.par ... e-xml") |
| expat.js:7:16:7:36 | req.par ... e-xml") |
| expat.js:7:16:7:36 | req.par ... e-xml") |
| expat.js:6:16:6:36 | req.par ... e-xml") |
| expat.js:6:16:6:36 | req.par ... e-xml") |
| expat.js:6:16:6:36 | req.par ... e-xml") |
| jquery.js:2:7:2:36 | src |
| jquery.js:2:13:2:29 | document.location |
| jquery.js:2:13:2:29 | document.location |
@@ -30,12 +30,12 @@ nodes
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
edges
| closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src |
| closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src |
@@ -51,7 +51,7 @@ edges
| domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search |
| domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search |
| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src |
| expat.js:7:16:7:36 | req.par ... e-xml") | expat.js:7:16:7:36 | req.par ... e-xml") |
| expat.js:6:16:6:36 | req.par ... e-xml") | expat.js:6:16:6:36 | req.par ... e-xml") |
| jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src |
| jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src |
| jquery.js:2:13:2:29 | document.location | jquery.js:2:13:2:36 | documen ... .search |
@@ -59,16 +59,16 @@ edges
| jquery.js:2:13:2:36 | documen ... .search | jquery.js:2:7:2:36 | src |
| libxml.js:6:21:6:41 | req.par ... e-xml") | libxml.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
#select
| closure.js:4:24:4:26 | src | closure.js:2:13:2:29 | document.location | closure.js:4:24:4:26 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | closure.js:2:13:2:29 | document.location | user-provided value |
| domparser.js:6:37:6:39 | src | domparser.js:2:13:2:29 | document.location | domparser.js:6:37:6:39 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
| domparser.js:11:55:11:57 | src | domparser.js:2:13:2:29 | document.location | domparser.js:11:55:11:57 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
| domparser.js:14:57:14:59 | src | domparser.js:2:13:2:29 | document.location | domparser.js:14:57:14:59 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
| expat.js:7:16:7:36 | req.par ... e-xml") | expat.js:7:16:7:36 | req.par ... e-xml") | expat.js:7:16:7:36 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | expat.js:7:16:7:36 | req.par ... e-xml") | user-provided value |
| expat.js:6:16:6:36 | req.par ... e-xml") | expat.js:6:16:6:36 | req.par ... e-xml") | expat.js:6:16:6:36 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | expat.js:6:16:6:36 | req.par ... e-xml") | user-provided value |
| jquery.js:5:14:5:16 | src | jquery.js:2:13:2:29 | document.location | jquery.js:5:14:5:16 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | jquery.js:2:13:2:29 | document.location | user-provided value |
| libxml.js:6:21:6:41 | req.par ... e-xml") | libxml.js:6:21:6:41 | req.par ... e-xml") | libxml.js:6:21:6:41 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | user-provided value |
| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | user-provided value |
| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | user-provided value |
| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | user-provided value |

View File

@@ -2,7 +2,6 @@ const express = require('express');
const expat = require('node-expat');
express().get('/some/path', function(req) {
// NOT OK: expat expands internal entities by default
var parser = new expat.Parser();
parser.write(req.param("some-xml"));
parser.write(req.param("some-xml")); // NOT OK: expat expands internal entities by default
});

View File

@@ -2,7 +2,6 @@ const express = require('express');
const libxmljs = require('libxmljs');
express().get('/some/path', function(req) {
// NOT OK: the SAX parser expands external entities by default
const parser = new libxmljs.SaxParser();
parser.parseString(req.param("some-xml"));
parser.parseString(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
});

View File

@@ -2,7 +2,6 @@ const express = require('express');
const libxmljs = require('libxmljs');
express().get('/some/path', function(req) {
// NOT OK: the SAX parser expands external entities by default
const parser = new libxmljs.SaxPushParser();
parser.push(req.param("some-xml"));
parser.push(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
});

View File

@@ -2,12 +2,12 @@
const pg = require('pg');
const client = new pg.Client({
user: 'dbuser',
user: 'dbuser', // NOT OK
host: 'database.server.com',
database: 'mydb',
password: 'abcdefgh',
password: 'abcdefgh', // NOT OK
port: 3211,
}); // NOT OK
});
client.connect();
})();
@@ -26,8 +26,8 @@
basicAuth({users: { 'admin': 'abcdefgh' }}); // NOT OK
var users = {};
users['unknown-admin-name'] = 'abcdefgh';
basicAuth({users: users}) // NOT OK
users['unknown-admin-name'] = 'abcdefgh'; // NOT OK
basicAuth({users: users});
})();
(function() {
@@ -43,26 +43,26 @@
var config = new AWS.Config();
config.update({ accessKeyId: 'username', secretAccessKey: 'abcdefgh'}); // NOT OK
var o = {};
o.secretAccessKey = 'abcdefgh';
config.update(o); // NOT OK
o.secretAccessKey = 'abcdefgh'; // NOT OK
config.update(o);
})();
(function() {
var request = require('request');
request.get(url).auth('username', 'abcdefgh'); // NOT OK
request.get(url, { // NOT OK
request.get(url, {
'auth': {
'user': 'username',
'pass': 'abcdefgh'
'user': 'username', // NOT OK
'pass': 'abcdefgh' // NOT OK
}
});
request.get(url).auth(null, null, _, 'bearerToken'); // NOT OK
request.get(url, { // NOT OK
request.get(url, {
'auth': {
'bearer': 'bearerToken'
'bearer': 'bearerToken' // NOT OK
}
});
@@ -70,10 +70,10 @@
request.head(url).auth('username', 'abcdefgh'); // NOT OK
request(url).auth('username', 'abcdefgh'); // NOT OK
request(url, { // NOT OK
request(url, {
'auth': {
'user': 'username',
'pass': 'abcdefgh'
'user': 'username', // NOT OK
'pass': 'abcdefgh' // NOT OK
}
});
})();
@@ -94,31 +94,31 @@
(function() {
var pkgcloud = require('pkgcloud');
pkgcloud.compute.createClient({ // NOT OK
account: 'x1',
keyId: 'x2',
storageAccount: 'x3',
username: 'x4',
key: 'abcdefgh',
apiKey: 'abcdefgh',
storageAccessKey: 'abcdefgh',
password: 'abcdefgh',
token: 'abcdefgh'
pkgcloud.compute.createClient({
account: 'x1', // NOT OK
keyId: 'x2',// NOT OK
storageAccount: 'x3', // NOT OK
username: 'x4', // NOT OK
key: 'abcdefgh', // NOT OK
apiKey: 'abcdefgh', // NOT OK
storageAccessKey: 'abcdefgh', // NOT OK
password: 'abcdefgh', // NOT OK
token: 'abcdefgh' // NOT OK
});
pkgcloud.compute.createClient({ // OK
INNOCENT_DATA: '42'
});
pkgcloud.providers.SOME_PROVIDER.compute.createClient({ // NOT OK
username: 'x5',
password: 'abcdefgh'
pkgcloud.providers.SOME_PROVIDER.compute.createClient({
username: 'x5', // NOT OK
password: 'abcdefgh' // NOT OK
});
pkgcloud.UNKNOWN_SERVICE.createClient({ // OK
username: 'x6',
password: 'abcdefgh'
});
pkgcloud.providers.SOME_PROVIDER.UNKNOWN_SERVICE.createClient({ // OK
username: 'x7',
password: 'abcdefgh'
pkgcloud.providers.SOME_PROVIDER.UNKNOWN_SERVICE.createClient({
username: 'x7', // OK
password: 'abcdefgh' // OK
});
pkgcloud.compute.createClient({ // OK
username: process.env.USERNAME,

View File

@@ -2,113 +2,113 @@ nodes
| tst.js:9:8:9:26 | req.params.shutDown |
| tst.js:9:8:9:26 | req.params.shutDown |
| tst.js:9:8:9:26 | req.params.shutDown |
| tst.js:14:9:14:19 | req.cookies |
| tst.js:14:9:14:19 | req.cookies |
| tst.js:14:9:14:30 | req.coo ... inThing |
| tst.js:14:9:14:30 | req.coo ... inThing |
| tst.js:30:9:30:37 | v3 |
| tst.js:30:14:30:37 | id(req. ... okieId) |
| tst.js:30:17:30:27 | req.cookies |
| tst.js:30:17:30:27 | req.cookies |
| tst.js:30:17:30:36 | req.cookies.cookieId |
| tst.js:31:9:31:10 | v3 |
| tst.js:31:9:31:10 | v3 |
| tst.js:37:13:37:23 | req.cookies |
| tst.js:37:13:37:23 | req.cookies |
| tst.js:37:13:37:32 | req.cookies.cookieId |
| tst.js:37:13:37:32 | req.cookies.cookieId |
| tst.js:43:9:43:19 | req.cookies |
| tst.js:43:9:43:19 | req.cookies |
| tst.js:43:9:43:28 | req.cookies.cookieId |
| tst.js:43:9:43:28 | req.cookies.cookieId |
| tst.js:50:8:50:23 | req.params.login |
| tst.js:50:8:50:23 | req.params.login |
| tst.js:50:8:50:23 | req.params.login |
| tst.js:65:8:65:23 | req.params.login |
| tst.js:65:8:65:23 | req.params.login |
| tst.js:65:8:65:23 | req.params.login |
| tst.js:70:9:70:19 | req.cookies |
| tst.js:70:9:70:19 | req.cookies |
| tst.js:70:9:70:28 | req.cookies.cookieId |
| tst.js:70:9:70:28 | req.cookies.cookieId |
| tst.js:70:34:70:53 | req.params.requestId |
| tst.js:70:34:70:53 | req.params.requestId |
| tst.js:70:34:70:53 | req.params.requestId |
| tst.js:75:14:75:24 | req.cookies |
| tst.js:75:14:75:24 | req.cookies |
| tst.js:75:14:75:33 | req.cookies.cookieId |
| tst.js:75:14:75:33 | req.cookies.cookieId |
| tst.js:75:39:75:58 | req.params.requestId |
| tst.js:75:39:75:58 | req.params.requestId |
| tst.js:75:39:75:58 | req.params.requestId |
| tst.js:90:9:90:19 | req.cookies |
| tst.js:90:9:90:19 | req.cookies |
| tst.js:90:9:90:28 | req.cookies.cookieId |
| tst.js:90:9:90:28 | req.cookies.cookieId |
| tst.js:90:9:90:41 | req.coo ... secret" |
| tst.js:90:9:90:41 | req.coo ... secret" |
| tst.js:104:10:104:17 | req.body |
| tst.js:104:10:104:17 | req.body |
| tst.js:104:10:104:17 | req.body |
| tst.js:111:13:111:32 | req.query.vulnerable |
| tst.js:111:13:111:32 | req.query.vulnerable |
| tst.js:111:13:111:32 | req.query.vulnerable |
| tst.js:118:13:118:32 | req.query.vulnerable |
| tst.js:118:13:118:32 | req.query.vulnerable |
| tst.js:118:13:118:32 | req.query.vulnerable |
| tst.js:126:13:126:32 | req.query.vulnerable |
| tst.js:126:13:126:32 | req.query.vulnerable |
| tst.js:126:13:126:32 | req.query.vulnerable |
| tst.js:13:9:13:19 | req.cookies |
| tst.js:13:9:13:19 | req.cookies |
| tst.js:13:9:13:30 | req.coo ... inThing |
| tst.js:13:9:13:30 | req.coo ... inThing |
| tst.js:27:9:27:37 | v3 |
| tst.js:27:14:27:37 | id(req. ... okieId) |
| tst.js:27:17:27:27 | req.cookies |
| tst.js:27:17:27:27 | req.cookies |
| tst.js:27:17:27:36 | req.cookies.cookieId |
| tst.js:28:9:28:10 | v3 |
| tst.js:28:9:28:10 | v3 |
| tst.js:33:13:33:23 | req.cookies |
| tst.js:33:13:33:23 | req.cookies |
| tst.js:33:13:33:32 | req.cookies.cookieId |
| tst.js:33:13:33:32 | req.cookies.cookieId |
| tst.js:38:9:38:19 | req.cookies |
| tst.js:38:9:38:19 | req.cookies |
| tst.js:38:9:38:28 | req.cookies.cookieId |
| tst.js:38:9:38:28 | req.cookies.cookieId |
| tst.js:44:8:44:23 | req.params.login |
| tst.js:44:8:44:23 | req.params.login |
| tst.js:44:8:44:23 | req.params.login |
| tst.js:57:8:57:23 | req.params.login |
| tst.js:57:8:57:23 | req.params.login |
| tst.js:57:8:57:23 | req.params.login |
| tst.js:61:9:61:19 | req.cookies |
| tst.js:61:9:61:19 | req.cookies |
| tst.js:61:9:61:28 | req.cookies.cookieId |
| tst.js:61:9:61:28 | req.cookies.cookieId |
| tst.js:61:34:61:53 | req.params.requestId |
| tst.js:61:34:61:53 | req.params.requestId |
| tst.js:61:34:61:53 | req.params.requestId |
| tst.js:65:14:65:24 | req.cookies |
| tst.js:65:14:65:24 | req.cookies |
| tst.js:65:14:65:33 | req.cookies.cookieId |
| tst.js:65:14:65:33 | req.cookies.cookieId |
| tst.js:65:39:65:58 | req.params.requestId |
| tst.js:65:39:65:58 | req.params.requestId |
| tst.js:65:39:65:58 | req.params.requestId |
| tst.js:78:9:78:19 | req.cookies |
| tst.js:78:9:78:19 | req.cookies |
| tst.js:78:9:78:28 | req.cookies.cookieId |
| tst.js:78:9:78:28 | req.cookies.cookieId |
| tst.js:78:9:78:41 | req.coo ... secret" |
| tst.js:78:9:78:41 | req.coo ... secret" |
| tst.js:91:10:91:17 | req.body |
| tst.js:91:10:91:17 | req.body |
| tst.js:91:10:91:17 | req.body |
| tst.js:98:13:98:32 | req.query.vulnerable |
| tst.js:98:13:98:32 | req.query.vulnerable |
| tst.js:98:13:98:32 | req.query.vulnerable |
| tst.js:105:13:105:32 | req.query.vulnerable |
| tst.js:105:13:105:32 | req.query.vulnerable |
| tst.js:105:13:105:32 | req.query.vulnerable |
| tst.js:113:13:113:32 | req.query.vulnerable |
| tst.js:113:13:113:32 | req.query.vulnerable |
| tst.js:113:13:113:32 | req.query.vulnerable |
edges
| tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown |
| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing |
| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing |
| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing |
| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing |
| tst.js:30:9:30:37 | v3 | tst.js:31:9:31:10 | v3 |
| tst.js:30:9:30:37 | v3 | tst.js:31:9:31:10 | v3 |
| tst.js:30:14:30:37 | id(req. ... okieId) | tst.js:30:9:30:37 | v3 |
| tst.js:30:17:30:27 | req.cookies | tst.js:30:17:30:36 | req.cookies.cookieId |
| tst.js:30:17:30:27 | req.cookies | tst.js:30:17:30:36 | req.cookies.cookieId |
| tst.js:30:17:30:36 | req.cookies.cookieId | tst.js:30:14:30:37 | id(req. ... okieId) |
| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId |
| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId |
| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId |
| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId |
| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId |
| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId |
| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId |
| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId |
| tst.js:50:8:50:23 | req.params.login | tst.js:50:8:50:23 | req.params.login |
| tst.js:65:8:65:23 | req.params.login | tst.js:65:8:65:23 | req.params.login |
| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId |
| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId |
| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId |
| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId |
| tst.js:70:34:70:53 | req.params.requestId | tst.js:70:34:70:53 | req.params.requestId |
| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId |
| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId |
| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId |
| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId |
| tst.js:75:39:75:58 | req.params.requestId | tst.js:75:39:75:58 | req.params.requestId |
| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId |
| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId |
| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId |
| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId |
| tst.js:90:9:90:28 | req.cookies.cookieId | tst.js:90:9:90:41 | req.coo ... secret" |
| tst.js:90:9:90:28 | req.cookies.cookieId | tst.js:90:9:90:41 | req.coo ... secret" |
| tst.js:104:10:104:17 | req.body | tst.js:104:10:104:17 | req.body |
| tst.js:111:13:111:32 | req.query.vulnerable | tst.js:111:13:111:32 | req.query.vulnerable |
| tst.js:118:13:118:32 | req.query.vulnerable | tst.js:118:13:118:32 | req.query.vulnerable |
| tst.js:126:13:126:32 | req.query.vulnerable | tst.js:126:13:126:32 | req.query.vulnerable |
| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing |
| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing |
| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing |
| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing |
| tst.js:27:9:27:37 | v3 | tst.js:28:9:28:10 | v3 |
| tst.js:27:9:27:37 | v3 | tst.js:28:9:28:10 | v3 |
| tst.js:27:14:27:37 | id(req. ... okieId) | tst.js:27:9:27:37 | v3 |
| tst.js:27:17:27:27 | req.cookies | tst.js:27:17:27:36 | req.cookies.cookieId |
| tst.js:27:17:27:27 | req.cookies | tst.js:27:17:27:36 | req.cookies.cookieId |
| tst.js:27:17:27:36 | req.cookies.cookieId | tst.js:27:14:27:37 | id(req. ... okieId) |
| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId |
| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId |
| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId |
| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId |
| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId |
| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId |
| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId |
| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId |
| tst.js:44:8:44:23 | req.params.login | tst.js:44:8:44:23 | req.params.login |
| tst.js:57:8:57:23 | req.params.login | tst.js:57:8:57:23 | req.params.login |
| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId |
| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId |
| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId |
| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId |
| tst.js:61:34:61:53 | req.params.requestId | tst.js:61:34:61:53 | req.params.requestId |
| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId |
| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId |
| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId |
| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId |
| tst.js:65:39:65:58 | req.params.requestId | tst.js:65:39:65:58 | req.params.requestId |
| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId |
| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId |
| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId |
| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId |
| tst.js:78:9:78:28 | req.cookies.cookieId | tst.js:78:9:78:41 | req.coo ... secret" |
| tst.js:78:9:78:28 | req.cookies.cookieId | tst.js:78:9:78:41 | req.coo ... secret" |
| tst.js:91:10:91:17 | req.body | tst.js:91:10:91:17 | req.body |
| tst.js:98:13:98:32 | req.query.vulnerable | tst.js:98:13:98:32 | req.query.vulnerable |
| tst.js:105:13:105:32 | req.query.vulnerable | tst.js:105:13:105:32 | req.query.vulnerable |
| tst.js:113:13:113:32 | req.query.vulnerable | tst.js:113:13:113:32 | req.query.vulnerable |
#select
| tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | This condition guards a sensitive $@, but $@ controls it. | tst.js:11:9:11:22 | process.exit() | action | tst.js:9:8:9:26 | req.params.shutDown | a user-provided value |
| tst.js:14:9:14:30 | req.coo ... inThing | tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing | This condition guards a sensitive $@, but $@ controls it. | tst.js:16:9:16:17 | o.login() | action | tst.js:14:9:14:19 | req.cookies | a user-provided value |
| tst.js:31:9:31:10 | v3 | tst.js:30:17:30:27 | req.cookies | tst.js:31:9:31:10 | v3 | This condition guards a sensitive $@, but $@ controls it. | tst.js:33:9:33:22 | process.exit() | action | tst.js:30:17:30:27 | req.cookies | a user-provided value |
| tst.js:37:13:37:32 | req.cookies.cookieId | tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:39:13:39:26 | process.exit() | action | tst.js:37:13:37:23 | req.cookies | a user-provided value |
| tst.js:43:9:43:28 | req.cookies.cookieId | tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:46:13:46:26 | process.exit() | action | tst.js:43:9:43:19 | req.cookies | a user-provided value |
| tst.js:50:8:50:23 | req.params.login | tst.js:50:8:50:23 | req.params.login | tst.js:50:8:50:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:54:9:54:15 | login() | action | tst.js:50:8:50:23 | req.params.login | a user-provided value |
| tst.js:65:8:65:23 | req.params.login | tst.js:65:8:65:23 | req.params.login | tst.js:65:8:65:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:67:9:67:15 | login() | action | tst.js:65:8:65:23 | req.params.login | a user-provided value |
| tst.js:90:9:90:41 | req.coo ... secret" | tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:41 | req.coo ... secret" | This condition guards a sensitive $@, but $@ controls it. | tst.js:92:9:92:22 | process.exit() | action | tst.js:90:9:90:19 | req.cookies | a user-provided value |
| tst.js:111:13:111:32 | req.query.vulnerable | tst.js:111:13:111:32 | req.query.vulnerable | tst.js:111:13:111:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:114:9:114:16 | verify() | action | tst.js:111:13:111:32 | req.query.vulnerable | a user-provided value |
| tst.js:118:13:118:32 | req.query.vulnerable | tst.js:118:13:118:32 | req.query.vulnerable | tst.js:118:13:118:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:121:13:121:20 | verify() | action | tst.js:118:13:118:32 | req.query.vulnerable | a user-provided value |
| tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | This condition guards a sensitive $@, but $@ controls it. | tst.js:10:9:10:22 | process.exit() | action | tst.js:9:8:9:26 | req.params.shutDown | a user-provided value |
| tst.js:13:9:13:30 | req.coo ... inThing | tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing | This condition guards a sensitive $@, but $@ controls it. | tst.js:14:9:14:17 | o.login() | action | tst.js:13:9:13:19 | req.cookies | a user-provided value |
| tst.js:28:9:28:10 | v3 | tst.js:27:17:27:27 | req.cookies | tst.js:28:9:28:10 | v3 | This condition guards a sensitive $@, but $@ controls it. | tst.js:29:9:29:22 | process.exit() | action | tst.js:27:17:27:27 | req.cookies | a user-provided value |
| tst.js:33:13:33:32 | req.cookies.cookieId | tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:34:13:34:26 | process.exit() | action | tst.js:33:13:33:23 | req.cookies | a user-provided value |
| tst.js:38:9:38:28 | req.cookies.cookieId | tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:40:13:40:26 | process.exit() | action | tst.js:38:9:38:19 | req.cookies | a user-provided value |
| tst.js:44:8:44:23 | req.params.login | tst.js:44:8:44:23 | req.params.login | tst.js:44:8:44:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:47:9:47:15 | login() | action | tst.js:44:8:44:23 | req.params.login | a user-provided value |
| tst.js:57:8:57:23 | req.params.login | tst.js:57:8:57:23 | req.params.login | tst.js:57:8:57:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:58:9:58:15 | login() | action | tst.js:57:8:57:23 | req.params.login | a user-provided value |
| tst.js:78:9:78:41 | req.coo ... secret" | tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:41 | req.coo ... secret" | This condition guards a sensitive $@, but $@ controls it. | tst.js:79:9:79:22 | process.exit() | action | tst.js:78:9:78:19 | req.cookies | a user-provided value |
| tst.js:98:13:98:32 | req.query.vulnerable | tst.js:98:13:98:32 | req.query.vulnerable | tst.js:98:13:98:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:101:9:101:16 | verify() | action | tst.js:98:13:98:32 | req.query.vulnerable | a user-provided value |
| tst.js:105:13:105:32 | req.query.vulnerable | tst.js:105:13:105:32 | req.query.vulnerable | tst.js:105:13:105:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:108:13:108:20 | verify() | action | tst.js:105:13:105:32 | req.query.vulnerable | a user-provided value |

View File

@@ -1,6 +1,6 @@
| tst-different-kinds-comparison-bypass.js:7:5:7:42 | req.que ... .userId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst-different-kinds-comparison-bypass.js:7:5:7:20 | req.query.userId | req.query.userId | tst-different-kinds-comparison-bypass.js:7:25:7:35 | req.cookies | req.cookies |
| tst-different-kinds-comparison-bypass.js:11:5:11:23 | req.url == req.body | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst-different-kinds-comparison-bypass.js:11:5:11:11 | req.url | req.url | tst-different-kinds-comparison-bypass.js:11:16:11:23 | req.body | req.body |
| tst-different-kinds-comparison-bypass.js:16:9:16:14 | a == b | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst-different-kinds-comparison-bypass.js:13:11:13:26 | req.query.userId | req.query.userId | tst-different-kinds-comparison-bypass.js:13:29:13:39 | req.cookies | req.cookies |
| tst.js:70:9:70:53 | req.coo ... questId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:70:9:70:19 | req.cookies | req.cookies | tst.js:70:34:70:53 | req.params.requestId | req.params.requestId |
| tst.js:75:14:75:58 | req.coo ... questId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:75:14:75:24 | req.cookies | req.cookies | tst.js:75:39:75:58 | req.params.requestId | req.params.requestId |
| tst.js:82:16:82:22 | p === q | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:84:18:84:28 | req.cookies | req.cookies | tst.js:84:40:84:59 | req.params.requestId | req.params.requestId |
| tst.js:61:9:61:53 | req.coo ... questId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:61:9:61:19 | req.cookies | req.cookies | tst.js:61:34:61:53 | req.params.requestId | req.params.requestId |
| tst.js:65:14:65:58 | req.coo ... questId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:65:14:65:24 | req.cookies | req.cookies | tst.js:65:39:65:58 | req.params.requestId | req.params.requestId |
| tst.js:71:16:71:22 | p === q | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:73:18:73:28 | req.cookies | req.cookies | tst.js:73:40:73:59 | req.params.requestId | req.params.requestId |

View File

@@ -6,18 +6,15 @@ app.get('/user/:id', function(req, res) {
// OK
process.exit();
if(req.params.shutDown) {
// NOT OK: depends on user input
if(req.params.shutDown) { // NOT OK: depends on user input
process.exit();
}
if (req.cookies.loginThing) {
// NOT OK: depends on user input
if (req.cookies.loginThing) { // NOT OK: depends on user input
o.login();
}
if (req.cookies.loginThing) {
// OK: not a sensitive action
if (req.cookies.loginThing) { // OK: not a sensitive action
o.getLogin();
}
@@ -28,67 +25,57 @@ app.get('/user/:id', function(req, res) {
return v;
}
var v3 = id(req.cookies.cookieId);
if (v3) {
// NOT OK, depends on user input
if (v3) { // NOT OK, depends on user input
process.exit();
}
if (otherCondition) {
if (req.cookies.cookieId) {
// NOT OK: depends on user input
if (req.cookies.cookieId) { // NOT OK: depends on user input
process.exit();
}
}
if (req.cookies.cookieId) {
if (req.cookies.cookieId) { // OK: but flagged anyway due to plain dominance analysis [INCONSISTENCY]
if (otherCondition) {
// OK: but flagged anyway due to plain dominance analysis
process.exit();
}
}
if(req.params.login) {
if(req.params.login) { // NOT OK: depends on user input
} else {
// NOT OK: depends on user input
login()
}
if(req.params.login && somethingElse) {
if(req.params.login && somethingElse) { // OK: depends on something else
} else {
// OK: depends on something else
login()
}
if(req.params.login && somethingElse) {
// NOT OK: depends on user input
if(req.params.login && somethingElse) { // NOT OK: depends on user input
login()
}
if (req.cookies.cookieId === req.params.requestId) {
// NOT OK: depends on user input
if (req.cookies.cookieId === req.params.requestId) { // NOT OK: depends on user input
process.exit();
}
var v1 = req.cookies.cookieId === req.params.requestId;
var v1 = req.cookies.cookieId === req.params.requestId; // NOT OK: depends on user input
if (v1) {
// NOT OK: depends on user input
process.exit();
}
function cmp(p, q) {
return p === q;
}
var v2 = cmp(req.cookies.cookieId, req.params.requestId);
var v2 = cmp(req.cookies.cookieId, req.params.requestId); // NOT OK, but not detected due to flow limitations [INCONSISTENCY]
if (v2) {
// NOT OK, but not detected due to flow limitations
process.exit();
}
if (req.cookies.cookieId === "secret") {
// NOT OK: depends on user input
if (req.cookies.cookieId === "secret") { // NOT OK: depends on user input
process.exit();
}

View File

@@ -35,9 +35,9 @@ function whileLoop(val) {
function useLengthIndirectly(val) {
var ret = [];
var len = val.length;
var len = val.length; // NOT OK!
for (var i = 0; i < len; i++) { // NOT OK!
for (var i = 0; i < len; i++) {
ret.push(val[i]);
}
}

View File

@@ -56,8 +56,8 @@ function returns(val) {
}
}
function lodashThrow(val) { // NOT OK!
_.map(val, function (e) {
function lodashThrow(val) {
_.map(val, function (e) { // NOT OK!
if (!e) {
try {
throw new Error(); // Does not prevent DoS.

View File

@@ -33,7 +33,7 @@ express().get('/some/path', function(req, res) {
foo.indexOf(); // OK
}
if (foo instanceof Array) {
foo.indexOf(); // OK, but still flagged
foo.indexOf(); // OK, but still flagged [INCONSISTENCY]
}
(foo + f()).indexOf(); // OK

View File

@@ -20,8 +20,8 @@ var server = http.createServer(function(req, res) {
request.get(tainted); // NOT OK
var options = {};
options.url = tainted;
request(options); // NOT OK
options.url = tainted; // NOT OK
request(options);
request("http://" + tainted); // NOT OK
@@ -44,7 +44,7 @@ var server = http.createServer(function(req, res) {
request('http://example.com/' + base + '/' + tainted); // NOT OK
request('http://example.com/' + base + ('/' + tainted)); // NOT OK - but not flagged
request('http://example.com/' + base + ('/' + tainted)); // NOT OK - but not flagged [INCONSISTENCY]
request(`http://example.com/?${base}/${tainted}`); // OK

View File

@@ -25,6 +25,20 @@ abstract class ConsistencyConfiguration extends string {
File getAFile() { none() }
}
/**
* A string that either equals a `ConsistencyConfiguration`, or the empty string if no such configuration exists.
*
* Is used internally to match a configuration or lack thereof.
*/
final private class Conf extends string {
Conf() {
this instanceof ConsistencyConfiguration
or
not exists(ConsistencyConfiguration c) and
this = ""
}
}
/**
* A line-comment that asserts whether a result exists at that line or not.
* Can optionally include `[INCONSISTENCY]` to indicate that a consistency issue is expected at the location
@@ -54,22 +68,23 @@ private class AssertionComment extends LineComment {
private DataFlow::Node getASink() { exists(DataFlow::Configuration cfg | cfg.hasFlow(_, result)) }
/**
* Gets all the alerts for consistency consistency checking.
* Gets all the alerts for consistency consistency checking from a configuration `conf`.
*/
private DataFlow::Node alerts() {
result = any(ConsistencyConfiguration res).getAnAlert()
private DataFlow::Node alerts(Conf conf) {
result = any(ConsistencyConfiguration res | res = conf).getAnAlert()
or
not exists(ConsistencyConfiguration r) and
result = getASink()
result = getASink() and
conf = ""
}
/**
* Gets an alert in `file` at `line`.
* Gets an alert in `file` at `line` for configuration `conf`.
* The `line` can be either the first or the last line of the alert.
* And if no expression exists at `line`, then an alert on the next line is used.
*/
private DataFlow::Node getAlert(File file, int line) {
result = alerts() and
private DataFlow::Node getAlert(File file, int line, Conf conf) {
result = alerts(conf) and
result.getFile() = file and
(result.hasLocationInfo(_, _, _, line, _) or result.hasLocationInfo(_, line, _, _, _))
or
@@ -77,7 +92,7 @@ private DataFlow::Node getAlert(File file, int line) {
not exists(Expr e |
e.getFile() = file and [e.getLocation().getStartLine(), e.getLocation().getEndLine()] = line
) and
result = alerts() and
result = alerts(conf) and
result.getFile() = file and
result.hasLocationInfo(_, line + 1, _, _, _)
}
@@ -91,66 +106,70 @@ private AssertionComment getComment(File file, int line) {
}
/**
* Holds if there is a false positive in `file` at `line`
* Holds if there is a false positive in `file` at `line` for configuration `conf`.
*/
private predicate falsePositive(File file, int line, AssertionComment comment) {
exists(getAlert(file, line)) and
private predicate falsePositive(File file, int line, AssertionComment comment, Conf conf) {
exists(getAlert(file, line, conf)) and
comment = getComment(file, line) and
not comment.shouldHaveAlert()
}
/**
* Holds if there is a false negative in `file` at `line`
* Holds if there is a false negative in `file` at `line` for configuration `conf`.
*/
private predicate falseNegative(File file, int line, AssertionComment comment) {
not exists(getAlert(file, line)) and
private predicate falseNegative(File file, int line, AssertionComment comment, Conf conf) {
not exists(getAlert(file, line, conf)) and
comment = getComment(file, line) and
comment.shouldHaveAlert()
}
/**
* Gets a file that should be included for consistency checking.
* Gets a file that should be included for consistency checking for configuration `conf`.
*/
private File getATestFile() {
private File getATestFile(string conf) {
not exists(any(ConsistencyConfiguration res).getAFile()) and
result = any(LineComment comment).getFile()
result = any(LineComment comment).getFile() and
conf = ""
or
result = any(ConsistencyConfiguration res).getAFile()
result = any(ConsistencyConfiguration res | res = conf).getAFile()
}
/**
* Gets a description of the configuration that has a sink in `file` at `line`.
* Gets a description of the configuration that has a sink in `file` at `line` for configuration `conf`.
* Or the empty string
*/
bindingset[file, line]
private string getSinkDescription(File file, int line) {
not exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line))) and result = ""
private string getSinkDescription(File file, int line, Conf conf) {
not exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line, conf))) and
result = ""
or
exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line)) | result = " for " + c)
exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line, conf)) |
result = " for " + c
)
}
/**
* Holds if there is a consistency-issue at `location` with description `msg`.
* Holds if there is a consistency-issue at `location` with description `msg` for configuration `conf`.
* The consistency issue an unexpected false positive/negative.
* Or that false positive/negative was expected, and none were found.
*/
query predicate consistencyIssue(string location, string msg, string commentText) {
query predicate consistencyIssue(string location, string msg, string commentText, Conf conf) {
exists(File file, int line |
file = getATestFile() and location = file.getRelativePath() + ":" + line
file = getATestFile(conf) and location = file.getRelativePath() + ":" + line
|
exists(AssertionComment comment |
comment.getText().trim() = commentText and comment = getComment(file, line)
|
falsePositive(file, line, comment) and
falsePositive(file, line, comment, conf) and
not comment.expectConsistencyError() and
msg = "did not expected an alert, but found an alert" + getSinkDescription(file, line)
msg = "did not expect an alert, but found an alert" + getSinkDescription(file, line, conf)
or
falseNegative(file, line, comment) and
falseNegative(file, line, comment, conf) and
not comment.expectConsistencyError() and
msg = "expected an alert, but found none"
or
not falsePositive(file, line, comment) and
not falseNegative(file, line, comment) and
not falsePositive(file, line, comment, conf) and
not falseNegative(file, line, comment, conf) and
comment.expectConsistencyError() and
msg = "expected consistency issue, but found no such issue (" + comment.getText().trim() + ")"
)