Skip to content

Commit afd82e2

Browse files
committed
JS: Add Angular2 model
1 parent a92a701 commit afd82e2

File tree

4 files changed

+343
-0
lines changed

4 files changed

+343
-0
lines changed

javascript/ql/src/javascript.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import semmle.javascript.YAML
6565
import semmle.javascript.dataflow.DataFlow
6666
import semmle.javascript.dataflow.TaintTracking
6767
import semmle.javascript.dataflow.TypeInference
68+
import semmle.javascript.frameworks.Angular2
6869
import semmle.javascript.frameworks.AngularJS
6970
import semmle.javascript.frameworks.AsyncPackage
7071
import semmle.javascript.frameworks.AWS
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/**
2+
* Provides classes for working with Angular (also known as Angular 2.x) applications.
3+
*/
4+
5+
private import javascript
6+
private import semmle.javascript.security.dataflow.Xss
7+
private import semmle.javascript.security.dataflow.CodeInjectionCustomizations
8+
private import semmle.javascript.security.dataflow.ClientSideUrlRedirectCustomizations
9+
private import semmle.javascript.DynamicPropertyAccess
10+
11+
/**
12+
* Provides classes for working with Angular (also known as Angular 2.x) applications.
13+
*/
14+
module Angular2 {
15+
/** Gets a reference to a `Router` object. */
16+
DataFlow::SourceNode router() {
17+
result.hasUnderlyingType("@angular/router", "Router")
18+
}
19+
20+
/** Gets a reference to a `RouterState` object. */
21+
DataFlow::SourceNode routerState() {
22+
result.hasUnderlyingType("@angular/router", "RouterState")
23+
or
24+
result = router().getAPropertyRead("routerState")
25+
}
26+
27+
/** Gets a reference to a `RouterStateSnapshot` object. */
28+
DataFlow::SourceNode routerStateSnapshot() {
29+
result.hasUnderlyingType("@angular/router", "RouterStateSnapshot")
30+
or
31+
result = routerState().getAPropertyRead("snapshot")
32+
}
33+
34+
/** Gets a reference to an `ActivatedRoute` object. */
35+
DataFlow::SourceNode activatedRoute() {
36+
result.hasUnderlyingType("@angular/router", "ActivatedRoute")
37+
}
38+
39+
/** Gets a reference to an `ActivatedRouteSnapshot` object. */
40+
DataFlow::SourceNode activatedRouteSnapshot() {
41+
result.hasUnderlyingType("@angular/router", "ActivatedRouteSnapshot")
42+
or
43+
result = activatedRoute().getAPropertyRead("snapshot")
44+
}
45+
46+
/**
47+
* Gets a data flow node referring to the value of the route property `name`, accessed
48+
* via one of the following patterns:
49+
* ```js
50+
* route.snapshot.name
51+
* route.snapshot.data.name
52+
* route.name.subscribe(x => ...)
53+
* ```
54+
*/
55+
DataFlow::SourceNode activatedRouteProp(string name) {
56+
// this.route.snapshot.foo
57+
result = activatedRouteSnapshot().getAPropertyRead(name)
58+
or
59+
// this.route.snapshot.data.foo
60+
result = activatedRouteSnapshot().getAPropertyRead("data").getAPropertyRead(name)
61+
or
62+
// this.route.foo.subscribe(foo => { ... })
63+
result = activatedRoute().getAPropertyRead(name).getAMethodCall("subscribe").getABoundCallbackParameter(0, 0)
64+
}
65+
66+
/** Gets an array of URL segments matched by some route. */
67+
private DataFlow::SourceNode urlSegmentArray() {
68+
result = activatedRouteProp("url")
69+
}
70+
71+
/** Gets a data flow node referring to a `UrlSegment` object matched by some route. */
72+
DataFlow::SourceNode urlSegment() {
73+
result = getAnEnumeratedArrayElement(urlSegmentArray())
74+
or
75+
result = urlSegmentArray().getAPropertyRead(any(string s | exists(s.toInt())))
76+
}
77+
78+
/** Gets a reference to a `ParamMap` object, usually containing values from the URL. */
79+
DataFlow::SourceNode paramMap() {
80+
result.hasUnderlyingType("@angular/router", "ParamMap")
81+
or
82+
result = activatedRouteProp(["paramMap", "queryParamMap"])
83+
or
84+
result = urlSegment().getAPropertyRead("parameterMap")
85+
}
86+
87+
/** Gets a reference to a `Params` object, usually containing values from the URL. */
88+
DataFlow::SourceNode paramDictionaryObject() {
89+
result.hasUnderlyingType("@angular/router", "Params") and
90+
not result instanceof DataFlow::ObjectLiteralNode // ignore object literals found by contextual typing
91+
or
92+
result = activatedRouteProp(["params", "queryParams"])
93+
or
94+
result = paramMap().getAPropertyRead("params")
95+
or
96+
result = urlSegment().getAPropertyRead("parameters")
97+
}
98+
99+
/**
100+
* A value from `@angular/router` derived from the URL.
101+
*/
102+
class AngularSource extends RemoteFlowSource {
103+
AngularSource() {
104+
this = paramMap().getAMethodCall(["get", "getAll"])
105+
or
106+
this = paramDictionaryObject()
107+
or
108+
this = activatedRouteProp("fragment")
109+
or
110+
this = urlSegment().getAPropertyRead("path")
111+
or
112+
// Note that Router.url and RouterStateSnapshot.url are strings, not UrlSegment[]
113+
this = router().getAPropertyRead("url")
114+
or
115+
this = routerStateSnapshot().getAPropertyRead("url")
116+
}
117+
118+
override string getSourceType() {
119+
result = "Angular route parameter"
120+
}
121+
}
122+
123+
/** Gets a reference to a `DomSanitizer` object. */
124+
DataFlow::SourceNode domSanitizer() {
125+
result.hasUnderlyingType("@angular/platform-browser", "DomSanitizer")
126+
}
127+
128+
/** A value that is about to be promoted to a trusted HTML or CSS value. */
129+
private class AngularXssSink extends DomBasedXss::Sink {
130+
AngularXssSink() { this = domSanitizer().getAMethodCall(["bypassSecurityTrustHtml", "bypassSecurityTrustStyle"]).getArgument(0) }
131+
}
132+
133+
/** A value that is about to be promoted to a trusted script value. */
134+
private class AngularCodeInjectionSink extends CodeInjection::Sink {
135+
AngularCodeInjectionSink() { this = domSanitizer().getAMethodCall(["bypassSecurityTrustScript"]).getArgument(0) }
136+
}
137+
138+
/**
139+
* A value that is about to be promoted to a trusted URL or resource URL value.
140+
*/
141+
private class AngularUrlSink extends ClientSideUrlRedirect::Sink {
142+
// We mark this as a client URL redirect sink for precision reasons, though its description can be a bit confusing.
143+
AngularUrlSink() { this = domSanitizer().getAMethodCall(["bypassSecurityTrustUrl", "bypassSecurityTrustResourceUrl"]).getArgument(0) }
144+
}
145+
146+
private predicate taintStep(DataFlow::Node pred, DataFlow::Node succ) {
147+
exists(DataFlow::CallNode call |
148+
call = DataFlow::moduleMember("@angular/router", "convertToParamMap").getACall()
149+
or
150+
call = router().getAMemberCall(["parseUrl", "serializeUrl"])
151+
|
152+
pred = call.getArgument(0) and
153+
succ = call
154+
)
155+
}
156+
157+
private class AngularTaintStep extends TaintTracking::AdditionalTaintStep {
158+
AngularTaintStep() {
159+
taintStep(_, this)
160+
}
161+
162+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
163+
taintStep(pred, succ)
164+
}
165+
}
166+
167+
/** Gets a reference to an `HttpClient` object. */
168+
DataFlow::SourceNode httpClient() {
169+
result.hasUnderlyingType("@angular/common/http", "HttpClient")
170+
}
171+
172+
private class AngularClientRequest extends ClientRequest::Range, DataFlow::MethodCallNode {
173+
int argumentOffset;
174+
175+
AngularClientRequest() {
176+
this = httpClient().getAMethodCall("request") and argumentOffset = 1
177+
or
178+
this = httpClient().getAMethodCall() and
179+
not getMethodName() = "request" and
180+
argumentOffset = 0
181+
}
182+
183+
override DataFlow::Node getUrl() {
184+
result = getArgument(argumentOffset)
185+
}
186+
187+
override DataFlow::Node getHost() {
188+
none()
189+
}
190+
191+
override DataFlow::Node getADataNode() {
192+
getMethodName() = ["patch", "post", "put"] and
193+
result = getArgument(argumentOffset + 1)
194+
or
195+
result = getOptionArgument(argumentOffset + 1, "body")
196+
}
197+
}
198+
199+
/** Gets a reference to a `DomAdapter`, which provides acess to raw DOM elements. */
200+
private DataFlow::SourceNode domAdapter() {
201+
// Note: these are internal properties, prefixed with the theta character "ɵ".
202+
// Despite being internal, some codebases do access them.
203+
result.hasUnderlyingType("@angular/common", "ɵDomAdapter")
204+
or
205+
result = DataFlow::moduleImport("@angular/common").getAMemberCall("ɵgetDOM")
206+
}
207+
208+
/** A reference to the DOM location obtained through `DomAdapter.getLocation()`. */
209+
private class DomAdapterLocation extends DOM::LocationSource::Range {
210+
DomAdapterLocation() {
211+
this = domAdapter().getAMethodCall("getLocation")
212+
}
213+
}
214+
}

javascript/ql/test/query-tests/Security/CWE-079/Xss.expected

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,50 @@ nodes
1515
| addEventListener.js:12:24:12:28 | event |
1616
| addEventListener.js:12:24:12:33 | event.data |
1717
| addEventListener.js:12:24:12:33 | event.data |
18+
| angular2-client.ts:21:44:21:66 | \\u0275getDOM ... ation() |
19+
| angular2-client.ts:21:44:21:66 | \\u0275getDOM ... ation() |
20+
| angular2-client.ts:21:44:21:71 | \\u0275getDOM ... ().href |
21+
| angular2-client.ts:21:44:21:71 | \\u0275getDOM ... ().href |
22+
| angular2-client.ts:23:44:23:69 | this.ro ... .params |
23+
| angular2-client.ts:23:44:23:69 | this.ro ... .params |
24+
| angular2-client.ts:23:44:23:73 | this.ro ... ams.foo |
25+
| angular2-client.ts:23:44:23:73 | this.ro ... ams.foo |
26+
| angular2-client.ts:24:44:24:74 | this.ro ... yParams |
27+
| angular2-client.ts:24:44:24:74 | this.ro ... yParams |
28+
| angular2-client.ts:24:44:24:78 | this.ro ... ams.foo |
29+
| angular2-client.ts:24:44:24:78 | this.ro ... ams.foo |
30+
| angular2-client.ts:25:44:25:71 | this.ro ... ragment |
31+
| angular2-client.ts:25:44:25:71 | this.ro ... ragment |
32+
| angular2-client.ts:25:44:25:71 | this.ro ... ragment |
33+
| angular2-client.ts:26:44:26:82 | this.ro ... ('foo') |
34+
| angular2-client.ts:26:44:26:82 | this.ro ... ('foo') |
35+
| angular2-client.ts:26:44:26:82 | this.ro ... ('foo') |
36+
| angular2-client.ts:27:44:27:87 | this.ro ... ('foo') |
37+
| angular2-client.ts:27:44:27:87 | this.ro ... ('foo') |
38+
| angular2-client.ts:27:44:27:87 | this.ro ... ('foo') |
39+
| angular2-client.ts:29:46:29:59 | map.get('foo') |
40+
| angular2-client.ts:29:46:29:59 | map.get('foo') |
41+
| angular2-client.ts:29:46:29:59 | map.get('foo') |
42+
| angular2-client.ts:32:44:32:74 | this.ro ... 1].path |
43+
| angular2-client.ts:32:44:32:74 | this.ro ... 1].path |
44+
| angular2-client.ts:32:44:32:74 | this.ro ... 1].path |
45+
| angular2-client.ts:33:44:33:80 | this.ro ... ameters |
46+
| angular2-client.ts:33:44:33:80 | this.ro ... ameters |
47+
| angular2-client.ts:33:44:33:82 | this.ro ... eters.x |
48+
| angular2-client.ts:33:44:33:82 | this.ro ... eters.x |
49+
| angular2-client.ts:34:44:34:91 | this.ro ... et('x') |
50+
| angular2-client.ts:34:44:34:91 | this.ro ... et('x') |
51+
| angular2-client.ts:34:44:34:91 | this.ro ... et('x') |
52+
| angular2-client.ts:35:44:35:89 | this.ro ... .params |
53+
| angular2-client.ts:35:44:35:89 | this.ro ... .params |
54+
| angular2-client.ts:35:44:35:91 | this.ro ... arams.x |
55+
| angular2-client.ts:35:44:35:91 | this.ro ... arams.x |
56+
| angular2-client.ts:37:44:37:58 | this.router.url |
57+
| angular2-client.ts:37:44:37:58 | this.router.url |
58+
| angular2-client.ts:37:44:37:58 | this.router.url |
59+
| angular2-client.ts:41:44:41:76 | routeSn ... ('foo') |
60+
| angular2-client.ts:41:44:41:76 | routeSn ... ('foo') |
61+
| angular2-client.ts:41:44:41:76 | routeSn ... ('foo') |
1862
| exception-xss.js:2:6:2:28 | foo |
1963
| exception-xss.js:2:12:2:28 | document.location |
2064
| exception-xss.js:2:12:2:28 | document.location |
@@ -505,6 +549,34 @@ edges
505549
| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event |
506550
| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data |
507551
| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data |
552+
| angular2-client.ts:21:44:21:66 | \\u0275getDOM ... ation() | angular2-client.ts:21:44:21:71 | \\u0275getDOM ... ().href |
553+
| angular2-client.ts:21:44:21:66 | \\u0275getDOM ... ation() | angular2-client.ts:21:44:21:71 | \\u0275getDOM ... ().href |
554+
| angular2-client.ts:21:44:21:66 | \\u0275getDOM ... ation() | angular2-client.ts:21:44:21:71 | \\u0275getDOM ... ().href |
555+
| angular2-client.ts:21:44:21:66 | \\u0275getDOM ... ation() | angular2-client.ts:21:44:21:71 | \\u0275getDOM ... ().href |
556+
| angular2-client.ts:23:44:23:69 | this.ro ... .params | angular2-client.ts:23:44:23:73 | this.ro ... ams.foo |
557+
| angular2-client.ts:23:44:23:69 | this.ro ... .params | angular2-client.ts:23:44:23:73 | this.ro ... ams.foo |
558+
| angular2-client.ts:23:44:23:69 | this.ro ... .params | angular2-client.ts:23:44:23:73 | this.ro ... ams.foo |
559+
| angular2-client.ts:23:44:23:69 | this.ro ... .params | angular2-client.ts:23:44:23:73 | this.ro ... ams.foo |
560+
| angular2-client.ts:24:44:24:74 | this.ro ... yParams | angular2-client.ts:24:44:24:78 | this.ro ... ams.foo |
561+
| angular2-client.ts:24:44:24:74 | this.ro ... yParams | angular2-client.ts:24:44:24:78 | this.ro ... ams.foo |
562+
| angular2-client.ts:24:44:24:74 | this.ro ... yParams | angular2-client.ts:24:44:24:78 | this.ro ... ams.foo |
563+
| angular2-client.ts:24:44:24:74 | this.ro ... yParams | angular2-client.ts:24:44:24:78 | this.ro ... ams.foo |
564+
| angular2-client.ts:25:44:25:71 | this.ro ... ragment | angular2-client.ts:25:44:25:71 | this.ro ... ragment |
565+
| angular2-client.ts:26:44:26:82 | this.ro ... ('foo') | angular2-client.ts:26:44:26:82 | this.ro ... ('foo') |
566+
| angular2-client.ts:27:44:27:87 | this.ro ... ('foo') | angular2-client.ts:27:44:27:87 | this.ro ... ('foo') |
567+
| angular2-client.ts:29:46:29:59 | map.get('foo') | angular2-client.ts:29:46:29:59 | map.get('foo') |
568+
| angular2-client.ts:32:44:32:74 | this.ro ... 1].path | angular2-client.ts:32:44:32:74 | this.ro ... 1].path |
569+
| angular2-client.ts:33:44:33:80 | this.ro ... ameters | angular2-client.ts:33:44:33:82 | this.ro ... eters.x |
570+
| angular2-client.ts:33:44:33:80 | this.ro ... ameters | angular2-client.ts:33:44:33:82 | this.ro ... eters.x |
571+
| angular2-client.ts:33:44:33:80 | this.ro ... ameters | angular2-client.ts:33:44:33:82 | this.ro ... eters.x |
572+
| angular2-client.ts:33:44:33:80 | this.ro ... ameters | angular2-client.ts:33:44:33:82 | this.ro ... eters.x |
573+
| angular2-client.ts:34:44:34:91 | this.ro ... et('x') | angular2-client.ts:34:44:34:91 | this.ro ... et('x') |
574+
| angular2-client.ts:35:44:35:89 | this.ro ... .params | angular2-client.ts:35:44:35:91 | this.ro ... arams.x |
575+
| angular2-client.ts:35:44:35:89 | this.ro ... .params | angular2-client.ts:35:44:35:91 | this.ro ... arams.x |
576+
| angular2-client.ts:35:44:35:89 | this.ro ... .params | angular2-client.ts:35:44:35:91 | this.ro ... arams.x |
577+
| angular2-client.ts:35:44:35:89 | this.ro ... .params | angular2-client.ts:35:44:35:91 | this.ro ... arams.x |
578+
| angular2-client.ts:37:44:37:58 | this.router.url | angular2-client.ts:37:44:37:58 | this.router.url |
579+
| angular2-client.ts:41:44:41:76 | routeSn ... ('foo') | angular2-client.ts:41:44:41:76 | routeSn ... ('foo') |
508580
| exception-xss.js:2:6:2:28 | foo | exception-xss.js:86:17:86:19 | foo |
509581
| exception-xss.js:2:6:2:28 | foo | exception-xss.js:86:17:86:19 | foo |
510582
| exception-xss.js:2:12:2:28 | document.location | exception-xss.js:2:6:2:28 | foo |
@@ -937,6 +1009,19 @@ edges
9371009
| addEventListener.js:2:20:2:29 | event.data | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:29 | event.data | Cross-site scripting vulnerability due to $@. | addEventListener.js:1:43:1:47 | event | user-provided value |
9381010
| addEventListener.js:6:20:6:23 | data | addEventListener.js:5:43:5:48 | {data} | addEventListener.js:6:20:6:23 | data | Cross-site scripting vulnerability due to $@. | addEventListener.js:5:43:5:48 | {data} | user-provided value |
9391011
| addEventListener.js:12:24:12:33 | event.data | addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:33 | event.data | Cross-site scripting vulnerability due to $@. | addEventListener.js:10:21:10:25 | event | user-provided value |
1012+
| angular2-client.ts:21:44:21:71 | \\u0275getDOM ... ().href | angular2-client.ts:21:44:21:66 | \\u0275getDOM ... ation() | angular2-client.ts:21:44:21:71 | \\u0275getDOM ... ().href | Cross-site scripting vulnerability due to $@. | angular2-client.ts:21:44:21:66 | \\u0275getDOM ... ation() | user-provided value |
1013+
| angular2-client.ts:23:44:23:73 | this.ro ... ams.foo | angular2-client.ts:23:44:23:69 | this.ro ... .params | angular2-client.ts:23:44:23:73 | this.ro ... ams.foo | Cross-site scripting vulnerability due to $@. | angular2-client.ts:23:44:23:69 | this.ro ... .params | user-provided value |
1014+
| angular2-client.ts:24:44:24:78 | this.ro ... ams.foo | angular2-client.ts:24:44:24:74 | this.ro ... yParams | angular2-client.ts:24:44:24:78 | this.ro ... ams.foo | Cross-site scripting vulnerability due to $@. | angular2-client.ts:24:44:24:74 | this.ro ... yParams | user-provided value |
1015+
| angular2-client.ts:25:44:25:71 | this.ro ... ragment | angular2-client.ts:25:44:25:71 | this.ro ... ragment | angular2-client.ts:25:44:25:71 | this.ro ... ragment | Cross-site scripting vulnerability due to $@. | angular2-client.ts:25:44:25:71 | this.ro ... ragment | user-provided value |
1016+
| angular2-client.ts:26:44:26:82 | this.ro ... ('foo') | angular2-client.ts:26:44:26:82 | this.ro ... ('foo') | angular2-client.ts:26:44:26:82 | this.ro ... ('foo') | Cross-site scripting vulnerability due to $@. | angular2-client.ts:26:44:26:82 | this.ro ... ('foo') | user-provided value |
1017+
| angular2-client.ts:27:44:27:87 | this.ro ... ('foo') | angular2-client.ts:27:44:27:87 | this.ro ... ('foo') | angular2-client.ts:27:44:27:87 | this.ro ... ('foo') | Cross-site scripting vulnerability due to $@. | angular2-client.ts:27:44:27:87 | this.ro ... ('foo') | user-provided value |
1018+
| angular2-client.ts:29:46:29:59 | map.get('foo') | angular2-client.ts:29:46:29:59 | map.get('foo') | angular2-client.ts:29:46:29:59 | map.get('foo') | Cross-site scripting vulnerability due to $@. | angular2-client.ts:29:46:29:59 | map.get('foo') | user-provided value |
1019+
| angular2-client.ts:32:44:32:74 | this.ro ... 1].path | angular2-client.ts:32:44:32:74 | this.ro ... 1].path | angular2-client.ts:32:44:32:74 | this.ro ... 1].path | Cross-site scripting vulnerability due to $@. | angular2-client.ts:32:44:32:74 | this.ro ... 1].path | user-provided value |
1020+
| angular2-client.ts:33:44:33:82 | this.ro ... eters.x | angular2-client.ts:33:44:33:80 | this.ro ... ameters | angular2-client.ts:33:44:33:82 | this.ro ... eters.x | Cross-site scripting vulnerability due to $@. | angular2-client.ts:33:44:33:80 | this.ro ... ameters | user-provided value |
1021+
| angular2-client.ts:34:44:34:91 | this.ro ... et('x') | angular2-client.ts:34:44:34:91 | this.ro ... et('x') | angular2-client.ts:34:44:34:91 | this.ro ... et('x') | Cross-site scripting vulnerability due to $@. | angular2-client.ts:34:44:34:91 | this.ro ... et('x') | user-provided value |
1022+
| angular2-client.ts:35:44:35:91 | this.ro ... arams.x | angular2-client.ts:35:44:35:89 | this.ro ... .params | angular2-client.ts:35:44:35:91 | this.ro ... arams.x | Cross-site scripting vulnerability due to $@. | angular2-client.ts:35:44:35:89 | this.ro ... .params | user-provided value |
1023+
| angular2-client.ts:37:44:37:58 | this.router.url | angular2-client.ts:37:44:37:58 | this.router.url | angular2-client.ts:37:44:37:58 | this.router.url | Cross-site scripting vulnerability due to $@. | angular2-client.ts:37:44:37:58 | this.router.url | user-provided value |
1024+
| angular2-client.ts:41:44:41:76 | routeSn ... ('foo') | angular2-client.ts:41:44:41:76 | routeSn ... ('foo') | angular2-client.ts:41:44:41:76 | routeSn ... ('foo') | Cross-site scripting vulnerability due to $@. | angular2-client.ts:41:44:41:76 | routeSn ... ('foo') | user-provided value |
9401025
| exception-xss.js:86:17:86:19 | foo | exception-xss.js:2:12:2:28 | document.location | exception-xss.js:86:17:86:19 | foo | Cross-site scripting vulnerability due to $@. | exception-xss.js:2:12:2:28 | document.location | user-provided value |
9411026
| jquery.js:4:5:4:11 | tainted | jquery.js:2:17:2:33 | document.location | jquery.js:4:5:4:11 | tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
9421027
| jquery.js:7:5:7:34 | "<div i ... + "\\">" | jquery.js:2:17:2:33 | document.location | jquery.js:7:5:7:34 | "<div i ... + "\\">" | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |

0 commit comments

Comments
 (0)