Skip to content

Commit 1dc0a06

Browse files
authored
Merge pull request github#14679 from hmac/hmac-model-editor-ruby
Ruby: Experimental model editor support
2 parents 6a48e6e + 199c6b2 commit 1dc0a06

19 files changed

+314
-1
lines changed

ruby/ql/lib/codeql/ruby/frameworks/core/Gem.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ module Gem {
5757
}
5858

5959
/** Gets the name of the gem */
60-
string getName() { result = this.getSpecProperty("name").getConstantValue().getString() }
60+
string getName() {
61+
result = this.getSpecProperty("name").getConstantValue().getString() or
62+
result = specCall.getArgument(0).getAValueReachingSink().getConstantValue().getString()
63+
}
6164

6265
/** Gets a path that is loaded when the gem is required */
6366
private string getARequirePath() {

ruby/ql/lib/codeql/ruby/security/CodeInjectionCustomizations.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ private import codeql.ruby.Concepts
44
private import codeql.ruby.Frameworks
55
private import codeql.ruby.dataflow.RemoteFlowSources
66
private import codeql.ruby.dataflow.BarrierGuards
7+
private import codeql.ruby.frameworks.data.internal.ApiGraphModels
78

89
/**
910
* Provides default sources, sinks and sanitizers for detecting
@@ -156,4 +157,8 @@ module CodeInjection {
156157

157158
override FlowState::State getAState() { result instanceof FlowState::Full }
158159
}
160+
161+
private class ExternalCodeInjectionSink extends Sink {
162+
ExternalCodeInjectionSink() { this = ModelOutput::getASinkNode("code-injection").asSink() }
163+
}
159164
}

ruby/ql/lib/codeql/ruby/security/CommandInjectionCustomizations.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import codeql.ruby.dataflow.RemoteFlowSources
99
private import codeql.ruby.Concepts
1010
private import codeql.ruby.Frameworks
1111
private import codeql.ruby.ApiGraphs
12+
private import codeql.ruby.frameworks.data.internal.ApiGraphModels
1213

1314
module CommandInjection {
1415
/**
@@ -52,4 +53,10 @@ module CommandInjection {
5253
this.(DataFlow::CallNode).getMethodName() = "shellescape"
5354
}
5455
}
56+
57+
private class ExternalCommandInjectionSink extends Sink {
58+
ExternalCommandInjectionSink() {
59+
this = ModelOutput::getASinkNode("command-injection").asSink()
60+
}
61+
}
5562
}

ruby/ql/lib/codeql/ruby/security/LogInjectionQuery.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import codeql.ruby.DataFlow
88
import codeql.ruby.TaintTracking
99
import codeql.ruby.dataflow.RemoteFlowSources
1010
import codeql.ruby.frameworks.Core
11+
private import codeql.ruby.frameworks.data.internal.ApiGraphModels
1112

1213
/**
1314
* A data flow source for user input used in log entries.
@@ -50,6 +51,10 @@ class LoggingSink extends Sink {
5051
LoggingSink() { this = any(Logging logging).getAnInput() }
5152
}
5253

54+
private class ExternalLogInjectionSink extends Sink {
55+
ExternalLogInjectionSink() { this = ModelOutput::getASinkNode("log-injection").asSink() }
56+
}
57+
5358
/**
5459
* A call to `String#replace` that replaces `\n` is considered to sanitize the replaced string (reduce false positive).
5560
*/

ruby/ql/lib/codeql/ruby/security/PathInjectionCustomizations.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import codeql.ruby.Concepts
1111
private import codeql.ruby.DataFlow
1212
private import codeql.ruby.dataflow.BarrierGuards
1313
private import codeql.ruby.dataflow.RemoteFlowSources
14+
private import codeql.ruby.frameworks.data.internal.ApiGraphModels
1415

1516
module PathInjection {
1617
/**
@@ -52,4 +53,8 @@ module PathInjection {
5253
class StringConstArrayInclusionCallAsSanitizer extends Sanitizer,
5354
StringConstArrayInclusionCallBarrier
5455
{ }
56+
57+
private class ExternalPathInjectionSink extends Sink {
58+
ExternalPathInjectionSink() { this = ModelOutput::getASinkNode("path-injection").asSink() }
59+
}
5560
}

ruby/ql/lib/codeql/ruby/security/SqlInjectionCustomizations.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ private import codeql.ruby.DataFlow
88
private import codeql.ruby.dataflow.BarrierGuards
99
private import codeql.ruby.dataflow.RemoteFlowSources
1010
private import codeql.ruby.ApiGraphs
11+
private import codeql.ruby.frameworks.data.internal.ApiGraphModels
1112

1213
/**
1314
* Provides default sources, sinks and sanitizers for detecting SQL injection
@@ -56,4 +57,8 @@ module SqlInjection {
5657
{ }
5758

5859
private class SqlSanitizationAsSanitizer extends Sanitizer, SqlSanitization { }
60+
61+
private class ExternalSqlInjectionSink extends Sink {
62+
ExternalSqlInjectionSink() { this = ModelOutput::getASinkNode("sql-injection").asSink() }
63+
}
5964
}

ruby/ql/lib/codeql/ruby/security/UrlRedirectCustomizations.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import codeql.ruby.dataflow.RemoteFlowSources
1111
private import codeql.ruby.dataflow.BarrierGuards
1212
private import codeql.ruby.dataflow.Sanitizers
1313
private import codeql.ruby.frameworks.ActionController
14+
private import codeql.ruby.frameworks.data.internal.ApiGraphModels
1415

1516
/**
1617
* Provides default sources, sinks and sanitizers for detecting
@@ -73,6 +74,10 @@ module UrlRedirect {
7374
}
7475
}
7576

77+
private class ExternalUrlRedirectSink extends Sink {
78+
ExternalUrlRedirectSink() { this = ModelOutput::getASinkNode("url-redirection").asSink() }
79+
}
80+
7681
/**
7782
* A comparison with a constant string, considered as a sanitizer-guard.
7883
*/

ruby/ql/src/queries/modeling/GenerateModel.ql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/**
2+
* @name Generate flow models
3+
* @description Queries to generate source, sink, summary and type models.
4+
* @kind table
5+
* @id rb/utils/modeleditor/generate-model
6+
* @tags modeleditor generate-model framework-mode
7+
*/
8+
19
private import internal.Types
210
private import internal.Summaries
311

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* @name Fetch endpoints for use in the model editor (application mode)
3+
* @description A list of 3rd party endpoints (methods and attributes) used in the codebase. Excludes test and generated code.
4+
* @kind table
5+
* @id rb/utils/modeleditor/application-mode-endpoints
6+
* @tags modeleditor endpoints application-mode
7+
*/
8+
9+
import codeql.ruby.AST
10+
11+
// This query is empty as Application Mode is not yet supported for Ruby.
12+
from
13+
Call usage, string package, string type, string name, string parameters, boolean supported,
14+
string namespace, string version, string supportedType, string classification
15+
where none()
16+
select usage, package, namespace, type, name, parameters, supported, namespace, version,
17+
supportedType, classification
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* @name Fetch endpoints for use in the model editor (framework mode)
3+
* @description A list of endpoints accessible (methods and attributes) for consumers of the library. Excludes test and generated code.
4+
* @kind table
5+
* @id rb/utils/modeleditor/framework-mode-endpoints
6+
* @tags modeleditor endpoints framework-mode
7+
*/
8+
9+
import ruby
10+
import ModelEditor
11+
12+
from PublicEndpointFromSource endpoint
13+
select endpoint, endpoint.getNamespace(), endpoint.getTypeName(), endpoint.getName(),
14+
endpoint.getParameterTypes(), endpoint.getSupportedStatus(), endpoint.getFile().getBaseName(),
15+
endpoint.getSupportedType()

0 commit comments

Comments
 (0)