Ruby: add rb/log-inection query

This commit is contained in:
Alex Ford
2022-08-10 16:16:54 +01:00
parent cce39fb2ce
commit c31995764b
2 changed files with 89 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
/**
* Provides a taint-tracking configuration for reasoning about untrusted user input used in log entries.
*/
import ruby
import codeql.ruby.Concepts
import codeql.ruby.DataFlow
import codeql.ruby.TaintTracking
import codeql.ruby.dataflow.RemoteFlowSources
import codeql.ruby.frameworks.Core
/**
* A data flow source for user input used in log entries.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for user input used in log entries.
*/
abstract class Sink extends DataFlow::Node { }
/**
* A sanitizer for malicious user input used in log entries.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* A taint-tracking configuration for untrusted user input used in log entries.
*/
class LogInjectionConfiguration extends TaintTracking::Configuration {
LogInjectionConfiguration() { this = "LogInjection" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A source of remote user controlled input.
*/
class RemoteSource extends Source instanceof RemoteFlowSource { }
/**
* An input to a logging mechanism.
*/
class LoggingSink extends Sink {
LoggingSink() { this = any(Logging logging).getAnInput() }
}
/**
* A call to `String#replace` that replaces `\n` is considered to sanitize the replaced string (reduce false positive).
*/
class StringReplaceSanitizer extends Sanitizer {
StringReplaceSanitizer() {
exists(string s | this.(StringSubstitutionCall).replaces(s, "") and s.regexpMatch("\\n")) and
// exclude replacement methods that may not fully sanitize the string
this.(StringSubstitutionCall).isGlobal()
}
}
/**
* A call to an HTML escape method is considered to sanitize its input.
*/
class HtmlEscapingAsSanitizer extends Sanitizer {
HtmlEscapingAsSanitizer() { this = any(HtmlEscaping esc).getOutput() }
}

View File

@@ -0,0 +1,21 @@
/**
* @name Log injection
* @description Building log entries from user-controlled sources is vulnerable to
* insertion of forged log entries by a malicious user.
* @kind path-problem
* @problem.severity error
* @security-severity 7.8
* @precision medium
* @id rb/log-injection
* @tags security
* external/cwe/cwe-117
*/
import ruby
import DataFlow::PathGraph
import codeql.ruby.security.LogInjectionQuery
from LogInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows to log entry.", source.getNode(),
"User-provided value"