어떻게 PHP 에서 SQL 주입 을 방지 합 니까?
6806 단어 PHPStackOverflow
stackoverflow 에서 php 에서 가장 높 은 득 표 문제http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php 전재 가 필요 하 시 면 원문 과 번역문 의 링크 를 밝 혀 주 십시오. 감사합니다.
Q: 사용자 가 입력 한 변경 사항 이 없 는 것 을 SQL 검색 어 에 넣 으 면 SQL 주입 을 초래 할 수 있 습 니 다. 예 를 들 어 다음 의 예 를 들 어:
$unsafe_variable = $_POST['user_input'];
mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");
왜 구멍 이 뚫 렸 을 까?사용자 가 입력 할 수 있 기 때문에
value'); DROP TABLE table;--
검색 어 는 이렇게 되 었 습 니 다.INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')
도대체 우 리 는 무엇 을 해서 sql 주입 을 방지 할 수 있 습 니까?
A: 사전 컴 파일 문 (prepared statements) 과 매개 변수 화 조회 (parameterized queries) 를 사용 합 니 다.이 sql 문 구 는 매개 변수 에서 데이터베이스 서버 로 나 누 어 보 내 분석 합 니 다.이렇게 하면 해커 가 악성 sql 코드 를 삽입 할 수 없다.
이것 을 완성 하 는 두 가지 방법 이 있다.
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));
foreach ($stmt as $row) {
// do something with $row
}
2. MySqli
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
연 결 된 데이터베이스 가 my sql 이 아니라면 구체 적 인 데이터베이스 가 제공 하 는 다른 옵션 을 참고 할 수 있 습 니 다. 예 를 들 어 (pg prepare () and pg execute () for PostgreSQL) Pdo 는 일반적인 옵션 입 니 다.
올 바른 연결 구축
메모: Mysql 데이터 베 이 스 를 PDO 로 연결 할 때 실제 예비 처 리 는 기본적으로 열 리 지 않 습 니 다.그 를 떠 나 기 위해 서 는 아 날로 그 예비 처리 문 구 를 닫 아야 합 니 다. 다음은 예 입 니 다.
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
위의 예 에서 잘못된 모델 은 엄격 한 의미 에서 필요 없 지만 추가 하 는 것 을 추천 합 니 다.이렇게 하면 스 크 립 트 가 치 명 적 인 오류 (Fatal Error) 를 만 났 을 때 실행 을 멈 추 지 않 습 니 다.개발 자 에 게 PDOexception 이상 을 캡 처 합 니 다.
첫 번 째 setAttribute () 는 필수 입 니 다.이것 은 PDO 에 게 아 날로 그 예비 처 리 를 닫 고 진정한 예비 처리 문 구 를 사용 하 라 고 알려 줍 니 다.이 는 Mysql 서버 에 넘 겨 진 구문 과 값 이 해석 되 지 않 았 음 을 보증 합 니 다. (공격 자가 sql 주입 을 할 기회 가 없 도록 합 니 다.)
구조 함수 에 문자 집합 (charset) 을 설정 할 수 있 지만, 이전 버 전의 PHP (< 5.3.6) 는 DSN 에 설 치 된 문자 집합 인 자 를 무시 합 니 다.
해명 하 다.
도대체 무슨 일이 있 었 던 거 죠?당신 의 SQL 문 구 는 prepare 에 건 네 준 후에 데이터베이스 서버 에 의 해 해석 되 고 컴 파일 되 었 습 니 다.매개 변 수 를 만 듭 니 다.그리고 execute 방법 을 실행 할 때 예비 처리 문 구 는 지정 한 매개 변수 값 을 결합 시 켜 습 격 됩 니 다.
여기 서 중요 한 것 은 매개 변수 값 과 컴 파일 된 문 구 를 연결 하 는 것 입 니 다. 간단 한 SQL 문자열 이 아니 라 SQL 주입 은 스 크 립 트 를 속여 서 악의 적 인 문자열 을 추가 하여 sql 을 만들어 데이터 베 이 스 를 보 낼 때 결 과 를 가 져 옵 니 다.그래서 분 리 된 매개 변수 에서 진정한 sql 문 구 를 보 내 면 위험 을 제어 할 수 있 습 니 다. 끝 날 때 하지 않 으 려 는 일 들 이 있 습 니 다.(번역자 주: 개편 의 예 를 보십시오).사전 컴 파일 을 사용 할 때 모든 매개 변 수 는 문자열 로 사 용 됩 니 다.이 예 에서 $name 변수 가 'Sarah' 를 포함 하고 있다 면;DELETE FROM employees 라 는 결 과 는 'Sarah', DELETE FROM employees' 문자열 만 간단하게 검색 할 수 있 기 때문에 빈 표를 얻 지 못 할 것 입 니 다.
또 하나의 사전 컴 파일 을 사용 하 는 장점 은 같은 세 션 에서 하나의 statement 을 여러 번 실행 하면 한 번 만 해석 되 고 컴 파일 되 어 속도 에 더욱 우호 적 이라는 것 이다.
읊다, 읊조리다
$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');
$preparedStatement->execute(array('column' => $unsafeValue));
예비 처 리 는 동적 조회 로 사용 할 수 있 습 니까?
사전 처 리 를 조회 의 매개 변수 로 사용 할 때 동적 조회 의 구 조 는 매개 변수 화 되 지 않 고 자연 조회 특징 은 매개 변수 화 되 지 않 기 때문에 가능 한 값 을 제한 하 는 화이트 리스트 필 터 를 설정 하 는 것 이 좋 습 니 다.
// Value whitelist
// $dir can only be 'DESC' or 'ASC'
$dir = !empty($direction) ? 'DESC' : 'ASC';
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
laravel에 yo에서 angularJs&coffeescript를 사용할 수 있도록 한다.먼저 yo 명령을 사용할 수 있어야하므로 아래에서 설치 global에 설치한 곳에서 laravel의 프로젝트 루트로 이동. 클라이언트 코드를 관리하는 디렉토리를 만들고 이동합니다. 클라이언트 환경 만들기 이것으로 히...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.