mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Refactor Grape framework to be encapsulated properly in Module
This commit is contained in:
@@ -29,293 +29,299 @@ module Grape {
|
||||
not exists(GrapeApiClass parent | this != parent and this = parent.getADescendent())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that extends `Grape::API`.
|
||||
* For example,
|
||||
*
|
||||
* ```rb
|
||||
* class FooAPI < Grape::API
|
||||
* get '/users' do
|
||||
* name = params[:name]
|
||||
* User.where("name = #{name}")
|
||||
* end
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class GrapeApiClass extends DataFlow::ClassNode {
|
||||
GrapeApiClass() {
|
||||
this = grapeApiBaseClass().getADescendentModule() and
|
||||
not exists(DataFlow::ModuleNode m | m = grapeApiBaseClass().asModule() | this = m)
|
||||
/**
|
||||
* A class that extends `Grape::API`.
|
||||
* For example,
|
||||
*
|
||||
* ```rb
|
||||
* class FooAPI < Grape::API
|
||||
* get '/users' do
|
||||
* name = params[:name]
|
||||
* User.where("name = #{name}")
|
||||
* end
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class GrapeApiClass extends DataFlow::ClassNode {
|
||||
GrapeApiClass() {
|
||||
this = grapeApiBaseClass().getADescendentModule() and
|
||||
not exists(DataFlow::ModuleNode m | m = grapeApiBaseClass().asModule() | this = m)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `GrapeEndpoint` defined in this class.
|
||||
*/
|
||||
GrapeEndpoint getAnEndpoint() { result.getApiClass() = this }
|
||||
|
||||
/**
|
||||
* Gets a `self` that possibly refers to an instance of this class.
|
||||
*/
|
||||
DataFlow::LocalSourceNode getSelf() {
|
||||
result = this.getAnInstanceSelf()
|
||||
or
|
||||
// Include the module-level `self` to recover some cases where a block at the module level
|
||||
// is invoked with an instance as the `self`.
|
||||
result = this.getModuleLevelSelf()
|
||||
}
|
||||
}
|
||||
|
||||
private DataFlow::ConstRef grapeApiBaseClass() {
|
||||
result = DataFlow::getConstant("Grape").getConstant("API")
|
||||
}
|
||||
|
||||
private API::Node grapeApiInstance() { result = any(GrapeApiClass cls).getSelf().track() }
|
||||
|
||||
/**
|
||||
* A Grape API endpoint (get, post, put, delete, etc.) call within a `Grape::API` class.
|
||||
*/
|
||||
class GrapeEndpoint extends DataFlow::CallNode {
|
||||
private GrapeApiClass apiClass;
|
||||
|
||||
GrapeEndpoint() {
|
||||
this =
|
||||
apiClass.getAModuleLevelCall(["get", "post", "put", "delete", "patch", "head", "options"])
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTP method for this endpoint (e.g., "GET", "POST", etc.)
|
||||
*/
|
||||
string getHttpMethod() { result = this.getMethodName().toUpperCase() }
|
||||
|
||||
/**
|
||||
* Gets the API class containing this endpoint.
|
||||
*/
|
||||
GrapeApiClass getApiClass() { result = apiClass }
|
||||
|
||||
/**
|
||||
* Gets the block containing the endpoint logic.
|
||||
*/
|
||||
DataFlow::BlockNode getBody() { result = this.getBlock() }
|
||||
|
||||
/**
|
||||
* Gets the path pattern for this endpoint, if specified.
|
||||
*/
|
||||
string getPath() { result = this.getArgument(0).getConstantValue().getString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `GrapeEndpoint` defined in this class.
|
||||
* A `RemoteFlowSource::Range` to represent accessing the
|
||||
* Grape parameters available via the `params` method within an endpoint.
|
||||
*/
|
||||
GrapeEndpoint getAnEndpoint() { result.getApiClass() = this }
|
||||
class GrapeParamsSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeParamsSource() { this.asExpr().getExpr() instanceof GrapeParamsCall }
|
||||
|
||||
/**
|
||||
* Gets a `self` that possibly refers to an instance of this class.
|
||||
*/
|
||||
DataFlow::LocalSourceNode getSelf() {
|
||||
result = this.getAnInstanceSelf()
|
||||
or
|
||||
// Include the module-level `self` to recover some cases where a block at the module level
|
||||
// is invoked with an instance as the `self`.
|
||||
result = this.getModuleLevelSelf()
|
||||
}
|
||||
}
|
||||
override string getSourceType() { result = "Grape::API#params" }
|
||||
|
||||
private DataFlow::ConstRef grapeApiBaseClass() {
|
||||
result = DataFlow::getConstant("Grape").getConstant("API")
|
||||
}
|
||||
|
||||
private API::Node grapeApiInstance() { result = any(GrapeApiClass cls).getSelf().track() }
|
||||
|
||||
/**
|
||||
* A Grape API endpoint (get, post, put, delete, etc.) call within a `Grape::API` class.
|
||||
*/
|
||||
class GrapeEndpoint extends DataFlow::CallNode {
|
||||
private GrapeApiClass apiClass;
|
||||
|
||||
GrapeEndpoint() {
|
||||
this =
|
||||
apiClass.getAModuleLevelCall(["get", "post", "put", "delete", "patch", "head", "options"])
|
||||
override Http::Server::RequestInputKind getKind() {
|
||||
result = Http::Server::parameterInputKind()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTTP method for this endpoint (e.g., "GET", "POST", etc.)
|
||||
* A call to `params` from within a Grape API endpoint or helper method.
|
||||
*/
|
||||
string getHttpMethod() { result = this.getMethodName().toUpperCase() }
|
||||
|
||||
/**
|
||||
* Gets the API class containing this endpoint.
|
||||
*/
|
||||
GrapeApiClass getApiClass() { result = apiClass }
|
||||
|
||||
/**
|
||||
* Gets the block containing the endpoint logic.
|
||||
*/
|
||||
DataFlow::BlockNode getBody() { result = this.getBlock() }
|
||||
|
||||
/**
|
||||
* Gets the path pattern for this endpoint, if specified.
|
||||
*/
|
||||
string getPath() { result = this.getArgument(0).getConstantValue().getString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `RemoteFlowSource::Range` to represent accessing the
|
||||
* Grape parameters available via the `params` method within an endpoint.
|
||||
*/
|
||||
class GrapeParamsSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeParamsSource() { this.asExpr().getExpr() instanceof GrapeParamsCall }
|
||||
|
||||
override string getSourceType() { result = "Grape::API#params" }
|
||||
|
||||
override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `params` from within a Grape API endpoint or helper method.
|
||||
*/
|
||||
private class GrapeParamsCall extends ParamsCallImpl {
|
||||
GrapeParamsCall() {
|
||||
// Params calls within endpoint blocks
|
||||
exists(GrapeApiClass api |
|
||||
this.getMethodName() = "params" and
|
||||
this.getParent+() = api.getADeclaration()
|
||||
)
|
||||
or
|
||||
// Params calls within helper methods (defined in helpers blocks)
|
||||
exists(GrapeApiClass api, DataFlow::CallNode helpersCall |
|
||||
helpersCall = api.getAModuleLevelCall("helpers") and
|
||||
this.getMethodName() = "params" and
|
||||
this.getParent+() = helpersCall.getBlock().asExpr().getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `headers` from within a Grape API endpoint or headers block.
|
||||
* Headers can also be a source of user input.
|
||||
*/
|
||||
class GrapeHeadersSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeHeadersSource() {
|
||||
this.asExpr().getExpr() instanceof GrapeHeadersCall
|
||||
or
|
||||
this.asExpr().getExpr() instanceof GrapeHeadersBlockCall
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "Grape::API#headers" }
|
||||
|
||||
override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `headers` from within a Grape API endpoint.
|
||||
*/
|
||||
private class GrapeHeadersCall extends MethodCall {
|
||||
GrapeHeadersCall() {
|
||||
exists(GrapeEndpoint endpoint |
|
||||
this.getParent+() = endpoint.getBody().asCallableAstNode() and
|
||||
this.getMethodName() = "headers"
|
||||
)
|
||||
or
|
||||
// Also handle cases where headers is called on an instance of a Grape API class
|
||||
this = grapeApiInstance().getAMethodCall("headers").asExpr().getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `request` from within a Grape API endpoint.
|
||||
* The request object can contain user input.
|
||||
*/
|
||||
class GrapeRequestSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeRequestSource() { this.asExpr().getExpr() instanceof GrapeRequestCall }
|
||||
|
||||
override string getSourceType() { result = "Grape::API#request" }
|
||||
|
||||
override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `route_param` from within a Grape API endpoint.
|
||||
* Route parameters are extracted from the URL path and can be a source of user input.
|
||||
*/
|
||||
class GrapeRouteParamSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeRouteParamSource() { this.asExpr().getExpr() instanceof GrapeRouteParamCall }
|
||||
|
||||
override string getSourceType() { result = "Grape::API#route_param" }
|
||||
|
||||
override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `request` from within a Grape API endpoint.
|
||||
*/
|
||||
private class GrapeRequestCall extends MethodCall {
|
||||
GrapeRequestCall() {
|
||||
exists(GrapeEndpoint endpoint |
|
||||
this.getParent+() = endpoint.getBody().asCallableAstNode() and
|
||||
this.getMethodName() = "request"
|
||||
)
|
||||
or
|
||||
// Also handle cases where request is called on an instance of a Grape API class
|
||||
this = grapeApiInstance().getAMethodCall("request").asExpr().getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `route_param` from within a Grape API endpoint.
|
||||
*/
|
||||
private class GrapeRouteParamCall extends MethodCall {
|
||||
GrapeRouteParamCall() {
|
||||
exists(GrapeEndpoint endpoint |
|
||||
this.getParent+() = endpoint.getBody().asExpr().getExpr() and
|
||||
this.getMethodName() = "route_param"
|
||||
)
|
||||
or
|
||||
// Also handle cases where route_param is called on an instance of a Grape API class
|
||||
this = grapeApiInstance().getAMethodCall("route_param").asExpr().getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `headers` block within a Grape API class.
|
||||
* This is different from the headers() method call - this is the DSL block for defining header requirements.
|
||||
*/
|
||||
private class GrapeHeadersBlockCall extends MethodCall {
|
||||
GrapeHeadersBlockCall() {
|
||||
exists(GrapeApiClass api |
|
||||
this.getParent+() = api.getADeclaration() and
|
||||
this.getMethodName() = "headers" and
|
||||
exists(this.getBlock())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `cookies` block within a Grape API class.
|
||||
* This DSL block defines cookie requirements and those cookies are user-controlled.
|
||||
*/
|
||||
private class GrapeCookiesBlockCall extends MethodCall {
|
||||
GrapeCookiesBlockCall() {
|
||||
exists(GrapeApiClass api |
|
||||
this.getParent+() = api.getADeclaration() and
|
||||
this.getMethodName() = "cookies" and
|
||||
exists(this.getBlock())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `cookies` method from within a Grape API endpoint or cookies block.
|
||||
* Similar to headers, cookies can be accessed as a method and are user-controlled input.
|
||||
*/
|
||||
class GrapeCookiesSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeCookiesSource() {
|
||||
this.asExpr().getExpr() instanceof GrapeCookiesCall
|
||||
or
|
||||
this.asExpr().getExpr() instanceof GrapeCookiesBlockCall
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "Grape::API#cookies" }
|
||||
|
||||
override Http::Server::RequestInputKind getKind() { result = Http::Server::cookieInputKind() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `cookies` method from within a Grape API endpoint.
|
||||
*/
|
||||
private class GrapeCookiesCall extends MethodCall {
|
||||
GrapeCookiesCall() {
|
||||
exists(GrapeEndpoint endpoint |
|
||||
this.getParent+() = endpoint.getBody().asCallableAstNode() and
|
||||
this.getMethodName() = "cookies"
|
||||
)
|
||||
or
|
||||
// Also handle cases where cookies is called on an instance of a Grape API class
|
||||
this = grapeApiInstance().getAMethodCall("cookies").asExpr().getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A method defined within a `helpers` block in a Grape API class.
|
||||
* These methods become available in endpoint contexts through Grape's DSL.
|
||||
*/
|
||||
private class GrapeHelperMethod extends Method {
|
||||
private GrapeApiClass apiClass;
|
||||
|
||||
GrapeHelperMethod() {
|
||||
exists(DataFlow::CallNode helpersCall |
|
||||
helpersCall = apiClass.getAModuleLevelCall("helpers") and
|
||||
this.getParent+() = helpersCall.getBlock().asExpr().getExpr()
|
||||
)
|
||||
private class GrapeParamsCall extends ParamsCallImpl {
|
||||
GrapeParamsCall() {
|
||||
// Params calls within endpoint blocks
|
||||
exists(GrapeApiClass api |
|
||||
this.getMethodName() = "params" and
|
||||
this.getParent+() = api.getADeclaration()
|
||||
)
|
||||
or
|
||||
// Params calls within helper methods (defined in helpers blocks)
|
||||
exists(GrapeApiClass api, DataFlow::CallNode helpersCall |
|
||||
helpersCall = api.getAModuleLevelCall("helpers") and
|
||||
this.getMethodName() = "params" and
|
||||
this.getParent+() = helpersCall.getBlock().asExpr().getExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the API class that contains this helper method.
|
||||
* A call to `headers` from within a Grape API endpoint or headers block.
|
||||
* Headers can also be a source of user input.
|
||||
*/
|
||||
GrapeApiClass getApiClass() { result = apiClass }
|
||||
}
|
||||
class GrapeHeadersSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeHeadersSource() {
|
||||
this.asExpr().getExpr() instanceof GrapeHeadersCall
|
||||
or
|
||||
this.asExpr().getExpr() instanceof GrapeHeadersBlockCall
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional call-target to resolve helper method calls defined in `helpers` blocks.
|
||||
*
|
||||
* This class is responsible for resolving calls to helper methods defined in
|
||||
* `helpers` blocks, allowing the dataflow framework to accurately track
|
||||
* the flow of information between these methods and their call sites.
|
||||
*/
|
||||
private class GrapeHelperMethodTarget extends AdditionalCallTarget {
|
||||
override DataFlowCallable viableTarget(CfgNodes::ExprNodes::CallCfgNode call) {
|
||||
// Find calls to helper methods from within Grape endpoints or other helper methods
|
||||
exists(GrapeHelperMethod helperMethod, MethodCall mc |
|
||||
result.asCfgScope() = helperMethod and
|
||||
mc = call.getAstNode() and
|
||||
mc.getMethodName() = helperMethod.getName() and
|
||||
mc.getParent+() = helperMethod.getApiClass().getADeclaration()
|
||||
)
|
||||
override string getSourceType() { result = "Grape::API#headers" }
|
||||
|
||||
override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `headers` from within a Grape API endpoint.
|
||||
*/
|
||||
private class GrapeHeadersCall extends MethodCall {
|
||||
GrapeHeadersCall() {
|
||||
exists(GrapeEndpoint endpoint |
|
||||
this.getParent+() = endpoint.getBody().asCallableAstNode() and
|
||||
this.getMethodName() = "headers"
|
||||
)
|
||||
or
|
||||
// Also handle cases where headers is called on an instance of a Grape API class
|
||||
this = grapeApiInstance().getAMethodCall("headers").asExpr().getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `request` from within a Grape API endpoint.
|
||||
* The request object can contain user input.
|
||||
*/
|
||||
class GrapeRequestSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeRequestSource() { this.asExpr().getExpr() instanceof GrapeRequestCall }
|
||||
|
||||
override string getSourceType() { result = "Grape::API#request" }
|
||||
|
||||
override Http::Server::RequestInputKind getKind() {
|
||||
result = Http::Server::parameterInputKind()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `route_param` from within a Grape API endpoint.
|
||||
* Route parameters are extracted from the URL path and can be a source of user input.
|
||||
*/
|
||||
class GrapeRouteParamSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeRouteParamSource() { this.asExpr().getExpr() instanceof GrapeRouteParamCall }
|
||||
|
||||
override string getSourceType() { result = "Grape::API#route_param" }
|
||||
|
||||
override Http::Server::RequestInputKind getKind() {
|
||||
result = Http::Server::parameterInputKind()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `request` from within a Grape API endpoint.
|
||||
*/
|
||||
private class GrapeRequestCall extends MethodCall {
|
||||
GrapeRequestCall() {
|
||||
exists(GrapeEndpoint endpoint |
|
||||
this.getParent+() = endpoint.getBody().asCallableAstNode() and
|
||||
this.getMethodName() = "request"
|
||||
)
|
||||
or
|
||||
// Also handle cases where request is called on an instance of a Grape API class
|
||||
this = grapeApiInstance().getAMethodCall("request").asExpr().getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `route_param` from within a Grape API endpoint.
|
||||
*/
|
||||
private class GrapeRouteParamCall extends MethodCall {
|
||||
GrapeRouteParamCall() {
|
||||
exists(GrapeEndpoint endpoint |
|
||||
this.getParent+() = endpoint.getBody().asExpr().getExpr() and
|
||||
this.getMethodName() = "route_param"
|
||||
)
|
||||
or
|
||||
// Also handle cases where route_param is called on an instance of a Grape API class
|
||||
this = grapeApiInstance().getAMethodCall("route_param").asExpr().getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `headers` block within a Grape API class.
|
||||
* This is different from the headers() method call - this is the DSL block for defining header requirements.
|
||||
*/
|
||||
private class GrapeHeadersBlockCall extends MethodCall {
|
||||
GrapeHeadersBlockCall() {
|
||||
exists(GrapeApiClass api |
|
||||
this.getParent+() = api.getADeclaration() and
|
||||
this.getMethodName() = "headers" and
|
||||
exists(this.getBlock())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `cookies` block within a Grape API class.
|
||||
* This DSL block defines cookie requirements and those cookies are user-controlled.
|
||||
*/
|
||||
private class GrapeCookiesBlockCall extends MethodCall {
|
||||
GrapeCookiesBlockCall() {
|
||||
exists(GrapeApiClass api |
|
||||
this.getParent+() = api.getADeclaration() and
|
||||
this.getMethodName() = "cookies" and
|
||||
exists(this.getBlock())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `cookies` method from within a Grape API endpoint or cookies block.
|
||||
* Similar to headers, cookies can be accessed as a method and are user-controlled input.
|
||||
*/
|
||||
class GrapeCookiesSource extends Http::Server::RequestInputAccess::Range {
|
||||
GrapeCookiesSource() {
|
||||
this.asExpr().getExpr() instanceof GrapeCookiesCall
|
||||
or
|
||||
this.asExpr().getExpr() instanceof GrapeCookiesBlockCall
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "Grape::API#cookies" }
|
||||
|
||||
override Http::Server::RequestInputKind getKind() { result = Http::Server::cookieInputKind() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `cookies` method from within a Grape API endpoint.
|
||||
*/
|
||||
private class GrapeCookiesCall extends MethodCall {
|
||||
GrapeCookiesCall() {
|
||||
exists(GrapeEndpoint endpoint |
|
||||
this.getParent+() = endpoint.getBody().asCallableAstNode() and
|
||||
this.getMethodName() = "cookies"
|
||||
)
|
||||
or
|
||||
// Also handle cases where cookies is called on an instance of a Grape API class
|
||||
this = grapeApiInstance().getAMethodCall("cookies").asExpr().getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A method defined within a `helpers` block in a Grape API class.
|
||||
* These methods become available in endpoint contexts through Grape's DSL.
|
||||
*/
|
||||
private class GrapeHelperMethod extends Method {
|
||||
private GrapeApiClass apiClass;
|
||||
|
||||
GrapeHelperMethod() {
|
||||
exists(DataFlow::CallNode helpersCall |
|
||||
helpersCall = apiClass.getAModuleLevelCall("helpers") and
|
||||
this.getParent+() = helpersCall.getBlock().asExpr().getExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the API class that contains this helper method.
|
||||
*/
|
||||
GrapeApiClass getApiClass() { result = apiClass }
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional call-target to resolve helper method calls defined in `helpers` blocks.
|
||||
*
|
||||
* This class is responsible for resolving calls to helper methods defined in
|
||||
* `helpers` blocks, allowing the dataflow framework to accurately track
|
||||
* the flow of information between these methods and their call sites.
|
||||
*/
|
||||
private class GrapeHelperMethodTarget extends AdditionalCallTarget {
|
||||
override DataFlowCallable viableTarget(CfgNodes::ExprNodes::CallCfgNode call) {
|
||||
// Find calls to helper methods from within Grape endpoints or other helper methods
|
||||
exists(GrapeHelperMethod helperMethod, MethodCall mc |
|
||||
result.asCfgScope() = helperMethod and
|
||||
mc = call.getAstNode() and
|
||||
mc.getMethodName() = helperMethod.getName() and
|
||||
mc.getParent+() = helperMethod.getApiClass().getADeclaration()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@ import codeql.ruby.frameworks.Grape
|
||||
import codeql.ruby.Concepts
|
||||
import codeql.ruby.AST
|
||||
|
||||
query predicate grapeApiClasses(GrapeApiClass api) { any() }
|
||||
query predicate grapeApiClasses(Grape::GrapeApiClass api) { any() }
|
||||
|
||||
query predicate grapeEndpoints(GrapeApiClass api, GrapeEndpoint endpoint, string method, string path) {
|
||||
query predicate grapeEndpoints(Grape::GrapeApiClass api, Grape::GrapeEndpoint endpoint, string method, string path) {
|
||||
endpoint = api.getAnEndpoint() and
|
||||
method = endpoint.getHttpMethod() and
|
||||
path = endpoint.getPath()
|
||||
}
|
||||
|
||||
query predicate grapeParams(GrapeParamsSource params) { any() }
|
||||
query predicate grapeParams(Grape::GrapeParamsSource params) { any() }
|
||||
|
||||
query predicate grapeHeaders(GrapeHeadersSource headers) { any() }
|
||||
query predicate grapeHeaders(Grape::GrapeHeadersSource headers) { any() }
|
||||
|
||||
query predicate grapeRequest(GrapeRequestSource request) { any() }
|
||||
query predicate grapeRequest(Grape::GrapeRequestSource request) { any() }
|
||||
|
||||
query predicate grapeRouteParam(GrapeRouteParamSource routeParam) { any() }
|
||||
query predicate grapeRouteParam(Grape::GrapeRouteParamSource routeParam) { any() }
|
||||
|
||||
query predicate grapeCookies(GrapeCookiesSource cookies) { any() }
|
||||
query predicate grapeCookies(Grape::GrapeCookiesSource cookies) { any() }
|
||||
|
||||
Reference in New Issue
Block a user