CVE-2014-125037: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: A vulnerability, which was classified as critical, was found in License to Kill. This affects an unknown part of the file models/injury.rb. The manipulation of the argument name leads to sql injection. The patch is named cd11cf174f361c98e9b1b4c281aa7b77f46b5078. It is recommended to apply a patch to fix this issue. The associated identifier of this vulnerability is VDB-217191.
CWE description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
CVSS v3 base score: 9.8
Published: 2023-01-02T18:15Z
Repository: https://github.com/elizabrock/license-to-kill
Language: Ruby
Files changed: lib/database.rb, models/injury.rb, spec/injury_integration_spec.rb
Commit date: 2014-05-01 09:22:12 -0500
Commit message: Fix the SQL injection! STRING INTERPOLATION - NEVER AGAIN. NEVER!

Diff: diff --git a/lib/database.rb b/lib/database.rb
index 2f00647..416c6c9 100644
--- a/lib/database.rb
+++ b/lib/database.rb
@@ -11,10 +11,10 @@ class Database < SQLite3::Database
 
   def create_tables
     self.execute("CREATE TABLE injuries (id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(50))")
   end
 
-  def execute(statement)
+  def execute(statement, bind_vars = [])
     Environment.logger.info("Executing: " + statement)
-    super(statement)
+    super(statement, bind_vars)
   end
 end
diff --git a/models/injury.rb b/models/injury.rb
index b882052..16c5293 100644
--- a/models/injury.rb
+++ b/models/injury.rb
@@ -17,12 +17,12 @@ class Injury
     result = Environment.database_connection.execute(statement)
     result[0][0]
   end
 
   def self.find_by_name(name)
-    statement = "Select * from injuries where name = \"#{name}\";"
-    execute_and_instantiate(statement)[0]
+    statement = "Select * from injuries where name = ?;"
+    execute_and_instantiate(statement, name)[0]
   end
 
   def self.last
     statement = "Select * from injuries order by id DESC limit(1);"
     execute_and_instantiate(statement)[0]
@@ -31,20 +31,20 @@ class Injury
   def save
     if Injury.find_by_name(self.name)
       @errors << "#{self.name} already exists."
       false
     else
-      statement = "Insert into injuries (name) values ('#{name}');"
-      Environment.database_connection.execute(statement)
+      statement = "Insert into injuries (name) values (?);"
+      Environment.database_connection.execute(statement, name)
       true
     end
   end
 
   private
 
-  def self.execute_and_instantiate(statement)
-    rows = Environment.database_connection.execute(statement)
+  def self.execute_and_instantiate(statement, bind_vars = [])
+    rows = Environment.database_connection.execute(statement, bind_vars)
     results = []
     rows.each do |row|
       results << Injury.new(row["name"])
     end
     results
diff --git a/spec/injury_integration_spec.rb b/spec/injury_integration_spec.rb
index 35f074d..c77ed35 100644
--- a/spec/injury_integration_spec.rb
+++ b/spec/injury_integration_spec.rb
@@ -55,16 +55,19 @@ describe "Adding an injury" do
       end
     end
     context "without alphabet characters" do
       let(:output){ run_ltk_with_input("2", "4*25") }
       it "should not save the injury" do
+        pending
         Injury.count.should == 1
       end
       it "should print an error message" do
+        pending
         output.should include("'4*25' is not a valid injury name, as it does not include any letters'")
       end
       it "should let them try again" do
+        pending
         menu_text = "What is the injury you want to add?"
         output.should include_in_order(menu_text, "not a valid", menu_text)
       end
     end
   end

Vulnerable code:   def execute(statement)
    super(statement)
    statement = "Select * from injuries where name = \"#{name}\";"
    execute_and_instantiate(statement)[0]
      statement = "Insert into injuries (name) values ('#{name}');"
      Environment.database_connection.execute(statement)
  def self.execute_and_instantiate(statement)
    rows = Environment.database_connection.execute(statement)
Fixed code:   def execute(statement, bind_vars = [])
    super(statement, bind_vars)
    statement = "Select * from injuries where name = ?;"
    execute_and_instantiate(statement, name)[0]
      statement = "Insert into injuries (name) values (?);"
      Environment.database_connection.execute(statement, name)
  def self.execute_and_instantiate(statement, bind_vars = [])
    rows = Environment.database_connection.execute(statement, bind_vars)
        pending
        pending
        pending