Ruby: model rails/globalid

This commit is contained in:
Alex Ford
2022-11-25 17:15:16 +00:00
parent c779b8f711
commit e321657f59
4 changed files with 200 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
/**
* Provides modeling for `GlobalID`, a library for identifying model instances by URI.
* Version: 1.0.0
* https://github.com/rails/globalid
*/
private import codeql.ruby.ApiGraphs
private import codeql.ruby.Concepts
private import codeql.ruby.DataFlow
private import codeql.ruby.frameworks.ActiveRecord
/**
* Provides modeling for `GlobalID`, a library for identifying model instances by URI.
* Version: 1.0.0
* https://github.com/rails/globalid
*/
module GlobalId {
/** A call to `GlobalID::parse` */
class ParseCall extends DataFlow::CallNode {
ParseCall() { this = API::getTopLevelMember("GlobalID").getAMethodCall("parse") }
}
/** A call to `GlobalID::find` */
class FindCall extends DataFlow::CallNode, OrmInstantiation::Range {
FindCall() { this = API::getTopLevelMember("GlobalID").getAMethodCall("find") }
override predicate methodCallMayAccessField(string methodName) { none() }
}
/** `GlobalID::Locator` */
module Locator {
/** A call to `GlobalID::Locator.locate` */
class LocateCall extends DataFlow::CallNode, OrmInstantiation::Range {
LocateCall() {
this = API::getTopLevelMember("GlobalID").getMember("Locator").getAMethodCall("locate")
}
override predicate methodCallMayAccessField(string methodName) { none() }
}
/** A call to `GlobalID::Locator.locate_signed` */
class LocateSignedCall extends DataFlow::CallNode, OrmInstantiation::Range {
LocateSignedCall() {
this =
API::getTopLevelMember("GlobalID").getMember("Locator").getAMethodCall("locate_signed")
}
override predicate methodCallMayAccessField(string methodName) { none() }
}
/** A call to `GlobalID::Locator.locate_many` */
class LocateManyCall extends DataFlow::CallNode, OrmInstantiation::Range {
LocateManyCall() {
this = API::getTopLevelMember("GlobalID").getMember("Locator").getAMethodCall("locate_many")
}
override predicate methodCallMayAccessField(string methodName) { none() }
}
/** A call to `GlobalID::Locator.locate_many_signed` */
class LocateManySignedCall extends DataFlow::CallNode, OrmInstantiation::Range {
LocateManySignedCall() {
this =
API::getTopLevelMember("GlobalID")
.getMember("Locator")
.getAMethodCall("locate_many_signed")
}
override predicate methodCallMayAccessField(string methodName) { none() }
}
}
// TODO: methods in this module are available to any class that includes it, not just ActiveRecord models
/** `GlobalID::Identification` */
module Identification {
/** A call to `GlobalID::Identification.to_global_id` */
class ToGlobalIdCall extends ActiveRecordInstanceMethodCall {
ToGlobalIdCall() { this.getMethodName() = ["to_global_id", "to_gid"] }
}
/** A call to `GlobalID::Identification.to_gid_param` */
class ToGidParamCall extends ActiveRecordInstanceMethodCall {
ToGidParamCall() { this.getMethodName() = "to_gid_param" }
}
/** A call to `GlobalID::Identification.to_signed_global_id` */
class ToSignedGlobalIdCall extends ActiveRecordInstanceMethodCall {
ToSignedGlobalIdCall() { this.getMethodName() = ["to_signed_global_id", "to_sgid"] }
}
/** A call to `GlobalID::Identification.to_sgid_param` */
class ToSgidParamCall extends ActiveRecordInstanceMethodCall {
ToSgidParamCall() { this.getMethodName() = "to_sgid_param" }
}
}
}
/** Provides modeling for `SignedGlobalID`, a module of the `rails/globalid` library. */
module SignedGlobalId {
/** A call to `SignedGlobalID::parse` */
class ParseCall extends DataFlow::CallNode {
ParseCall() { this = API::getTopLevelMember("SignedGlobalID").getAMethodCall("parse") }
}
/** A call to `SignedGlobalID::find` */
class FindCall extends DataFlow::CallNode, OrmInstantiation::Range {
FindCall() { this = API::getTopLevelMember("SignedGlobalID").getAMethodCall("find") }
override predicate methodCallMayAccessField(string methodName) { none() }
}
}

View File

@@ -0,0 +1,24 @@
locateCalls
| globalid.rb:6:3:6:30 | call to locate |
| globalid.rb:11:3:11:30 | call to locate |
locateSignedCalls
| globalid.rb:16:3:16:38 | call to locate_signed |
| globalid.rb:21:3:21:38 | call to locate_signed |
toGlobalIdCalls
| globalid.rb:5:9:5:33 | call to to_global_id |
| globalid.rb:10:9:10:27 | call to to_gid |
toGidParamCalls
| globalid.rb:35:10:35:34 | call to to_gid_param |
toSignedGlobalIdCalls
| globalid.rb:15:10:15:41 | call to to_signed_global_id |
| globalid.rb:20:10:20:29 | call to to_sgid |
toSgidParamCalls
| globalid.rb:41:11:41:36 | call to to_sgid_param |
globalIdParseCalls
| globalid.rb:36:9:36:27 | call to parse |
globalIdFindCalls
| globalid.rb:37:3:37:19 | call to find |
signedGlobalIdParseCalls
| globalid.rb:42:10:42:35 | call to parse |
signedGlobalIdFindCalls
| globalid.rb:43:3:43:26 | call to find |

View File

@@ -0,0 +1,21 @@
import codeql.ruby.frameworks.GlobalId
query predicate locateCalls(GlobalId::Locator::LocateCall c) { any() }
query predicate locateSignedCalls(GlobalId::Locator::LocateSignedCall c) { any() }
query predicate toGlobalIdCalls(GlobalId::Identification::ToGlobalIdCall c) { any() }
query predicate toGidParamCalls(GlobalId::Identification::ToGidParamCall c) { any() }
query predicate toSignedGlobalIdCalls(GlobalId::Identification::ToSignedGlobalIdCall c) { any() }
query predicate toSgidParamCalls(GlobalId::Identification::ToSgidParamCall c) { any() }
query predicate globalIdParseCalls(GlobalId::ParseCall c) { any() }
query predicate globalIdFindCalls(GlobalId::FindCall c) { any() }
query predicate signedGlobalIdParseCalls(SignedGlobalId::ParseCall c) { any() }
query predicate signedGlobalIdFindCalls(SignedGlobalId::FindCall c) { any() }

View File

@@ -0,0 +1,44 @@
class User < ActiveRecord::Base
end
def m1
gid = User.find(1).to_global_id
GlobalID::Locator.locate gid
end
def m2
gid = User.find(1).to_gid
GlobalID::Locator.locate gid
end
def m3
sgid = User.find(1).to_signed_global_id
GlobalID::Locator.locate_signed sgid
end
def m4
sgid = User.find(1).to_sgid
GlobalID::Locator.locate_signed sgid
end
def m5
gids = User.all.map(&:to_gid)
GlobalID::Locator.locate_many gids
end
def m6
sgids = User.all.map(&:to_sgid)
GlobalID::Locator.locate_many_signed sgids
end
def m7
gidp = User.find(1).to_gid_param
gid = GlobalID.parse gidp
GlobalID.find gid
end
def m8
sgidp = User.find(1).to_sgid_param
sgid = SignedGlobalID.parse sgidp
SignedGlobalID.find sgid
end