diff --git a/ruby/ql/src/queries/modeling/GenerateModel.ql b/ruby/ql/src/queries/modeling/GenerateModel.ql index be2572c1a63..0fc469418b5 100644 --- a/ruby/ql/src/queries/modeling/GenerateModel.ql +++ b/ruby/ql/src/queries/modeling/GenerateModel.ql @@ -1,10 +1,11 @@ // TODO: metadata private import internal.Types +private import internal.Sources private import internal.Sinks query predicate typeModel = Types::typeModel/3; -query predicate sourceModel(string type, string path, string kind) { none() } +query predicate sourceModel = Sources::sourceModel/3; query predicate sinkModel = Sinks::sinkModel/3; diff --git a/ruby/ql/src/queries/modeling/internal/Sinks.qll b/ruby/ql/src/queries/modeling/internal/Sinks.qll index a941ff55132..4199b3f4cec 100644 --- a/ruby/ql/src/queries/modeling/internal/Sinks.qll +++ b/ruby/ql/src/queries/modeling/internal/Sinks.qll @@ -13,56 +13,129 @@ private import Util as Util // TODO: there is probably a more sensible central location for this module module Sinks { - private module SinkKinds { - class Kind extends string { - Kind() { - this = - [ - "code-injection", "command-injection", "path-injection", "sql-injection", - "nosql-injection", "html-injection", "request-forgery", "url-redirection", - "unsafe-deserialization" - ] - } + private module Configs { + signature class KindSig { + predicate isSink(DataFlow::Node node); + + predicate isSanitizer(DataFlow::Node node); + + string getKind(); } - Kind codeInjection() { result = "code-injection" } + signature class SinkSig extends DataFlow::Node; - Kind commandInjection() { result = "command-injection" } + signature class SanitizerSig extends DataFlow::Node; - Kind pathInjection() { result = "path-injection" } + abstract class MCustomization { + abstract DataFlow::Node getSink(); + abstract DataFlow::Node getSanitizer(); +abstract string getKind(); + } - Kind sqlInjection() { result = "sql-injection" } + module SKind implements KindSig { + predicate isSink(DataFlow::Node node) { node instanceof Customization::Sink } - Kind nosqlInjection() { result = "nosql-injection" } + predicate isSanitizer(DataFlow::Node node) { node instanceof Customization::Sanitizer } - Kind htmlInjection() { result = "html-injection" } + string getKind() { Customization::isKind(result) } + } - Kind requestForgery() { result = "request-forgery" } + module MCodeInjection implements MCustomization { + import CodeInjection - Kind urlRedirection() { result = "url-redirection" } + predicate isKind(string k) { k = "code-injection" } + } - Kind unsafeDeserialization() { result = "unsafe-deserialization" } + module CodeInjectionKind = SKind; + + module MCommandInjection implements MCustomization { + import CommandInjection + + predicate isKind(string k) { k = "command-injection" } + } + + module CommandInjectionKind = SKind; + + module MPathInjection implements MCustomization { + import PathInjection + + predicate isKind(string k) { k = "path-injection" } + } + + module PathInjectionKind = SKind; + + module MSqlInjection implements MCustomization { + import SqlInjection + + predicate isKind(string k) { k = "sql-injection" } + } + + module SqlInjectionKind = SKind; + + module HtmlInjection implements MCustomization { + import ReflectedXss as R + import StoredXss as S + + class Sanitizer extends DataFlow::Node { + Sanitizer() { this instanceof R::Sanitizer or this instanceof S::Sanitizer } + } + + class Sink extends DataFlow::Node { + Sink() { this instanceof R::Sink or this instanceof S::Sink } + } + + predicate isKind(string k) { k = "sql-injection" } + } + + module HtmlInjectionKind = SKind; + + module MRequestForgery implements MCustomization { + import ServerSideRequestForgery + + predicate isKind(string k) { k = "request-forgery" } + } + + module RequestForgeryKind = SKind; + + module MUrlRedirection implements MCustomization { + import UrlRedirect + + predicate isKind(string k) { k = "url-redirection" } + } + + module UrlRedirectionKind = SKind; + + module MUnsafeDeserialization implements MCustomization { + import UnsafeDeserialization + + predicate isKind(string k) { k = "unsafe-deserialization" } + } + + module UnsafeDeserializationKind = SKind; } - private DataFlow::Node getTaintSinkOfKind(SinkKinds::Kind kind) { + private DataFlow::Node getTaintSinkOfKind(string kind) { result.getLocation().getFile() instanceof Util::RelevantFile and - ( - kind = SinkKinds::codeInjection() and result instanceof CodeInjection::Sink - or - kind = SinkKinds::commandInjection() and result instanceof CommandInjection::Sink - or - kind = SinkKinds::htmlInjection() and - (result instanceof ReflectedXss::Sink or result instanceof StoredXss::Sink) - or - kind = SinkKinds::pathInjection() and result instanceof PathInjection::Sink - or - kind = SinkKinds::requestForgery() and result instanceof ServerSideRequestForgery::Sink - or - kind = SinkKinds::unsafeDeserialization() and result instanceof UnsafeDeserialization::Sink - or - kind = SinkKinds::urlRedirection() and result instanceof UrlRedirect::Sink - or - kind = SinkKinds::sqlInjection() and result instanceof SqlInjection::Sink +( +kind = Configs::CodeInjectionKind::getKind() + and + + // kind = SinkKinds::codeInjection() and result instanceof Configs::CodeInjectionKind::Sink + // or + // kind = SinkKinds::commandInjection() and result instanceof CommandInjection::Sink + // or + // kind = SinkKinds::htmlInjection() and + // (result instanceof ReflectedXss::Sink or result instanceof StoredXss::Sink) + // or + // kind = SinkKinds::pathInjection() and result instanceof PathInjection::Sink + // or + // kind = SinkKinds::requestForgery() and result instanceof ServerSideRequestForgery::Sink + // or + // kind = SinkKinds::unsafeDeserialization() and result instanceof UnsafeDeserialization::Sink + // or + // kind = SinkKinds::urlRedirection() and result instanceof UrlRedirect::Sink + // or + // kind = SinkKinds::sqlInjection() and result instanceof SqlInjection::Sink ) and // the sink is not a string literal not exists(Ast::StringLiteral str |