File tree Expand file tree Collapse file tree 3 files changed +29
-12
lines changed
test/library-tests/frameworks/Nest Expand file tree Collapse file tree 3 files changed +29
-12
lines changed Original file line number Diff line number Diff line change 55import javascript
66private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations
77private import semmle.javascript.dataflow.internal.PreCallGraphStep
8+ private import semmle.javascript.internal.NameResolution
89private import semmle.javascript.internal.TypeResolution
910
1011/**
@@ -317,14 +318,6 @@ module NestJS {
317318 }
318319 }
319320
320- private predicate isStringType ( Type type ) {
321- type instanceof StringType
322- or
323- type instanceof AnyType
324- or
325- isStringType ( type .( PromiseType ) .getElementType ( ) .unfold ( ) )
326- }
327-
328321 /**
329322 * A return value from a route handler, seen as an argument to `res.send()`.
330323 *
@@ -343,10 +336,10 @@ module NestJS {
343336 ReturnValueAsResponseSend ( ) {
344337 handler .isReturnValueReflected ( ) and
345338 this = handler .getAReturn ( ) and
346- // Only returned strings are sinks
347- not exists ( Type type |
348- type = this .asExpr ( ) . getType ( ) and
349- not isStringType ( type . unfold ( ) )
339+ // Only returned strings are sinks. If we can find a type for the return value, it must be string-like.
340+ not exists ( NameResolution :: Node type |
341+ TypeResolution :: valueHasType ( this .asExpr ( ) , type ) and
342+ not TypeResolution :: hasUnderlyingStringOrAnyType ( type )
350343 )
351344 }
352345
Original file line number Diff line number Diff line change @@ -360,4 +360,25 @@ module TypeResolution {
360360 * Holds if the given value has a type that implied it is a Promise object. Does not hold for unions unless all parts of the union are promises.
361361 */
362362 predicate valueHasPromiseType = ValueHasProperty< isPromiseType / 1 > :: valueHasProperty / 1 ;
363+
364+ /**
365+ * Holds if `type` contains `string` or `any`, possibly wrapped in a promise.
366+ */
367+ predicate hasUnderlyingStringOrAnyType ( Node type ) {
368+ type .( TypeAnnotation ) .isStringy ( )
369+ or
370+ type .( TypeAnnotation ) .isAny ( )
371+ or
372+ type instanceof StringLiteralTypeExpr
373+ or
374+ type instanceof TemplateLiteralTypeExpr
375+ or
376+ exists ( Node mid | hasUnderlyingStringOrAnyType ( mid ) |
377+ TypeFlow:: step ( mid , type )
378+ or
379+ UnderlyingTypes:: underlyingTypeStep ( mid , type )
380+ or
381+ type = unwrapPromiseType ( mid )
382+ )
383+ }
363384}
Original file line number Diff line number Diff line change @@ -71,6 +71,9 @@ responseSendArgument
7171| local/customPipe.ts:37:16:37:31 | '' + unsanitized |
7272| local/customPipe.ts:42:16:42:31 | '' + unsanitized |
7373| local/customPipe.ts:48:16:48:31 | '' + unsanitized |
74+ | local/routes.ts:7:12:7:16 | 'foo' |
75+ | local/routes.ts:12:12:12:16 | 'foo' |
76+ | local/routes.ts:17:12:17:16 | 'foo' |
7477| local/routes.ts:32:31:32:31 | x |
7578| local/routes.ts:33:31:33:38 | queryObj |
7679| local/routes.ts:34:31:34:34 | name |
You can’t perform that action at this time.
0 commit comments