Rails에서 배우는 SQL 주입 취약점
스카스카 기사이지만 용서해주세요
연습 환경
기사 투고, 코멘트 투고, 북마크 등을 할 수 있는 연습용 앱 「TARGET」
GitHub 리포지토리 htps : // 기주 b. 코 m / 후미 타카 1 / 탄 t
SQL 주입 취약점이란?
외부로부터 받은 파라미터로부터 SQL문을 작성해, DB를 조작하고 있는 프로그램에 일어날 수 있는 취약성
예 사용자 목록을 볼 수 있는 사이트가 있습니다.
'소'로 검색하면 사용자 이름에 '소'를 포함하는 사용자가 표시됩니다.
발행되는 SQL문 SELECT `users`.* FROM `users` WHERE (name LIKE '%小%')
아래의 공격용 문자열로 검색하면 해시화된 비밀번호가 표시됩니다.
&&') UNION SELECT 1, encrypted_password, 3,4,5,6,7,8,9,10,11 FROM target_development.users;#
발행되는 SQL 문SELECT `users`.* FROM `users` WHERE (name LIKE '%&&') UNION SELECT 1, encrypted_password, 3,4,5,6,7,8,9,10,11 FROM target_development.users;# %')
※공격 문자열에 필요한 데이터베이스명이나 컬럼명은 informaiton_schema로부터 취득 가능합니다
왜 발생하는가
외부의 매개 변수에 SQL 특수 문자가 포함되어 있고 예상치 못한 SQL 문이 발행되기 때문에
위의 예에서
1. 검색 문자열 &&')
은 정규 SELECT 문을 잘못 종료합니다.
2. 연속 문자열 UNION SELECT 1, encrypted_password, 3,4,5,6,7,8,9,10,11 FROM target_development.users;
이 그대로 SQL로 발행됩니다.
연습용 사이트에는 외부로부터의 파라미터를 그대로 받아 SQL문을 발행하는 취약한 처리가 포함되어 있다
users_controller.rb def index
@users = User.where("name LIKE '%#{params[:q]}%'")
end
어떻게 막을까
1. 외부에서 매개변수에 포함된 특수 문자를 안전한 문자로 대체
users_controller.rb def index
sanitized_q = params[:q].gsub(/\'/,'\\\'') if params[:q]
@users = User.where("name LIKE '%#{sanitized_q}%'")
end
2. 자리표시자를 이용하여 SQL문을 발행한다.
users_controller.rb def index
@users = User.where("name LIKE ?","%#{params[:q]}%")
end
Rails는 SQL 특수 문자 필터를 제공합니다.
외부의 매개 변수에 SQL 특수 문자가 포함되어 있고 예상치 못한 SQL 문이 발행되기 때문에
위의 예에서
1. 검색 문자열
&&')
은 정규 SELECT 문을 잘못 종료합니다.2. 연속 문자열
UNION SELECT 1, encrypted_password, 3,4,5,6,7,8,9,10,11 FROM target_development.users;
이 그대로 SQL로 발행됩니다.연습용 사이트에는 외부로부터의 파라미터를 그대로 받아 SQL문을 발행하는 취약한 처리가 포함되어 있다
users_controller.rb
def index
@users = User.where("name LIKE '%#{params[:q]}%'")
end
어떻게 막을까
1. 외부에서 매개변수에 포함된 특수 문자를 안전한 문자로 대체
users_controller.rb def index
sanitized_q = params[:q].gsub(/\'/,'\\\'') if params[:q]
@users = User.where("name LIKE '%#{sanitized_q}%'")
end
2. 자리표시자를 이용하여 SQL문을 발행한다.
users_controller.rb def index
@users = User.where("name LIKE ?","%#{params[:q]}%")
end
Rails는 SQL 특수 문자 필터를 제공합니다.
def index
sanitized_q = params[:q].gsub(/\'/,'\\\'') if params[:q]
@users = User.where("name LIKE '%#{sanitized_q}%'")
end
def index
@users = User.where("name LIKE ?","%#{params[:q]}%")
end
배운 것
SQL 인젝션은 잘 알려진 취약성이기 때문에, 프레임워크 측에서 대응책이 준비되어 있지만, 외부 파라미터로부터 SQL문을 작성하는 경우에는 충분히 주의를 기울인다.
ORM 덕분에 SQL을 작성할 기회가 적었지만, 이 기회에 SQL을 파고들 수 있었다.
Reference
이 문제에 관하여(Rails에서 배우는 SQL 주입 취약점), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Fumitaka1/items/dd863bf4f45d9d4a4dde텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)