Merge pull request #13062 from maikypedia/maikypedia/sqli-sink

Ruby: Add MySQL as SQL Injection Sink
This commit is contained in:
Alex Ford
2023-06-02 17:06:35 +01:00
committed by GitHub
10 changed files with 159 additions and 0 deletions

View File

@@ -2814,7 +2814,10 @@
| file://:0:0:0:0 | parameter position 0 of File.realdirpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realdirpath |
| file://:0:0:0:0 | parameter position 0 of File.realpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realpath |
| file://:0:0:0:0 | parameter position 0 of Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] |
| file://:0:0:0:0 | parameter position 0 of Mysql2::Client.escape() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.escape() |
| file://:0:0:0:0 | parameter position 0 of Mysql2::Client.new() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.new() |
| file://:0:0:0:0 | parameter position 0 of PG.new() | file://:0:0:0:0 | [summary] to write: return (return) in PG.new() |
| file://:0:0:0:0 | parameter position 0 of SQLite3::Database.quote() | file://:0:0:0:0 | [summary] to write: return (return) in SQLite3::Database.quote() |
| file://:0:0:0:0 | parameter position 0 of Sequel.connect | file://:0:0:0:0 | [summary] to write: return (return) in Sequel.connect |
| file://:0:0:0:0 | parameter position 0 of String.try_convert | file://:0:0:0:0 | [summary] to write: return (return) in String.try_convert |
| file://:0:0:0:0 | parameter position 0 of \| | file://:0:0:0:0 | [summary] read: argument position 0.any element in \| |

View File

@@ -0,0 +1,5 @@
| Mysql2.rb:10:16:10:48 | call to query | Mysql2.rb:10:27:10:47 | "SELECT * FROM users" |
| Mysql2.rb:13:16:13:73 | call to query | Mysql2.rb:13:27:13:72 | "SELECT * FROM users WHERE use..." |
| Mysql2.rb:17:16:17:76 | call to query | Mysql2.rb:17:27:17:75 | "SELECT * FROM users WHERE use..." |
| Mysql2.rb:21:16:21:57 | call to execute | Mysql2.rb:20:31:20:82 | "SELECT * FROM users WHERE id ..." |
| Mysql2.rb:25:16:25:60 | call to execute | Mysql2.rb:24:31:24:93 | "SELECT * FROM users WHERE use..." |

View File

@@ -0,0 +1,5 @@
private import codeql.ruby.DataFlow
private import codeql.ruby.Concepts
private import codeql.ruby.frameworks.Mysql2
query predicate mysql2SqlExecution(SqlExecution e, DataFlow::Node sql) { sql = e.getSql() }

View File

@@ -0,0 +1,30 @@
class UsersController < ActionController::Base
def mysql2_handler(event:, context:)
name = params[:user_name]
conn = Mysql2::Client.new(
host: "127.0.0.1",
username: "root"
)
# GOOD: SQL statement is not constructed from user input
results1 = conn.query("SELECT * FROM users")
# BAD: SQL statement constructed from user input
results2 = conn.query("SELECT * FROM users WHERE username='#{name}'")
# GOOD: user input is escaped
escaped = Mysql2::Client.escape(name)
results3 = conn.query("SELECT * FROM users WHERE username='#{escaped}'")
# GOOD: user input is escaped
statement1 = conn.prepare("SELECT * FROM users WHERE id >= ? AND username = ?")
results4 = statement1.execute(1, name, :as => :array)
# BAD: SQL statement constructed from user input
statement2 = conn.prepare("SELECT * FROM users WHERE username='#{name}' AND password = ?")
results4 = statement2.execute("password", :as => :array)
# NOT EXECUTED
statement3 = conn.prepare("SELECT * FROM users WHERE username = ?")
end
end