PHP에서 SQL 주입 공격을 방지하는 방법은 무엇입니까?
P粉939473759
P粉939473759 2023-08-22 10:23:01
0
2
590
<p>사용자 입력이 수정 없이 SQL 쿼리에 삽입되면 다음 예와 같이 애플리케이션이 SQL 삽입 공격에 취약해집니다. </p> <pre class="lang-php Prettyprint-override"><code>$unsafe_variable = $_POST['user_input']; mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')"); <p>이는 사용자가 <code>value');-</code>와 같은 항목을 입력할 수 있기 때문입니다. </p> <pre class="brush:php;toolbar:false;">INSERT INTO `table`(`column`) VALUES('value'); DROP TABLE table;--') <p>이런 일이 발생하지 않도록 하려면 어떻게 해야 하나요? </p>
P粉939473759
P粉939473759

모든 응답(2)
P粉891237912

매개변수화된 쿼리를 사용하려면 Mysqli 또는 PDO를 사용해야 합니다. mysqli를 사용하여 예제를 다시 작성하려면 다음과 유사한 코드가 필요합니다.

으아아아

읽고 싶은 주요 기능은 mysqli::prepare입니다.

또한 다른 사람들이 제안한 것처럼 PDO와 같은 더 높은 수준의 추상화 계층을 사용하는 것이 더 유용하고 쉽다는 것을 알 수 있습니다.

당신이 언급한 상황은 매우 간단하며, 더 복잡한 상황에서는 더 정교한 접근 방식이 필요할 수 있습니다. 특히:

  • 사용자 입력을 기반으로 SQL의 구조를 변경하려는 경우 매개변수화된 쿼리는 도움이 되지 않으며 필수 이스케이프는 mysql_real_escape_string에 포함되지 않습니다. 이 경우 "안전한" 값만 허용되도록 사용자의 입력을 화이트리스트를 통해 전달하는 것이 좋습니다.
P粉771233336

어떤 데이터베이스를 사용하든 SQL 삽입 공격을 올바른방법은 SQL에서 데이터를 분리하여 데이터가 절대로 SQL 파서의 명령으로 해석되지 않는 데이터 형식으로 유지되도록 하는 것입니다. . 올바른 형식의 데이터 부분을 사용하여 SQL 문을 생성할 수 있지만 세부 사항을 완전히 이해하지 못하는 경우 항상 준비된 문과 매개변수화된 쿼리를 사용해야 합니다. 이는 매개변수와 별도로 전송되어 데이터베이스 서버에서 분석되는 SQL 문입니다. 이렇게 하면 공격자가 악성 SQL을 삽입할 수 없습니다.

이를 달성하는 방법에는 기본적으로 두 가지가 있습니다.

  1. PDO 사용(지원되는 모든 데이터베이스 드라이버에서 작동):

    으아아아
  2. MySQLi 사용(MySQL용):
    PHP 8.2+부터 execute_query() 메소드를 사용하여 매개변수를 준비하고, 매개변수를 바인딩하고, SQL 문을 실행할 수 있습니다.

    으아아아

    PHP8.1 이전:

    으아아아

MySQL이 아닌 다른 데이터베이스에 연결하는 경우 두 번째 드라이버별 옵션을 참조할 수 있습니다(예를 들어 PostgreSQL의 경우 pg_prepare()pg_execute()를 사용할 수 있음). PDO는 보편적인 옵션입니다.


연결을 올바르게 설정하세요

PDO

MySQL 데이터베이스에 액세스하기 위해 PDO를 사용할 때 실제 준비된 명령문은 기본적으로 사용되지 않습니다. 이 문제를 해결하려면 준비된 문의 시뮬레이션을 비활성화해야 합니다. 다음은 PDO을 사용하여 연결을 생성하는 예입니다.

으아아아

위의 예에서 오류 모드는 꼭 필요한 것은 아니지만 추가하는 것이 좋습니다 . 이렇게 하면 PDO가 PDOException를 던져 모든 MySQL 오류를 알려줍니다.

그러나 반드시 해야 하는 것은 PDO에게 시뮬레이션된 준비된 문을 비활성화하고 setAttribute()실제 준비된 문을 사용하도록 지시하는 첫 번째 줄 입니다. 이렇게 하면 명령문과 값이 MySQL 서버로 전송되기 전에 PHP에서 구문 분석되지 않으므로 잠재적인 공격자가 악성 SQL을 삽입할 수 없습니다.

생성자의 옵션에서 설정할 수 있지만 charset PHP의 "이전" 버전(5.3.6 이전)은 DSN의 charset 매개변수 를 자동으로 무시한다는 점에 유의하는 것이 중요합니다.

Mysqli

mysqli의 경우 동일한 루틴을 따라야 합니다.

으아아아

설명

prepare的SQL语句由数据库服务器解析和编译。通过指定参数(在上面的示例中,可以是?或命名参数,如:name),您告诉数据库引擎您要在哪里进行过滤。然后,当您调用execute을 통과하면 준비된 문이 지정된 매개변수 값과 결합됩니다.

여기서 중요한 점은 매개변수 값이 SQL 문자열이 아닌 컴파일된 문장과 결합된다는 점입니다. SQL 주입은 데이터베이스로 전송될 SQL을 생성할 때 스크립트를 속여 악성 문자열을 포함시키는 방식으로 작동합니다. 따라서 실제 SQL을 매개변수와 별도로 전송함으로써 예상치 못한 결과가 발생할 위험을 제한할 수 있습니다.

Prepared 문을 사용하여 전송된 모든 매개변수는 문자열로 처리됩니다(단, 데이터베이스 엔진이 매개변수를 일부 최적화할 수 있으므로 매개변수가 결국 숫자가 될 수 있음). 위의 예에서 $name变量包含'Sarah'; DELETE FROM employees,结果将仅是搜索字符串"'Sarah'; DELETE FROM employees"하면 빈 테이블을 얻지 못할 것입니다.

Prepared 문을 사용하는 또 다른 이점은 동일한 문이 동일한 세션에서 여러 번 실행되는 경우 한 번만 구문 분석되고 컴파일되므로 속도가 향상된다는 것입니다.

아, 인서트 작업 방법을 문의하셨기 때문에 다음은 예입니다(PDO 사용).

으아아아

동적 쿼리에 준비된 명령문이 적합합니까?

쿼리 매개변수에 대해 준비된 문을 계속 사용할 수 있지만 동적 쿼리 자체의 구조는 매개변수화할 수 없으며 특정 쿼리 함수는 매개변수화할 수 없습니다.

이러한 특정 시나리오의 경우 화이트리스트 필터를 사용하여 가능한 값을 제한하는 것이 가장 좋습니다.

으아아아
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿