rb/stored-xss structure and initial implementation (FileSystemReadAccess sources)

This commit is contained in:
Alex Ford
2021-09-25 19:06:21 +01:00
parent 1c08592637
commit a2084f813e
7 changed files with 165 additions and 16 deletions

View File

@@ -3,7 +3,7 @@
*
* Note, for performance reasons: only import this file if
* `ReflectedXSS::Configuration` is needed, otherwise
* `ReflectedXSSCustomizations` should be imported instead.
* `XSS::ReflectedXSS` should be imported instead.
*/
private import ruby
@@ -14,7 +14,7 @@ import codeql.ruby.TaintTracking
* Provides a taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities.
*/
module ReflectedXSS {
import ReflectedXSSCustomizations::ReflectedXSS
import XSS::ReflectedXSS
/**
* A taint-tracking configuration for detecting "reflected server-side cross-site scripting" vulnerabilities.

View File

@@ -0,0 +1,40 @@
/**
* Provides a taint-tracking configuration for reasoning about stored
* cross-site scripting vulnerabilities.
*
* Note, for performance reasons: only import this file if
* `StoredXSS::Configuration` is needed, otherwise
* `XSS::StoredXSS` should be imported instead.
*/
import ruby
import codeql.ruby.DataFlow
import codeql.ruby.TaintTracking
module StoredXSS {
import XSS::StoredXSS
/**
* A taint-tracking configuration for reasoning about Stored XSS.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "StoredXss" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isSanitizer(DataFlow::Node node) {
super.isSanitizer(node) or
node instanceof Sanitizer
}
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof SanitizerGuard
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalXSSTaintStep(node1, node2)
}
}
}

View File

@@ -1,3 +1,7 @@
/**
* Provides classes and predicates used by the XSS queries.
*/
private import ruby
private import codeql.ruby.DataFlow
private import codeql.ruby.CFG
@@ -7,40 +11,34 @@ private import codeql.ruby.frameworks.ActionController
private import codeql.ruby.frameworks.ActionView
private import codeql.ruby.dataflow.RemoteFlowSources
private import codeql.ruby.dataflow.BarrierGuards
import codeql.ruby.dataflow.internal.DataFlowDispatch
private import codeql.ruby.typetracking.TypeTracker
private import codeql.ruby.dataflow.internal.DataFlowDispatch
/**
* Provides default sources, sinks and sanitizers for detecting
* "reflected server-side cross-site scripting"
* vulnerabilities, as well as extension points for adding your own.
* "server-side cross-site scripting" vulnerabilities, as well as
* extension points for adding your own.
*/
module ReflectedXSS {
private module Shared {
/**
* A data flow source for "reflected server-side cross-site scripting" vulnerabilities.
* A data flow source for "server-side cross-site scripting" vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for "reflected server-side cross-site scripting" vulnerabilities.
* A data flow sink for "server-side cross-site scripting" vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
/**
* A sanitizer for "reflected server-side cross-site scripting" vulnerabilities.
* A sanitizer for "server-side cross-site scripting" vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* A sanitizer guard for "reflected server-side cross-site scripting" vulnerabilities.
* A sanitizer guard for "server-side cross-site scripting" vulnerabilities.
*/
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
/**
* A source of remote user input, considered as a flow source.
*/
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
private class ErbOutputMethodCallArgumentNode extends DataFlow::Node {
private MethodCall call;
@@ -198,3 +196,83 @@ module ReflectedXSS {
)
}
}
/**
* Provides default sources, sinks and sanitizers for detecting
* "reflected cross-site scripting" vulnerabilities, as well as
* extension points for adding your own.
*/
module ReflectedXSS {
/** A data flow source for stored XSS vulnerabilities. */
abstract class Source extends Shared::Source { }
/** A data flow sink for stored XSS vulnerabilities. */
abstract class Sink extends Shared::Sink { }
/** A sanitizer for stored XSS vulnerabilities. */
abstract class Sanitizer extends Shared::Sanitizer { }
/** A sanitizer guard for stored XSS vulnerabilities. */
abstract class SanitizerGuard extends Shared::SanitizerGuard { }
// Consider all arbitrary XSS sinks to be reflected XSS sinks
private class AnySink extends Sink instanceof Shared::Sink { }
// Consider all arbitrary XSS sanitizers to be reflected XSS sanitizers
private class AnySanitizer extends Sanitizer instanceof Shared::Sanitizer { }
// Consider all arbitrary XSS sanitizer guards to be reflected XSS sanitizer guards
private class AnySanitizerGuard extends SanitizerGuard instanceof Shared::SanitizerGuard {
override predicate checks(CfgNode expr, boolean branch) {
Shared::SanitizerGuard.super.checks(expr, branch)
}
}
// Consider all arbitrary XSS taint steps to be reflected XSS taint steps
predicate isAdditionalXSSTaintStep = Shared::isAdditionalXSSTaintStep/2;
/**
* A source of remote user input, considered as a flow source.
*/
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
}
/**
* Provides default sources, sinks and sanitizers for detecting
* "stored server-side cross-site scripting" vulnerabilities, as well as
* extension points for adding your own.
*/
module StoredXSS {
/** A data flow source for stored XSS vulnerabilities. */
abstract class Source extends Shared::Source { }
/** A data flow sink for stored XSS vulnerabilities. */
abstract class Sink extends Shared::Sink { }
/** A sanitizer for stored XSS vulnerabilities. */
abstract class Sanitizer extends Shared::Sanitizer { }
/** A sanitizer guard for stored XSS vulnerabilities. */
abstract class SanitizerGuard extends Shared::SanitizerGuard { }
// Consider all arbitrary XSS sinks to be stored XSS sinks
private class AnySink extends Sink instanceof Shared::Sink { }
// Consider all arbitrary XSS sanitizers to be stored XSS sanitizers
private class AnySanitizer extends Sanitizer instanceof Shared::Sanitizer { }
// Consider all arbitrary XSS sanitizer guards to be stored XSS sanitizer guards
private class AnySanitizerGuard extends SanitizerGuard instanceof Shared::SanitizerGuard {
override predicate checks(CfgNode expr, boolean branch) {
Shared::SanitizerGuard.super.checks(expr, branch)
}
}
// Consider all arbitrary XSS taint steps to be stored XSS taint steps
predicate isAdditionalXSSTaintStep = Shared::isAdditionalXSSTaintStep/2;
/** A file read, considered as a flow source for stored XSS. */
class FileSystemReadAccessAsSource extends Source instanceof FileSystemReadAccess { }
// TODO: Consider `FileNameSource` flowing to script tag `src` attributes and similar
// TODO: ORM database reads as sources
}