2012-03-19 21 views
0

私はmysqlデータベースにログインし、ユーザーが入力したユーザー名とパスワードに基づいて注文情報を返す次のrubyスクリプトを作成しました。私の質問は、私はSQLインジェクションを防ぐ方法を行くだろうか?私はそれが現時点で書かれている方法は、それが攻撃に広く開いたままになることを知っているが、私はルビーには新しく、これを防ぐために行く方法がわからない。ruby​​スクリプトによるSQLインジェクションの防止

#!/usr/bin/ruby 

#Import mysql module 
    require "mysql" 

    begin 

    #Establish connection to mysql database as the operator user. 
    connection = Mysql.real_connect("localhost", "operator", "", "rainforest") 
    #Allow Multi line statements 
    connection.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON) 

    #Prompt user for username 
    puts "Please Enter Your Customer Username:" 
    #Get username entered and store to variable 
    username = gets.chomp 

    #Prompt user for password 
    puts "Please Enter Your Customer Password" 
    #Get password entered and store to variable 
    password = gets.chomp 

    #Specify SQL query that returns order if user entered data matches data held in customer table 
    customerQuery = connection.query("SELECT O.order_ID, O.date_ordered, C.customer_name, P.product_name 
    FROM orders As O 
    INNER JOIN customer As C ON O.customer_ID=C.customer_ID 
    INNER JOIN product As P ON O.product_ID=P.product_ID 
    WHERE C.customer_name = '" + name + "' AND C.customer_password = '" + password + "'") 

    #If query returns a row then user has entered correct login details 
    if customerQuery.num_rows > 0 then 

    #tell user they have successfully logged in 
    puts "User Successfully Authenticated: Hello " + username + ". Here are your orders:  \n**********" 

    #Print all row data containing users order details to screen 
    while row = customerQuery.fetch_row do 

    puts row 
    puts "**********"  
    end 
    else 
    #if no rows return, user has entered incorrect details, inform them of this by printing to screen 
    puts "User Authentication Unsuccessful:Incorrect Username or Password, Please Try  Again" 
    end 
    #close connection to database 
    connection.close 
    end 

答えて

2

代わりに、文字列の連結/補間のプリペアドステートメントを使用します。

p = connection.prepare(%q{ 
    select o.order_id, o.date_ordered, c.customer_name, p.product_name 
    from orders as o 
    join customer as c on o.customer_id = c.customer_id 
    join product as p on o.product_id = p.product_id 
    where c.customer_name  = ? 
     and c.customer_password = ? 
}) 
customerQuery = p.execute(name, password) 
if customerQuery.num_rows > 0 
    customerQuery.each do |row| 
     #... 
    end 
else 
    #... 
end 

あなたは絶対に、その後connection.quoteを使用し、いくつかの奇妙な理由で、文字列の補間を使用する必要がある場合:

customerQuery = connection.query(%Q{ 
    select o.order_id, o.date_ordered, c.customer_name, p.product_name 
    from orders as o 
    join customer as c on o.customer_id = c.customer_id 
    join product as p on o.product_id = p.product_id 
    where c.customer_name  = '#{connection.quote(name)}' 
     and c.customer_password = '#{connection.quote(password)}' 
}) 

しかし、実際に他の選択肢がない限り、これをしないでください。この場合、文字列操作を使用する必要はありません。

関連する問題