66private import codeql.ruby.AST
77private import codeql.ruby.Concepts
88private import codeql.ruby.ApiGraphs
9+ private import codeql.ruby.DataFlow
10+ private import codeql.ruby.dataflow.RemoteFlowSources
911private import codeql.ruby.frameworks.stdlib.Logger:: Logger as StdlibLogger
1012
1113/**
@@ -26,4 +28,33 @@ module ActionCable {
2628 }
2729 }
2830 }
31+
32+ /**
33+ * The data argument in an RPC endpoint method on a subclass of
34+ * `ActionCable::Channel::Base`, considered as a remote flow source.
35+ */
36+ class ActionCableChannelRpcParam extends RemoteFlowSource:: Range {
37+ ActionCableChannelRpcParam ( ) {
38+ exists ( DataFlow:: MethodNode m |
39+ // Any method on a subclass of `ActionCable::Channel::Base`
40+ // automatically becomes an RPC endpoint
41+ m =
42+ DataFlow:: getConstant ( "ActionCable" )
43+ .getConstant ( "Channel" )
44+ .getConstant ( "Base" )
45+ .getADescendentModule ( )
46+ .getAnOwnInstanceMethod ( ) and
47+ // as long as it's public
48+ m .asCallableAstNode ( ) .isPublic ( ) and
49+ // and is not called `subscribed` or `unsubscribed`.
50+ not m .getMethodName ( ) = [ "subscribed" , "unsubscribed" ]
51+ |
52+ // If the method takes a parameter, it contains data from the remote
53+ // request.
54+ this = m .getParameter ( 0 )
55+ )
56+ }
57+
58+ override string getSourceType ( ) { result = "ActionCable channel RPC data" }
59+ }
2960}
0 commit comments