일반적으로, 당신은 SQL 쿼리를 구축하는 문자열 보간을 사용하지 않아야합니다. 이렇게하면 SQL injection 공격을받을 수 있습니다. 누군가가 닫는 따옴표 문자가있는 입력을 제공하고 다른 쿼리가 이어집니다. 예를 들어, 귀하의 예제를 사용 : 인스턴스 누군가가 자신의 입력에 인용 부호를 포함하기위한 경우
가
>> val = '7; DROP TABLE users;'
=> "7; DROP TABLE users;"
>> myQuery = "select * from t where t.val = \#{val}"
=> "select * from t where t.val = \#{val}"
>> eval "\"#{myQuery}\""
=> "select * from t where t.val = 7; DROP TABLE users;"
심지어 악의적 인 입력없이, 당신은 단순히 실수로, 당신이 의도되지 않은 코드를 실행할 수 있습니다.
절대적으로 필요한 경우가 아니면 eval
을 사용하지 않는 것이 좋습니다. 프로그램에 버그가있는 경우 다른 사람이 eval
으로 전달하여 임의의 코드를 실행할 수 있으며 일부 소스 코드가 일반 소스 트리가 아닌 다른 위치에서로드되기 때문에 코드 유지 관리가 어려워 질 수 있습니다.
그럼 대신 어떻게해야합니까? 데이터베이스 API에는 일반적으로 prepare
명령이 포함되어 있으며 SQL 문 실행을 준비 할 수 있습니다. 이 명령문에는 ?
문자를 포함 할 수 있습니다.이 문자는 해당 명령문에서 대체 할 수있는 매개 변수를 나타냅니다. 그런 다음 문에 execute
을 호출하여 해당 매개 변수의 값을 전달하면 다른 사람이 임의의 SQL을 실행하는 방법이 없어도 안전하게 실행됩니다.
다음은 귀하의 예에서 작동하는 방법입니다. 이것은 this MySQL/Ruby module을 사용한다고 가정합니다. 다른 인터페이스를 사용하는 경우 인터페이스가 동일하지만 정확히 같지 않을 수 있습니다.
>> val = 7
>> db = Mysql.new(hostname, username, password, databasename)
>> query = db.prepare("select * from t where t.val = ?")
>> query.execute(val)