JS: Add test

This commit is contained in:
Asger F
2025-01-29 13:42:34 +01:00
parent 4b2c7ef03f
commit b07c5c6ee0
6 changed files with 51 additions and 5 deletions

View File

@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { Controller } from './validation';
import { Foo } from './foo.interface';
import { FooImpl } from './foo.impl';
@Module({
controllers: [Controller],
providers: [{
provide: Foo, useClass: FooImpl
}],
})
export class AppModule { }

View File

@@ -0,0 +1,7 @@
import { Foo } from "./foo.interface";
export class FooImpl extends Foo {
fooMethod(x: string) {
sink(x); // $ MISSING: hasValueFlow=x
}
}

View File

@@ -0,0 +1,3 @@
export abstract class Foo {
abstract fooMethod(x: string): void;
}

View File

@@ -1,12 +1,22 @@
import { Get, Query } from '@nestjs/common';
import { IsIn } from 'class-validator';
import { Foo } from './foo.interface';
export class Controller {
constructor(
private readonly foo: Foo
) { }
@Get()
route1(@Query('x') validatedObj: Struct, @Query('y') unvalidated: string) {
if (Math.random()) return unvalidated; // NOT OK
return validatedObj.key; // OK
}
@Get()
route2(@Query('x') x: string) {
this.foo.fooMethod(x);
}
}
class Struct {

View File

@@ -1,5 +1,7 @@
testFailures
routeHandler
| global/validation.ts:6:3:9:3 | route1( ... OK\\n } |
| global/validation.ts:11:3:14:3 | route1( ... OK\\n } |
| global/validation.ts:17:3:19:3 | route2( ... x);\\n } |
| local/customDecorator.ts:18:3:20:3 | sneaky( ... OK\\n } |
| local/customDecorator.ts:23:3:25:3 | safe(@S ... OK\\n } |
| local/customPipe.ts:20:5:22:5 | sanitiz ... K\\n } |
@@ -36,8 +38,9 @@ requestInputAccess
| body | local/routes.ts:40:16:40:19 | body |
| body | local/routes.ts:66:26:66:29 | file |
| body | local/routes.ts:71:31:71:35 | files |
| parameter | global/validation.ts:6:22:6:33 | validatedObj |
| parameter | global/validation.ts:6:56:6:66 | unvalidated |
| parameter | global/validation.ts:11:22:11:33 | validatedObj |
| parameter | global/validation.ts:11:56:11:66 | unvalidated |
| parameter | global/validation.ts:17:22:17:22 | x |
| parameter | local/customDecorator.ts:6:12:6:41 | request ... ryParam |
| parameter | local/customPipe.ts:5:15:5:19 | value |
| parameter | local/customPipe.ts:13:15:13:19 | value |
@@ -58,8 +61,8 @@ requestInputAccess
| parameter | local/validation.ts:42:22:42:33 | validatedObj |
| parameter | local/validation.ts:42:56:42:66 | unvalidated |
responseSendArgument
| global/validation.ts:7:31:7:41 | unvalidated |
| global/validation.ts:8:12:8:27 | validatedObj.key |
| global/validation.ts:12:31:12:41 | unvalidated |
| global/validation.ts:13:12:13:27 | validatedObj.key |
| local/customDecorator.ts:19:12:19:16 | value |
| local/customDecorator.ts:24:12:24:16 | value |
| local/customPipe.ts:21:16:21:29 | '' + sanitized |

View File

@@ -1,5 +1,6 @@
import javascript
private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations
private import utils.test.InlineFlowTest
query Http::RouteHandler routeHandler() { any() }
@@ -17,3 +18,13 @@ query RemoteFlowSource requestInputAccess(string kind) {
query Http::ResponseSendArgument responseSendArgument() { any() }
query ServerSideUrlRedirect::Sink redirectSink() { any() }
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node node) {
exists(DataFlow::CallNode call | call.getCalleeName() = "sink" and node = call.getArgument(0))
}
}
import ValueFlowTest<TestConfig>