4
4
5
5
import javascript
6
6
import semmle.javascript.frameworks.HTTP
7
+ private import DataFlow
7
8
8
9
/**
9
10
* Provides classes for working with [Spife](https://github.com/npm/spife) applications.
10
11
*/
11
12
module Spife {
12
- private class TaggedTemplateEntryPoint extends API:: EntryPoint {
13
- TaggedTemplateEntryPoint ( ) { this = "TaggedTemplateEntryPoint" }
14
-
15
- override DataFlow:: SourceNode getASource ( ) { result .asExpr ( ) instanceof TaggedTemplateExpr }
16
- }
17
-
18
13
/**
19
14
* A call to a Spife method that sets up a route.
20
15
*/
21
- private class RouteSetup extends API :: CallNode , Http:: Servers:: StandardRouteSetup {
16
+ private class RouteSetup extends DataFlow :: CallNode , Http:: Servers:: StandardRouteSetup {
22
17
TaggedTemplateExpr template ;
23
18
24
19
RouteSetup ( ) {
25
- exists ( CallExpr templateCall |
26
- this .getCalleeNode ( ) .asExpr ( ) = template and
27
- API:: moduleImport ( [ "@npm/spife/routing" , "spife/routing" ] )
28
- .asSource ( )
29
- .flowsToExpr ( template .getTag ( ) ) and
30
- templateCall .getAChild ( ) = template
31
- )
20
+ this .getCalleeNode ( ) .asExpr ( ) = template and
21
+ API:: moduleImport ( [ "@npm/spife/routing" , "spife/routing" ] )
22
+ .asSource ( )
23
+ .flowsToExpr ( template .getTag ( ) )
32
24
}
33
25
34
26
private string getRoutePattern ( ) {
35
27
// Concatenate the constant parts of the expression
36
28
result =
37
- concat ( Expr e , int i |
29
+ strictconcat ( Expr e , int i |
38
30
e = template .getTemplate ( ) .getElement ( i ) and exists ( e .getStringValue ( ) )
39
31
|
40
32
e .getStringValue ( ) order by i
@@ -53,20 +45,33 @@ module Spife {
53
45
)
54
46
}
55
47
56
- API:: Node getHandlerByName ( string name ) { result = this .getParameter ( 0 ) .getMember ( name ) }
48
+ DataFlow:: SourceNode getHandlerDefinitions ( TypeBackTracker t ) {
49
+ t .start ( ) and
50
+ result = this .getArgument ( 0 ) .getALocalSource ( )
51
+ or
52
+ exists ( TypeBackTracker t2 | result = getHandlerDefinitions ( t2 ) .backtrack ( t2 , t ) )
53
+ }
54
+
55
+ DataFlow:: SourceNode getHandlerDefinitions ( ) {
56
+ result = getHandlerDefinitions ( TypeBackTracker:: end ( ) )
57
+ }
58
+
59
+ DataFlow:: SourceNode getHandlerByName ( string name ) {
60
+ result = getHandlerDefinitions ( ) .getAPropertySource ( name )
61
+ }
57
62
58
- API :: Node getHandlerByRoute ( string method , string path ) {
63
+ DataFlow :: SourceNode getHandlerByRoute ( string method , string path ) {
59
64
exists ( string handlerName |
60
65
this .hasLine ( method , path , handlerName ) and
61
66
result = this .getHandlerByName ( handlerName )
62
67
)
63
68
}
64
69
65
70
override DataFlow:: SourceNode getARouteHandler ( ) {
66
- result = this .getHandlerByRoute ( _, _) .getAValueReachingSink ( ) .( DataFlow:: FunctionNode )
71
+ result = this .getHandlerByRoute ( _, _) .getALocalSource ( ) .( DataFlow:: FunctionNode )
67
72
or
68
73
exists ( DataFlow:: MethodCallNode validation |
69
- validation = this .getHandlerByRoute ( _, _) .getAValueReachingSink ( ) and
74
+ validation = this .getHandlerByRoute ( _, _) .getALocalSource ( ) and
70
75
result = validation .getArgument ( 1 ) .getAFunctionValue ( )
71
76
)
72
77
}
0 commit comments