Merge pull request #11022 from hmac/try-code-injection

Ruby: try/try! as code execution
This commit is contained in:
Harry Maclean
2022-11-08 09:42:52 +13:00
committed by GitHub
5 changed files with 47 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `ActiveSupport` extensions `Object#try` and `Object#try!` are now recognised as code executions.

View File

@@ -81,6 +81,29 @@ module ActiveSupport {
preservesValue = true
}
}
/**
* A call to `Object#try`, which may execute its first argument as a Ruby
* method call.
* ```rb
* x = "abc"
* x.try(:upcase) # => "ABC"
* y = nil
* y.try(:upcase) # => nil
* ```
* `Object#try!` behaves similarly but raises `NoMethodError` if the
* receiver is not `nil` and does not respond to the method.
*/
class TryCallCodeExecution extends CodeExecution::Range, DataFlow::CallNode {
TryCallCodeExecution() {
this.asExpr().getExpr() instanceof UnknownMethodCall and
this.getMethodName() = ["try", "try!"]
}
override DataFlow::Node getCode() { result = this.getArgument(0) }
override predicate runsArbitraryCode() { none() }
}
}
/**

View File

@@ -5,3 +5,12 @@ constantizeCalls
loggerInstantiations
| active_support.rb:6:1:6:33 | call to new |
| active_support.rb:7:1:7:40 | call to new |
codeExecutions
| active_support.rb:1:1:1:22 | call to constantize |
| active_support.rb:3:1:3:13 | call to constantize |
| active_support.rb:4:1:4:18 | call to safe_constantize |
| active_support.rb:296:5:296:18 | call to try |
| active_support.rb:297:5:297:17 | call to try |
| active_support.rb:298:5:298:19 | call to try! |
| active_support.rb:298:5:298:35 | call to try! |
| active_support.rb:299:5:299:18 | call to try! |

View File

@@ -1,9 +1,12 @@
import codeql.ruby.frameworks.ActiveSupport
import codeql.ruby.DataFlow
import codeql.ruby.frameworks.stdlib.Logger
import codeql.ruby.Concepts
query DataFlow::Node constantizeCalls(ActiveSupport::CoreExtensions::String::Constantize c) {
result = c.getCode()
}
query predicate loggerInstantiations(Logger::LoggerInstantiation l) { any() }
query predicate codeExecutions(CodeExecution c) { any() }

View File

@@ -290,3 +290,11 @@ def m_deep_dup
x = source "a"
sink x.deep_dup # $hasValueFlow=a
end
def m_try(method)
x = "abc"
x.try(:upcase)
x.try(method)
x.try!(:upcase).try!(:downcase)
x.try!(method)
end