From 9b9fc186050e8ef326cf1c6e6810255cd22ea7bb Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Wed, 8 Sep 2021 17:48:54 +0100 Subject: [PATCH] Add taint step for Base64.decode64 --- .../UnsafeDeserializationCustomizations.qll | 21 +++++++++++++++++++ .../security/UnsafeDeserializationQuery.qll | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll b/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll index 875081caa48..84e61bd1ece 100644 --- a/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll +++ b/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll @@ -25,6 +25,13 @@ module UnsafeDeserialization { */ abstract class Sanitizer extends DataFlow::Node { } + /** + * Additional taint steps for "unsafe deserialization" vulnerabilities. + */ + predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + base64DecodeTaintStep(fromNode, toNode) + } + /** A source of remote user input, considered as a flow source for unsafe deserialization. */ class RemoteFlowSourceAsSource extends Source { RemoteFlowSourceAsSource() { this instanceof RemoteFlowSource } @@ -59,4 +66,18 @@ module UnsafeDeserialization { this = API::getTopLevelMember("JSON").getAMethodCall(["load", "restore"]).getArgument(0) } } + + /** + * `Base64.decode64` propagates taint from its argument to its return value. + */ + predicate base64DecodeTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + exists(DataFlow::CallNode callNode | + callNode = + API::getTopLevelMember("Base64") + .getAMethodCall(["decode64", "strict_decode64", "urlsafe_decode64"]) + | + fromNode = callNode.getArgument(0) and + toNode = callNode + ) + } } diff --git a/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll b/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll index f8d19ab76f4..d08b73da936 100644 --- a/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll +++ b/ql/lib/codeql/ruby/security/UnsafeDeserializationQuery.qll @@ -27,4 +27,8 @@ class Configuration extends TaintTracking::Configuration { super.isSanitizer(node) or node instanceof UnsafeDeserialization::Sanitizer } + + override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + UnsafeDeserialization::isAdditionalTaintStep(fromNode, toNode) + } }