이 기사에서는 PHP에 대한 관련 지식을 제공합니다. 주로 전처리 문이 무엇인지 설명합니다. PHP의 전처리된 쿼리는 어떻게 SQL 주입을 방지합니까? 관심 있는 친구들은 아래를 살펴보시면 모두에게 도움이 되길 바랍니다.
PHP의 전처리 쿼리는 어떻게 SQL 삽입을 방지하나요?
현재 SQL 삽입을 방지하는 가장 효과적인 방법은 준비된 문과 매개변수화된 쿼리를 사용하는 것입니다.
가장 일반적으로 사용되는 PHP PDO 확장을 예로 들어 보겠습니다.
준비된 문이란 무엇인가요?
실행하려는 SQL의 컴파일된 템플릿으로 생각하세요. 이는 변수 매개변수를 사용하여 사용자 정의할 수 있습니다.
Prepared 문의 두 가지 주요 이점:
1 쿼리는 한 번만 구문 분석(또는 전처리)하면 되지만 동일하거나 다른 매개변수를 사용하여 여러 번 실행할 수 있습니다. 쿼리가 준비되면 데이터베이스는 쿼리 실행 계획을 분석, 컴파일 및 최적화합니다. 복잡한 쿼리의 경우 이 프로세스가 더 오래 걸리며, 동일한 쿼리를 다른 매개변수로 여러 번 반복해야 하는 경우 애플리케이션 속도가 크게 느려질 수 있습니다. 준비된 문을 사용하면 반복적인 분석/컴파일/최적화 주기를 피할 수 있습니다. 간단히 말해서, 준비된 명령문은 더 적은 리소스를 사용하므로 더 빠르게 실행됩니다.
2. 준비된 명령문에 제공된 매개변수는 따옴표로 묶을 필요가 없으며 드라이버가 자동으로 처리합니다. 애플리케이션이 준비된 문만 사용하는 경우 SQL 주입이 발생하지 않도록 할 수 있습니다. (그러나 쿼리의 다른 부분이 이스케이프되지 않은 입력으로 구성되면 여전히 SQL 주입 위험이 있습니다.)
PDO의 특징은 드라이버가 전처리를 지원하지 않는 경우 PDO가 처리를 시뮬레이션한다는 것입니다. 이때 PDO 시뮬레이터에서 전처리 매개변수화된 쿼리 프로세스가 완료됩니다. PDO 시뮬레이터는 DSN에 지정된 문자 세트에 따라 입력 매개변수를 로컬로 이스케이프한 다음 이를 완전한 SQL 문으로 연결하여 MySQL 서버로 보냅니다.
따라서 PDO 시뮬레이터가 입력 매개변수를 올바르게 이스케이프할 수 있는지 여부가 SQL 주입을 차단하는 열쇠입니다.
5.3.6 미만 PHP 버전의 경우 DSN(데이터 소스 이름)은 기본적으로 charset 매개변수를 무시합니다. 이때 PDO의 로컬 이스케이프를 사용하면 여전히 SQL 주입이 발생할 수 있습니다.
따라서 Laravel 프레임워크의 하위 레이어는 PDO::ATTR_EMULATE_PREPARES=false를 직접 설정하여 SQL 문과 매개변수 값이 MySQL 서버로 전송되기 전에 PHP에서 구문 분석되지 않도록 합니다.
PHP 구현
// 查询 $calories = 150; $colour = 'red'; $sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'); $sth->bindValue(':calories', $calories, PDO::PARAM_INT); $sth->bindValue(':colour', $colour, PDO::PARAM_STR); $sth->execute();
// 插入,修改,删除 $preparedStmt = $db->prepare('INSERT INTO table (column) VALUES (:column)'); $preparedStmt->execute(array(':column' => $unsafeValue));
Laravel의 기본 구현
// 查询的实现 public function select($query, $bindings = [], $useReadPdo = true) { return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { if ($this->pretending()) { return []; } $statement = $this->prepared( $this->getPdoForSelect($useReadPdo)->prepare($query) ); $this->bindValues($statement, $this->prepareBindings($bindings)); $statement->execute(); return $statement->fetchAll(); }); } // 修改删除的实现 public function affectingStatement($query, $bindings = []) { return $this->run($query, $bindings, function ($query, $bindings) { if ($this->pretending()) { return 0; } $statement = $this->getPdo()->prepare($query); $this->bindValues($statement, $this->prepareBindings($bindings)); $statement->execute(); $this->recordsHaveBeenModified( ($count = $statement->rowCount()) > 0 ); return $count; }); }
권장 학습: "PHP 비디오 튜토리얼"
위 내용은 PHP의 사전 처리된 쿼리가 SQL 삽입을 방지하는 방법을 분석하는 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!