어떻게 PHP 에서 SQL 주입 을 방지 합 니까?

6806 단어 PHPStackOverflow
어떻게 PHP 에서 SQL 주입 을 방지 합 니까?
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 코드 를 삽입 할 수 없다.
이것 을 완성 하 는 두 가지 방법 이 있다.
  • PDO 대상 사용 (모든 데이터베이스 구동 에 좋 음)
  • $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'; 

    좋은 웹페이지 즐겨찾기