Ruby: use the 'customizations' pattern for the SQL injection query

This commit is contained in:
Nick Rolfe
2022-11-10 11:51:47 +00:00
parent e7576fdd1a
commit 4a98ef064e
3 changed files with 65 additions and 19 deletions

View File

@@ -0,0 +1,45 @@
/**
* Provides default sources, sinks and sanitizers for detecting SQL injection
* vulnerabilities, as well as extension points for adding your own.
*/
private import codeql.ruby.Concepts
private import codeql.ruby.DataFlow
private import codeql.ruby.dataflow.BarrierGuards
private import codeql.ruby.dataflow.RemoteFlowSources
/**
* Provides default sources, sinks and sanitizers for detecting SQL injection
* vulnerabilities, as well as extension points for adding your own.
*/
module SqlInjection {
abstract class Source extends DataFlow::Node { }
abstract class Sink extends DataFlow::Node { }
abstract class Sanitizer extends DataFlow::Node { }
/**
* A source of remote user input, considered as a flow source.
*/
private class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
/**
* A SQL statement of a SQL execution, considered as a flow sink.
*/
private class SqlExecutionAsSink extends Sink {
SqlExecutionAsSink() { this = any(SqlExecution e).getSql() }
}
/**
* A comparison with a constant string, considered as a sanitizer-guard.
*/
private class StringConstCompareAsSanitizerGuard extends Sanitizer, StringConstCompareBarrier { }
/**
* An inclusion check against an array of constant strings, considered as a
* sanitizer-guard.
*/
class StringConstArrayInclusionCallAsSanitizer extends Sanitizer,
StringConstArrayInclusionCallBarrier { }
}

View File

@@ -0,0 +1,18 @@
/**
* Provides default sources, sinks and sanitizers for detecting SQL injection
* vulnerabilities, as well as extension points for adding your own.
*/
private import codeql.ruby.DataFlow
private import codeql.ruby.TaintTracking
import SqlInjectionCustomizations::SqlInjection
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "SqlInjectionConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node source) { source instanceof Sink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}

View File

@@ -11,28 +11,11 @@
* external/cwe/cwe-089 * external/cwe/cwe-089
*/ */
import codeql.ruby.AST
import codeql.ruby.Concepts
import codeql.ruby.DataFlow import codeql.ruby.DataFlow
import codeql.ruby.dataflow.BarrierGuards import codeql.ruby.security.SqlInjectionQuery
import codeql.ruby.dataflow.RemoteFlowSources
import codeql.ruby.TaintTracking
import DataFlow::PathGraph import DataFlow::PathGraph
class SqlInjectionConfiguration extends TaintTracking::Configuration { from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
SqlInjectionConfiguration() { this = "SQLInjectionConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof SqlExecution }
override predicate isSanitizer(DataFlow::Node node) {
node instanceof StringConstCompareBarrier or
node instanceof StringConstArrayInclusionCallBarrier
}
}
from SqlInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink) where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "This SQL query depends on a $@.", source.getNode(), select sink.getNode(), source, sink, "This SQL query depends on a $@.", source.getNode(),
"user-provided value" "user-provided value"