Skip to content

Commit b07c5c6

Browse files
committed
JS: Add test
1 parent 4b2c7ef commit b07c5c6

File tree

6 files changed

+51
-5
lines changed

6 files changed

+51
-5
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Module } from '@nestjs/common';
2+
import { Controller } from './validation';
3+
import { Foo } from './foo.interface';
4+
import { FooImpl } from './foo.impl';
5+
6+
@Module({
7+
controllers: [Controller],
8+
providers: [{
9+
provide: Foo, useClass: FooImpl
10+
}],
11+
})
12+
export class AppModule { }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Foo } from "./foo.interface";
2+
3+
export class FooImpl extends Foo {
4+
fooMethod(x: string) {
5+
sink(x); // $ MISSING: hasValueFlow=x
6+
}
7+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export abstract class Foo {
2+
abstract fooMethod(x: string): void;
3+
}

javascript/ql/test/library-tests/frameworks/Nest/global/validation.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
import { Get, Query } from '@nestjs/common';
22
import { IsIn } from 'class-validator';
3+
import { Foo } from './foo.interface';
34

45
export class Controller {
6+
constructor(
7+
private readonly foo: Foo
8+
) { }
9+
510
@Get()
611
route1(@Query('x') validatedObj: Struct, @Query('y') unvalidated: string) {
712
if (Math.random()) return unvalidated; // NOT OK
813
return validatedObj.key; // OK
914
}
15+
16+
@Get()
17+
route2(@Query('x') x: string) {
18+
this.foo.fooMethod(x);
19+
}
1020
}
1121

1222
class Struct {

javascript/ql/test/library-tests/frameworks/Nest/test.expected

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
testFailures
12
routeHandler
2-
| global/validation.ts:6:3:9:3 | route1( ... OK\\n } |
3+
| global/validation.ts:11:3:14:3 | route1( ... OK\\n } |
4+
| global/validation.ts:17:3:19:3 | route2( ... x);\\n } |
35
| local/customDecorator.ts:18:3:20:3 | sneaky( ... OK\\n } |
46
| local/customDecorator.ts:23:3:25:3 | safe(@S ... OK\\n } |
57
| local/customPipe.ts:20:5:22:5 | sanitiz ... K\\n } |
@@ -36,8 +38,9 @@ requestInputAccess
3638
| body | local/routes.ts:40:16:40:19 | body |
3739
| body | local/routes.ts:66:26:66:29 | file |
3840
| body | local/routes.ts:71:31:71:35 | files |
39-
| parameter | global/validation.ts:6:22:6:33 | validatedObj |
40-
| parameter | global/validation.ts:6:56:6:66 | unvalidated |
41+
| parameter | global/validation.ts:11:22:11:33 | validatedObj |
42+
| parameter | global/validation.ts:11:56:11:66 | unvalidated |
43+
| parameter | global/validation.ts:17:22:17:22 | x |
4144
| parameter | local/customDecorator.ts:6:12:6:41 | request ... ryParam |
4245
| parameter | local/customPipe.ts:5:15:5:19 | value |
4346
| parameter | local/customPipe.ts:13:15:13:19 | value |
@@ -58,8 +61,8 @@ requestInputAccess
5861
| parameter | local/validation.ts:42:22:42:33 | validatedObj |
5962
| parameter | local/validation.ts:42:56:42:66 | unvalidated |
6063
responseSendArgument
61-
| global/validation.ts:7:31:7:41 | unvalidated |
62-
| global/validation.ts:8:12:8:27 | validatedObj.key |
64+
| global/validation.ts:12:31:12:41 | unvalidated |
65+
| global/validation.ts:13:12:13:27 | validatedObj.key |
6366
| local/customDecorator.ts:19:12:19:16 | value |
6467
| local/customDecorator.ts:24:12:24:16 | value |
6568
| local/customPipe.ts:21:16:21:29 | '' + sanitized |

javascript/ql/test/library-tests/frameworks/Nest/test.ql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import javascript
22
private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations
3+
private import utils.test.InlineFlowTest
34

45
query Http::RouteHandler routeHandler() { any() }
56

@@ -17,3 +18,13 @@ query RemoteFlowSource requestInputAccess(string kind) {
1718
query Http::ResponseSendArgument responseSendArgument() { any() }
1819

1920
query ServerSideUrlRedirect::Sink redirectSink() { any() }
21+
22+
module TestConfig implements DataFlow::ConfigSig {
23+
predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource }
24+
25+
predicate isSink(DataFlow::Node node) {
26+
exists(DataFlow::CallNode call | call.getCalleeName() = "sink" and node = call.getArgument(0))
27+
}
28+
}
29+
30+
import ValueFlowTest<TestConfig>

0 commit comments

Comments
 (0)