Ruby: Add InsecureDownload query

This query finds cases where a potentially unsafe file is downloaded
over an unsecured connection.
This commit is contained in:
Harry Maclean
2022-04-05 10:07:56 +12:00
parent ce7675ef43
commit bb3fb0325b
9 changed files with 404 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
failures
| insecure_download.rb:5:36:5:63 | # $BAD= (requires hash flow) | Missing result:BAD= |
edges
| insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | insecure_download.rb:33:15:33:17 | url |
| insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | insecure_download.rb:33:15:33:17 | url |
nodes
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | semmle.label | "http://example.org/unsafe.APK" |
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | semmle.label | "http://example.org/unsafe.APK" |
| insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | semmle.label | "http://example.org/unsafe.APK" : |
| insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | semmle.label | "http://example.org/unsafe.APK" : |
| insecure_download.rb:33:15:33:17 | url | semmle.label | url |
| insecure_download.rb:33:15:33:17 | url | semmle.label | url |
| insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | semmle.label | "http://example.org/unsafe" |
| insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | semmle.label | "http://example.org/unsafe" |
| insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | semmle.label | "http://example.org/unsafe.unk..." |
| insecure_download.rb:53:65:53:78 | "/myscript.sh" | semmle.label | "/myscript.sh" |
subpaths
#select
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | "http://example.org/unsafe.APK" |
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | "http://example.org/unsafe.APK" |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | insecure_download.rb:33:15:33:17 | url | $@ | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | "http://example.org/unsafe.APK" : |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | insecure_download.rb:33:15:33:17 | url | $@ | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | "http://example.org/unsafe.APK" : |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | $@ | insecure_download.rb:33:15:33:17 | url | url |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | $@ | insecure_download.rb:33:15:33:17 | url | url |
| insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | $@ | insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | "http://example.org/unsafe" |
| insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | $@ | insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | "http://example.org/unsafe" |
| insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | $@ | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | "http://example.org/unsafe.unk..." |
| insecure_download.rb:53:65:53:78 | "/myscript.sh" | insecure_download.rb:53:65:53:78 | "/myscript.sh" | insecure_download.rb:53:65:53:78 | "/myscript.sh" | $@ | insecure_download.rb:53:65:53:78 | "/myscript.sh" | "/myscript.sh" |

View File

@@ -0,0 +1,22 @@
import ruby
import codeql.ruby.DataFlow
import PathGraph
import TestUtilities.InlineFlowTest
import codeql.ruby.security.InsecureDownloadQuery
class FlowTest extends InlineFlowTest {
override DataFlow::Configuration getValueFlowConfig() { result = any(Configuration config) }
override DataFlow::Configuration getTaintFlowConfig() { none() }
override string getARelevantTag() { result = "BAD" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "BAD" and
super.hasActualResult(location, element, "hasValueFlow", value)
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, Configuration conf
where conf.hasFlowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

View File

@@ -0,0 +1,55 @@
require "excon"
def foo
def download_tools(installer)
Excon.get(installer[:url]) # $BAD= (requires hash flow)
end
constants = {
build_tools: {
installer_url: 'http://download.microsoft.com/download/5/f/7/5f7acaeb-8363-451f-9425-68a90f98b238/visualcppbuildtools_full.exe'
}
}
def get_build_tools_installer_path
build_tools = constants[:build_tools]
{ url: build_tools[:installer_url] }
end
download_tools get_build_tools_installer_path
end
def bar
Excon.get('http://www.google.com') # GOOD
Excon.get("https://download.microsoft.com/download/5/f/7/5f7acaeb-8363-451f-9425-68a90f98b238/visualcppbuildtools_full.exe") # GOOD
Excon.get("http://example.org/unsafe.APK") # $BAD=
end
def baz
url = "http://example.org/unsafe.APK"
Excon.get(url) # $BAD=
end
def test
File.open("foo.exe").write(Excon.get("http://example.org/unsafe").body) # $BAD=
File.open("foo.safe").write(Excon.get("http://example.org/unsafe").body) # GOOD
File.write("foo.exe", Excon.get("http://example.org/unsafe").body) # $BAD=
resp = Excon.get("http://example.org/unsafe.unknown") # $BAD=
file = File.open("unsafe.exe", "w")
file.write(resp.body)
resp = Excon.get("http://example.org/unsafe.unknown")
file = File.open("foo.safe", "w")
file.write(resp.body) # GOOD
end
def sh
script = Net::HTTP.new("http://mydownload.example.org").get("/myscript.sh").body # $BAD=
system(script)
end