문제

이전 질문에 대한 의견에서 누군가는 다음 SQL 문이 SQL 주입을 열어 준다고 말했습니다.

select
    ss.*,
    se.name as engine,
    ss.last_run_at + interval ss.refresh_frequency day as next_run_at,
    se.logo_name    
from 
    searches ss join search_engines se on ss.engine_id = se.id
where
    ss.user_id='.$user_id.'
group by ss.id
order by ss.project_id, ss.domain, ss.keywords

그것을 가정합니다 $userid 변수가 올바르게 탈출됩니다. 이것이 어떻게 취약하게 만들고, 수정하려면 어떻게해야합니까?

도움이 되었습니까?

해결책

그것이 제대로 탈출되었다고 가정하면, 당신을 취약하게 만드는 것은 아닙니다. 문제는 제대로 탈출하는 것이 첫눈에 보는 것보다 어렵다는 것입니다. 그리고 당신은 그런 쿼리를 할 때마다 제대로 탈출하도록 정죄합니다. 가능하면 모든 문제를 피하고 준비된 명령문 (또는 binded 매개 변수 또는 매개 변수화 쿼리)을 사용하십시오. 아이디어는 데이터 액세스 라이브러리가 값을 올바르게 탈출 할 수 있도록하는 것입니다.

예를 들어, PHP에서 사용합니다 mysqli:

$db_connection = new mysqli("localhost", "user", "pass", "db");
$statement = $db_connection->prepare("SELECT thing FROM stuff WHERE id = ?");
$statement->bind_param("i", $user_id); //$user_id is an integer which goes 
                                       //in place of ?
$statement->execute();

다른 팁

사용하는 모든 SQL 인터페이스 라이브러리에는 바인딩 매개 변수에 대한 지원이 있습니다. 영리하려고하지 말고 그냥 사용하십시오.

당신은 정말로, 당신이 물건을 제대로 탈출 한 것을 정말로 생각/희망 할 수도 있지만, 당신이하지 않는 시간의 가치는 없습니다.

또한 몇몇 데이터베이스는 준비된 명령문 캐싱을 지원하므로 올바르게 수행하면 효율성을 얻을 수 있습니다.

더 쉽고 안전하며 빠릅니다.

그것이 제대로 탈출하여 검증되면 문제가 없습니다.

문제는 제대로 탈출하거나 검증되지 않을 때 발생합니다. 이것은 조잡한 코딩 또는 감독으로 인해 발생할 수 있습니다.

문제는 특정 사례가 아니라 패턴이 있습니다. 이 패턴은 SQL 주입을 가능하게하는 반면 다른 패턴은 불가능합니다.

만약에 $ user_id 탈출하면 SQL 주입에 취약하지 않아야합니다.

이 경우 $ user_id가 숫자 또는 정수인지 확인합니다 (필요한 정확한 유형에 따라 다름). 항상 데이터를 가능한 가장 제한적인 유형으로 제한해야합니다.

여기에 '제대로 탈출'이 키워드라고 생각합니다. 당신의 마지막 질문, 나는 당신의 코드가 당신의 프로덕션 코드에서 복사된다는 가정을하고 있으며, 당신이 3 개의 테이블 가입에 대한 질문을했기 때문에, 당신이 올바른 탈출을하지 않았다는 가정을합니다. 따라서 SQL 주입 공격에 대한 나의 언급.

많은 사람들이 설명했듯이 귀하의 질문에 답하기 위해 만약에 변수는 '제대로 탈출'되었으며 문제가 없습니다. 그러나 왜 그렇게함으로써 자신을 괴롭히는가? 어떤 사람들이 지적했듯이, 때로는 제대로 탈출하는 것은 간단한 일이 아닙니다. PHP에는 SQL 주입을 불가능하게 만드는 패턴과 라이브러리가 있습니다. 왜 우리는 그것을 사용하지 않습니까? (또한 의도적으로 귀하의 코드가 실제로 PHP라고 가정합니다). Vinko Vrsalovic 대답 이 문제에 접근하는 방법에 대한 아이디어를 줄 수 있습니다.

그와 같은 진술은 실제로 문제가되지 않고 "안전"하지만, 당신이 어떻게이 일을하고 있는지 모르겠습니다 (API 스택에서 한 레벨 업). $ user_id가 문자열 조작을 사용하여 명령문에 삽입되는 경우 (PHP가 자동으로 문을 채우도록하는 것처럼) 위험합니다.

바인딩 API를 사용하여 채워지면 준비가되었습니다.

모든 대답은 좋고 옳았지만 추가해야한다고 생각합니다. prepare/execute 패러다임은 아닙니다 솔루션. 너 ~해야 한다 라이브러리 기능을 직접 사용하는 대신 데이터베이스 추상화 계층이 있어야하며 그러한 레이어는 문자열 매개 변수를 명시 적으로 탈출 할 수있는 좋은 장소입니다. prepare 그것을하거나 당신은 그것을 직접합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top