2016-11-25 6 views
0

내가 SQL 주입으로부터 자신을 방어하기 위해 노력하고있어 잡기되지, 나는 #where에 열 이름으로 변수를 사용하고 있습니다 :RSpec에 오류 StatementInvalid

변수 @key을 조작 할 수 해시에서 가져
class BuildSegment::FindUsers 

    def initialize(params) 
    @key = User.connection.quote_column_name(params[:key]) 
    @negative = params[:negative] 
    @pattern = params[:pattern] 
    end 

    def call 
    if @negative 
     users = User.where.not("#{@key} LIKE ?", @pattern) 
    else 
     users = User.where("#{@key} LIKE ?", @pattern) 
    end 

    users.uniq 
    end 
end 

사용자. 따라서, 예를 들어 내가 액티브 레코드 쿼리에 직접 @key 통과하고있어 @key = "email LIKE '%' OR email" 경우, 내가 얻을 : 모든 사용자를 반환

SELECT "users".* FROM "users" WHERE (email LIKE '%' OR email LIKE '') 

합니다.

ActiveRecord::StatementInvalid: 
     PG::UndefinedColumn: ERROR: column "email LIKE '%com%' OR email" does not exist 
     LINE 1: SELECT DISTINCT "users".* FROM "users" WHERE ("email LIKE '%... 
                  ^
     : SELECT DISTINCT "users".* FROM "users" WHERE ("email LIKE '%com%' OR email" LIKE '') 

이 테스트하지만, 실패 :

expect(segment_builder.call).to raise_error(ActiveRecord::StatementError) 

그리고 전체 역 추적 :

Failures: 

    1) BuildSegment is protected from SQL injection 
    Failure/Error: users_to_add = users.flatten 

    ActiveRecord::StatementInvalid: 
     PG::UndefinedColumn: ERROR: column "email LIKE '%com%' OR email" does not exist 
     LINE 1: SELECT DISTINCT "users".* FROM "users" WHERE ("email LIKE '%... 
                  ^
     : SELECT DISTINCT "users".* FROM "users" WHERE ("email LIKE '%com%' OR email" LIKE '') 
    # ./app/services/build_segment.rb:51:in `flatten' 
    # ./app/services/build_segment.rb:51:in `users_passing_all_rules' 
    # ./app/services/build_segment.rb:46:in `users_passing_filter' 
    # ./app/services/build_segment.rb:32:in `block in users_meeting_requirements_for' 
    # ./app/services/build_segment.rb:31:in `each' 
    # ./app/services/build_segment.rb:31:in `users_meeting_requirements_for' 
    # ./app/services/build_segment.rb:8:in `call' 
    # ./spec/services/build_segment_spec.rb:107:in `block (2 levels) in <top (required)>' 
    # ------------------ 
    # --- Caused by: --- 
    # PG::UndefinedColumn: 
    # ERROR: column "email LIKE '%com%' OR email" does not exist 
    # LINE 1: SELECT DISTINCT "users".* FROM "users" WHERE ("email LIKE '%... 
    #              ^
    # ./app/services/build_segment.rb:51:in `flatten' 

내 오류 일 수 있습니다 나는 ActiveRecord::StatementInvalid 오류를 반환하는 솔루션으로 quote_column_name(params[:key])을 발견?

답변

1

두 가지 문제를 코드로 :

1) 오류가 ActiveRecord::StatementInvalid하지 ActiveRecord::StatementError

2

)입니다 당신은을 사용하기 위해 필요한이 당신을 위해 작동하는 경우

은 참조 예외를 잡으려면 expect {}의 구문을 차단하십시오. 자세한 내용은 https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/raise-error-matcher을 참조하십시오.

+0

감사합니다. @sevenseacat! 둘 모두를 고치면 테스트가 통과되었습니다. – Patryk

0

SQL을 올바르게 이스케이프 처리하지 않는 것처럼 보입니다.

User.where.not("#{@key} LIKE ?, '#{@pattern}'") 

User.where("#{@key} LIKE ?, '#{@pattern}'")