mirror of
https://github.com/github/codeql.git
synced 2026-05-01 19:55:15 +02:00
Merge pull request #4958 from asgerf/js/angular2
Approved by erik-krogh
This commit is contained in:
@@ -97,6 +97,7 @@ typeInferenceMismatch
|
||||
| promise.js:5:25:5:32 | source() | promise.js:5:8:5:33 | bluebir ... urce()) |
|
||||
| promise.js:10:24:10:31 | source() | promise.js:10:8:10:32 | Promise ... urce()) |
|
||||
| promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise |
|
||||
| rxjs.js:3:1:3:8 | source() | rxjs.js:10:14:10:17 | data |
|
||||
| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:14:10:14:14 | taint |
|
||||
| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:33:14:33:18 | taint |
|
||||
| sanitizer-guards.js:2:11:2:18 | source() | sanitizer-guards.js:4:8:4:8 | x |
|
||||
|
||||
11
javascript/ql/test/library-tests/TaintTracking/rxjs.js
Normal file
11
javascript/ql/test/library-tests/TaintTracking/rxjs.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { map, catchError } from 'rxjs/operators';
|
||||
|
||||
source()
|
||||
.pipe(
|
||||
map(x => x + 'foo'),
|
||||
map(x => x + 'bar'),
|
||||
catchError(err => {})
|
||||
)
|
||||
.subscribe(data => {
|
||||
sink(data)
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({name: 'testPipe'})
|
||||
export class TestPipe implements PipeTransform {
|
||||
transform(value: string, arg?: string): string {
|
||||
document.body.innerHTML = value;
|
||||
return value + arg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Input, Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'mid-component',
|
||||
template: `
|
||||
<sink-component [sink7]="taint"></sink-component>
|
||||
|
||||
\n<sink-component [sink9]="taint" [testAttr]="taint"></sink-component>
|
||||
`
|
||||
})
|
||||
export class InlineComponent {
|
||||
taint: string;
|
||||
|
||||
constructor() {
|
||||
this.taint = source();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<sink-component [sink6]="field"></sink-component>
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Input, Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'mid-component',
|
||||
templateUrl: './mid.component.html'
|
||||
})
|
||||
export class MidComponent {
|
||||
@Input() field: string;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: "sink-component",
|
||||
template: "not important"
|
||||
})
|
||||
export class SinkComponent {
|
||||
sink1: string;
|
||||
sink2: string;
|
||||
sink3: string;
|
||||
sink4: string;
|
||||
sink5: string;
|
||||
sink6: string;
|
||||
sink7: string;
|
||||
sink8: string;
|
||||
sink9: string;
|
||||
|
||||
constructor(private sanitizer: DomSanitizer) {}
|
||||
|
||||
foo() {
|
||||
this.sanitizer.bypassSecurityTrustHtml(this.sink1);
|
||||
this.sanitizer.bypassSecurityTrustHtml(this.sink2);
|
||||
this.sanitizer.bypassSecurityTrustHtml(this.sink3);
|
||||
this.sanitizer.bypassSecurityTrustHtml(this.sink4);
|
||||
this.sanitizer.bypassSecurityTrustHtml(this.sink5);
|
||||
this.sanitizer.bypassSecurityTrustHtml(this.sink6);
|
||||
this.sanitizer.bypassSecurityTrustHtml(this.sink7);
|
||||
this.sanitizer.bypassSecurityTrustHtml(this.sink8);
|
||||
this.sanitizer.bypassSecurityTrustHtml(this.sink9);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<sink-component
|
||||
[sink1]="taint"
|
||||
[sink2]="taint | unknownPipe"
|
||||
[sink3]="taint | unknownPipe:'safe'"
|
||||
[sink4]="taint | testPipe:'safe'"
|
||||
[sink5]="42 | testPipe:taint"
|
||||
(someEvent)="methodOnComponent(taint)"
|
||||
[sink8]="$any(taint)"
|
||||
></sink-component>
|
||||
|
||||
<div *ngFor="let element of taintedArray">
|
||||
<sink-component [sink1]="element"></sink-component>
|
||||
</div>
|
||||
|
||||
<div *ngFor="let element of safeArray">
|
||||
<sink-component [sink2]="element"></sink-component>
|
||||
</div>
|
||||
|
||||
<mid-component [field]="taint"></mid-component>
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: "source-component",
|
||||
templateUrl: "./source.component.html"
|
||||
})
|
||||
export class Source {
|
||||
taint: string;
|
||||
taintedArray: string[];
|
||||
safeArray: string[];
|
||||
|
||||
constructor(private sanitizer: DomSanitizer) {
|
||||
this.taint = source();
|
||||
this.taintedArray = [...source()];
|
||||
this.safeArray = ['a', 'b'];
|
||||
}
|
||||
|
||||
methodOnComponent(x) {
|
||||
this.sanitizer.bypassSecurityTrustHtml(x);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
pipeRef
|
||||
| source.component.html:3:22:3:32 | unknownPipe |
|
||||
| source.component.html:4:22:4:32 | unknownPipe |
|
||||
| source.component.html:5:22:5:29 | testPipe |
|
||||
| source.component.html:6:19:6:26 | testPipe |
|
||||
pipeCall
|
||||
| source.component.html:3:14:3:32 | taint \| unknownPipe |
|
||||
| source.component.html:4:14:4:39 | taint \| ... :'safe' |
|
||||
| source.component.html:5:14:5:36 | taint \| ... :'safe' |
|
||||
| source.component.html:6:14:6:32 | 42 \| testPipe:taint |
|
||||
pipeCallArg
|
||||
| 0 | source.component.html:3:14:3:18 | taint | source.component.html:3:14:3:32 | taint \| unknownPipe |
|
||||
| 0 | source.component.html:4:14:4:18 | taint | source.component.html:4:14:4:39 | taint \| ... :'safe' |
|
||||
| 0 | source.component.html:5:14:5:18 | taint | source.component.html:5:14:5:36 | taint \| ... :'safe' |
|
||||
| 0 | source.component.html:6:14:6:15 | 42 | source.component.html:6:14:6:32 | 42 \| testPipe:taint |
|
||||
| 1 | source.component.html:4:34:4:39 | 'safe' | source.component.html:4:14:4:39 | taint \| ... :'safe' |
|
||||
| 1 | source.component.html:5:31:5:36 | 'safe' | source.component.html:5:14:5:36 | taint \| ... :'safe' |
|
||||
| 1 | source.component.html:6:28:6:32 | taint | source.component.html:6:14:6:32 | 42 \| testPipe:taint |
|
||||
pipeClass
|
||||
| TestPipe.ts:4:8:9:1 | class T ... ;\\n }\\n} |
|
||||
pipeClassRef
|
||||
| TestPipe.ts:4:8:9:1 | class T ... ;\\n }\\n} | source.component.html:5:22:5:29 | testPipe |
|
||||
| TestPipe.ts:4:8:9:1 | class T ... ;\\n }\\n} | source.component.html:6:19:6:26 | testPipe |
|
||||
taintFlow
|
||||
| inline.component.ts:15:22:15:29 | source() | sink.component.ts:28:48:28:57 | this.sink7 |
|
||||
| inline.component.ts:15:22:15:29 | source() | sink.component.ts:30:48:30:57 | this.sink9 |
|
||||
| source.component.ts:14:22:14:29 | source() | TestPipe.ts:6:31:6:35 | value |
|
||||
| source.component.ts:14:22:14:29 | source() | sink.component.ts:22:48:22:57 | this.sink1 |
|
||||
| source.component.ts:14:22:14:29 | source() | sink.component.ts:25:48:25:57 | this.sink4 |
|
||||
| source.component.ts:14:22:14:29 | source() | sink.component.ts:26:48:26:57 | this.sink5 |
|
||||
| source.component.ts:14:22:14:29 | source() | sink.component.ts:27:48:27:57 | this.sink6 |
|
||||
| source.component.ts:14:22:14:29 | source() | sink.component.ts:29:48:29:57 | this.sink8 |
|
||||
| source.component.ts:14:22:14:29 | source() | source.component.ts:20:48:20:48 | x |
|
||||
| source.component.ts:15:33:15:40 | source() | sink.component.ts:22:48:22:57 | this.sink1 |
|
||||
testAttrSourceLocation
|
||||
| inline.component.ts:8:43:8:61 | [testAttr]=taint | inline.component.ts:8:55:8:59 | <toplevel> |
|
||||
34
javascript/ql/test/library-tests/frameworks/Angular2/test.ql
Normal file
34
javascript/ql/test/library-tests/frameworks/Angular2/test.ql
Normal file
@@ -0,0 +1,34 @@
|
||||
import javascript
|
||||
private import semmle.javascript.security.dataflow.Xss
|
||||
|
||||
query Angular2::PipeRefExpr pipeRef() { any() }
|
||||
|
||||
query CallExpr pipeCall() { result.getCallee() instanceof Angular2::PipeRefExpr }
|
||||
|
||||
query CallExpr pipeCallArg(int i, Expr arg) {
|
||||
result.getCallee() instanceof Angular2::PipeRefExpr and
|
||||
result.getArgument(i) = arg
|
||||
}
|
||||
|
||||
query Angular2::PipeClass pipeClass() { any() }
|
||||
|
||||
query DataFlow::Node pipeClassRef(Angular2::PipeClass cls) { result = cls.getAPipeRef() }
|
||||
|
||||
class TaintConfig extends TaintTracking::Configuration {
|
||||
TaintConfig() { this = "TaintConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source.(DataFlow::CallNode).getCalleeName() = "source"
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink }
|
||||
}
|
||||
|
||||
query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) {
|
||||
any(TaintConfig c).hasFlow(source, sink)
|
||||
}
|
||||
|
||||
query predicate testAttrSourceLocation(HTML::Attribute attrib, Angular2::TemplateTopLevel top) {
|
||||
attrib.getName() = "[testAttr]" and
|
||||
top = attrib.getCodeInAttribute()
|
||||
}
|
||||
Reference in New Issue
Block a user