This commit is contained in:
Owen Mansel-Chan
2026-06-10 22:57:52 +02:00
parent 8e07690049
commit 9ea3e9088c
191 changed files with 1401 additions and 1346 deletions

View File

@@ -1 +1 @@
library-tests/dataflow/type-tracker/TypeTracker.ql
query: library-tests/dataflow/type-tracker/TypeTracker.ql

View File

@@ -1 +1 @@
AlertSuppression.ql
query: AlertSuppression.ql

View File

@@ -1 +1 @@
queries/analysis/Definitions.ql
query: queries/analysis/Definitions.ql

View File

@@ -1 +1 @@
queries/diagnostics/ExtractedFiles.ql
query: queries/diagnostics/ExtractedFiles.ql

View File

@@ -1 +1 @@
queries/diagnostics/ExtractionErrors.ql
query: queries/diagnostics/ExtractionErrors.ql

View File

@@ -1 +1 @@
queries/diagnostics/ExtractionWarnings.ql
query: queries/diagnostics/ExtractionWarnings.ql

View File

@@ -1 +1 @@
queries/summary/NumberOfFilesExtractedWithErrors.ql
query: queries/summary/NumberOfFilesExtractedWithErrors.ql

View File

@@ -1 +1 @@
queries/summary/NumberOfSuccessfullyExtractedFiles.ql
query: queries/summary/NumberOfSuccessfullyExtractedFiles.ql

View File

@@ -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 |

View File

@@ -1 +1,2 @@
experimental/CWE-522-DecompressionBombs/DecompressionBombs.ql
query: experimental/CWE-522-DecompressionBombs/DecompressionBombs.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -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

View File

@@ -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 |

View File

@@ -1 +1,2 @@
experimental/ldap-improper-auth/ImproperLdapAuth.ql
query: experimental/ldap-improper-auth/ImproperLdapAuth.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -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 |

View File

@@ -1 +1,2 @@
experimental/insecure-randomness/InsecureRandomness.ql
query: experimental/insecure-randomness/InsecureRandomness.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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)

View File

@@ -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: [""])

View File

@@ -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 |

View File

@@ -1 +1,2 @@
experimental/ldap-injection/LdapInjection.ql
query: experimental/ldap-injection/LdapInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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 = "

View File

@@ -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 = "

View File

@@ -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 |

View File

@@ -1 +1,2 @@
experimental/template-injection/TemplateInjection.ql
query: experimental/template-injection/TemplateInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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
<root>
@@ -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

View File

@@ -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
<root>
@@ -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

View File

@@ -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
<root>
@@ -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

View File

@@ -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 |

View File

@@ -1 +1,2 @@
experimental/xpath-injection/XpathInjection.ql
query: experimental/xpath-injection/XpathInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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 |

View File

@@ -1 +1,2 @@
experimental/cwe-022-zipslip/ZipSlip.ql
query: experimental/cwe-022-zipslip/ZipSlip.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -1 +1 @@
experimental/cwe-176/UnicodeBypassValidation.ql
query: experimental/cwe-176/UnicodeBypassValidation.ql

View File

@@ -1 +1,2 @@
experimental/cwe-347/EmptyJWTSecret.ql
query: experimental/cwe-347/EmptyJWTSecret.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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')

View File

@@ -1 +1,2 @@
experimental/cwe-347/MissingJWTVerification.ql
query: experimental/cwe-347/MissingJWTVerification.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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')

View File

@@ -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 |

View File

@@ -1 +1,2 @@
experimental/cwe-502/UnsafeYamlDeserialization.ql
query: experimental/cwe-502/UnsafeYamlDeserialization.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -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. |

View File

@@ -1 +1,2 @@
experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
query: experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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"

View File

@@ -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 |

View File

@@ -1 +1,2 @@
experimental/weak-params/WeakParams.ql
query: experimental/weak-params/WeakParams.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -1 +1 @@
queries/metrics/FLines.ql
query: queries/metrics/FLines.ql

View File

@@ -1 +1 @@
queries/metrics/FLinesOfCode.ql
query: queries/metrics/FLinesOfCode.ql

View File

@@ -1 +1 @@
queries/metrics/FLinesOfComments.ql
query: queries/metrics/FLinesOfComments.ql

View File

@@ -1 +1,2 @@
experimental/performance/UseDetect.ql
query: experimental/performance/UseDetect.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -1 +1,2 @@
queries/security/cwe-020/IncompleteHostnameRegExp.ql
query: queries/security/cwe-020/IncompleteHostnameRegExp.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -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

View File

@@ -1 +1,2 @@
queries/security/cwe-020/IncompleteUrlSubstringSanitization.ql
query: queries/security/cwe-020/IncompleteUrlSubstringSanitization.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -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 |

View File

@@ -1 +1,2 @@
queries/security/cwe-020/MissingFullAnchor.ql
query: queries/security/cwe-020/MissingFullAnchor.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -1 +1,2 @@
queries/security/cwe-020/MissingRegExpAnchor.ql
query: queries/security/cwe-020/MissingRegExpAnchor.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -1 +1,2 @@
queries/security/cwe-020/OverlyLargeRange.ql
query: queries/security/cwe-020/OverlyLargeRange.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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_%-.]/;
overlapsWithNothing = /[\w_%-.]/; # $ Alert

View File

@@ -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(<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(<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 |

View File

@@ -1 +1,2 @@
queries/security/cwe-078/KernelOpen.ql
query: queries/security/cwe-078/KernelOpen.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -1 +1,2 @@
queries/security/cwe-078/NonConstantKernelOpen.ql
query: queries/security/cwe-078/NonConstantKernelOpen.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -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 |

View File

@@ -1 +1,2 @@
queries/security/cwe-078/UnsafeShellCommandConstruction.ql
query: queries/security/cwe-078/UnsafeShellCommandConstruction.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1 +1 @@
queries/security/cwe-079/ReflectedXSS.ql
query: queries/security/cwe-079/ReflectedXSS.ql

View File

@@ -1 +1 @@
queries/security/cwe-079/StoredXSS.ql
query: queries/security/cwe-079/StoredXSS.ql

View File

@@ -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 | "<h2>#{...}</h2>" | 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 | "<h2>#{...}</h2>" | 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 | "<h2>#{...}</h2>" | 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 | "<h2>#{...}</h2>" | cross-site scripting |

View File

@@ -1 +1,2 @@
queries/security/cwe-079/UnsafeHtmlConstruction.ql
query: queries/security/cwe-079/UnsafeHtmlConstruction.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,27 +1,27 @@
class Foobar
def create_user_description(name)
"<h2>#{name}</h2>".html_safe # NOT OK - the parameter is not escaped
def create_user_description(name) # $ Source[rb/html-constructed-from-input]
"<h2>#{name}</h2>".html_safe # NOT OK - the parameter is not escaped # $ Alert[rb/html-constructed-from-input]
# escape
"<h2>#{ERB::Util.html_escape(name)}</h2>".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
<h2>#{name}</h2>
<h2>#{name}</h2> # $ Alert[rb/html-constructed-from-input]
HTML
h.html_safe # NOT OK - the parameter is not escaped
end
def sprintf_use name
sprintf("<h2>%s</h2>", name).html_safe # NOT OK - the parameter is not escaped
def sprintf_use name # $ Source[rb/html-constructed-from-input]
sprintf("<h2>%s</h2>", name).html_safe # NOT OK - the parameter is not escaped # $ Alert[rb/html-constructed-from-input]
# escape
sprintf("<h2>%s</h2>", ERB::Util.html_escape(name)).html_safe # OK - the parameter is escaped
end
def create_user_description2(name)
"<h2>#{name}</h2>".html_safe # NOT OK - the value is not necessarily HTML safe
def create_user_description2(name) # $ Source[rb/html-constructed-from-input]
"<h2>#{name}</h2>".html_safe # NOT OK - the value is not necessarily HTML safe # $ Alert[rb/html-constructed-from-input]
if name.html_safe?
"<h2>#{name}</h2>".html_safe # OK - value is marked as being HTML safe

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 |

View File

@@ -1 +1,2 @@
queries/security/cwe-089/SqlInjection.ql
query: queries/security/cwe-089/SqlInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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 |

View File

@@ -1 +1,2 @@
queries/security/cwe-094/UnsafeCodeConstruction.ql
query: queries/security/cwe-094/UnsafeCodeConstruction.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -1 +1,2 @@
queries/security/cwe-116/BadTagFilter.ql
query: queries/security/cwe-116/BadTagFilter.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,22 +1,22 @@
filters = [
/<script.*?>.*?<\/script>/i, # NOT OK - doesn't match newlines or `</script >`
/<script.*?>.*?<\/script>/im, # NOT OK - doesn't match `</script >`
/<script.*?>.*?<\/script>/i, # NOT OK - doesn't match newlines or `</script >` # $ Alert
/<script.*?>.*?<\/script>/im, # NOT OK - doesn't match `</script >` # $ Alert
/<script.*?>.*?<\/script[^>]*>/im, # OK
/<!--.*-->/im, # OK - we don't care regexps that only match comments
/<!--.*--!?>/im, # OK
/<!--.*--!?>/i, # NOT OK, does not match newlines
/<script.*?>(.|\s)*?<\/script[^>]*>/i, # NOT OK - doesn't match inside the script tag
/<script[^>]*?>.*?<\/script[^>]*>/i, # NOT OK - doesn't match newlines inside the content
/<script(\s|\w|=|")*?>.*?<\/script[^>]*>/im, # NOT OK - does not match single quotes for attribute values
/<script(\s|\w|=|')*?>.*?<\/script[^>]*>/im, # NOT OK - does not match double quotes for attribute values
/<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>/im, # NOT OK - does not match tabs between attributes
/<script.*?>.*?<\/script[^>]*>/m, # NOT OK - does not match uppercase SCRIPT tags
/<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>/m, # NOT OK - does not match mixed case script tags
/<script[^>]*?>[\s\S]*?<\/script.*>/i, # NOT OK - doesn't match newlines in the end tag
/<!--.*--!?>/i, # NOT OK, does not match newlines # $ Alert
/<script.*?>(.|\s)*?<\/script[^>]*>/i, # NOT OK - doesn't match inside the script tag # $ Alert
/<script[^>]*?>.*?<\/script[^>]*>/i, # NOT OK - doesn't match newlines inside the content # $ Alert
/<script(\s|\w|=|")*?>.*?<\/script[^>]*>/im, # NOT OK - does not match single quotes for attribute values # $ Alert
/<script(\s|\w|=|')*?>.*?<\/script[^>]*>/im, # NOT OK - does not match double quotes for attribute values # $ Alert
/<script( |\n|\w|=|'|")*?>.*?<\/script[^>]*>/im, # NOT OK - does not match tabs between attributes # $ Alert
/<script.*?>.*?<\/script[^>]*>/m, # NOT OK - does not match uppercase SCRIPT tags # $ Alert
/<(script|SCRIPT).*?>.*?<\/(script|SCRIPT)[^>]*>/m, # NOT OK - does not match mixed case script tags # $ Alert
/<script[^>]*?>[\s\S]*?<\/script.*>/i, # NOT OK - doesn't match newlines in the end tag # $ Alert
/<script[^>]*?>[\s\S]*?<\/script[^>]*?>/i, # OK
/<script\b[^>]*>([\s\S]*?)<\/script>/gi, # NOT OK - too strict matching on the end tag
/<(?:!--([\S|\s]*?)-->)|([^\/\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
/<script\b[^>]*>([\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)

View File

@@ -1 +1,2 @@
queries/security/cwe-116/IncompleteSanitization.ql
query: queries/security/cwe-116/IncompleteSanitization.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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)

View File

@@ -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 |

View File

@@ -1 +1,2 @@
queries/security/cwe-117/LogInjection.ql
query: queries/security/cwe-117/LogInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -1 +1,2 @@
queries/security/cwe-1333/ReDoS.ql
query: queries/security/cwe-1333/ReDoS.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

View File

@@ -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 |

View File

@@ -1 +1,2 @@
queries/security/cwe-1333/PolynomialReDoS.ql
query: queries/security/cwe-1333/PolynomialReDoS.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -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

Some files were not shown because too many files have changed in this diff Show More