@@ -51,6 +51,15 @@ module NestJS {
51
51
getAFunctionDecorator ( this ) = nestjs ( ) .getMember ( "Redirect" ) .getACall ( )
52
52
}
53
53
54
+ /**
55
+ * Holds if the return value is sent back in the response.
56
+ */
57
+ predicate isReturnValueReflected ( ) {
58
+ getAFunctionDecorator ( this ) = nestjs ( ) .getMember ( [ "Get" , "Post" ] ) .getACall ( ) and
59
+ not hasRedirectDecorator ( ) and
60
+ not getAFunctionDecorator ( this ) = nestjs ( ) .getMember ( "Render" ) .getACall ( )
61
+ }
62
+
54
63
/** Gets a pipe applied to the inputs of this route handler, not including global pipes. */
55
64
DataFlow:: Node getAPipe ( ) {
56
65
exists ( DataFlow:: CallNode decorator |
@@ -317,6 +326,14 @@ module NestJS {
317
326
}
318
327
}
319
328
329
+ private predicate isStringType ( Type type ) {
330
+ type instanceof StringType
331
+ or
332
+ type instanceof AnyType
333
+ or
334
+ isStringType ( type .( PromiseType ) .getElementType ( ) .unfold ( ) )
335
+ }
336
+
320
337
/**
321
338
* A return value from a route handler, seen as an argument to `res.send()`.
322
339
*
@@ -333,8 +350,13 @@ module NestJS {
333
350
NestJSRouteHandler handler ;
334
351
335
352
ReturnValueAsResponseSend ( ) {
336
- not handler .hasRedirectDecorator ( ) and
337
- this = handler .getAReturn ( ) .asExpr ( )
353
+ handler .isReturnValueReflected ( ) and
354
+ this = handler .getAReturn ( ) .asExpr ( ) and
355
+ // Only returned strings are sinks
356
+ not exists ( Type type |
357
+ type = getType ( ) and
358
+ not isStringType ( type .unfold ( ) )
359
+ )
338
360
}
339
361
340
362
override HTTP:: RouteHandler getRouteHandler ( ) { result = handler }
0 commit comments