2012-03-04 2 views
1

previous question I had posted에 대한 응답으로 데이터베이스를 SQL 주입으로 열었다는 응답이있었습니다.SQL 주입을 방지하기 위해 수행해야하는 단계는 무엇입니까?

<?php 


     $firstname = stripslashes(strip_tags($_POST['firstname'])); 

     $lastname = stripslashes(strip_tags($_POST['lastname'])); 
     $email = stripslashes(strip_tags($_POST['email'])); 
     $title = stripslashes(strip_tags($_POST['title'])); 
     $organization = stripslashes(strip_tags($_POST['organization'])); 


    $pdbHost = "localhost"; 
    $pdbUserName = "******"; 
    $pdbPassword = "******"; 
    $pdbName  = "db1080824_emails"; 



    // Connect to mySQL 
    $conlink = mysql_connect($pdbHost, $pdbUserName, $pdbPassword); 
    if(!$conlink) {die('Unable to connect to '.$pdbHost);} 
    if (!mysql_select_db($pdbName, $conlink)){die('Cannot find database '.$pdbName);} 

    //SQL query 

     $SQL2="INSERT INTO `db1080824_emails`.`emails` (`record_id` ,`firstname`,`lastname`,`email`,`title`,`organization`)VALUES (NULL , '".$firstname."', '".$lastname."', '".$email."', '".$title."', '".$organization."')"; 

     mysql_query($SQL2); 
    // Connect to Closing the connection 
    mysql_close($conlink); 
?> 

제안 내가위한 서버 측 유효성 검사를 할 수 있었다 '/가^[A-ZA는-Z0-9] /'일어날 수없는 SQL 인젝션 없도록하지만 충분한 것입니다 : 코드는 아래와 같습니다 아니면 데이터 위생을 보장하기 위해 따라야 할 모범 사례가 있습니까?

+0

http://en.wikipedia.org/wiki/SQL_injection을 - 더 읽어 어떻게 이루어집니다 및 호 w를 "실행 취소" – Joseph

+1

준비된 진술 만 사용하십시오. 기간. – knittl

+3

첫 번째 단계 : ** mysql_query ** 사용을 중단하고 PDO 또는 mysqli와 같은 최신 API를 사용하십시오. 둘 다 준비된 문을 지원합니다. SQL 문을 제대로 사용하면 SQL 주입을 방지하는 데 많은 도움이됩니다. – cHao

답변

3

준비된 문구를 사용하십시오. 진지하게. 이렇게하는 쉬운 방법은 PHP의 데이터베이스 래퍼 PDO을 사용하는 것입니다.

$firstname = $_POST['firstname']; 
$lastname = …; 
… 

$db = new PDO('mysql:host=hostname;dbname=dbname', 'username', 'password'); 
$stmt = $db->prepare('INSERT INTO `db1080824_emails`.`emails` (`firstname`,`lastname`,`email`,`title`,`organization`) 
    VALUES (:firstname, :lastname, :email, :title, :organization)'); 
$stmt->execute(array(
    ':firstname' => $firstname, 
    ':lastname' => $lastname, 
    ':email' => $email, 
    ':title' => $title, 
    ':organization' => $organization)); 
1

SQL 삽입을 방지하려면 mysql_real_escape_string()을 사용하십시오. 이 기능 만 있으면 충분합니다.

그리고 @knittl이 말한대로 준비된 명령문을 사용하는 것은 예방하기위한 좋은 방법이기도합니다. 그러나 일반적인 mysql_labary는이를 지원하지 않습니다. 당신은 PDO 나 MySQLi 같은 라이브러리를 필요로합니다. 더 높은 PHP 버전에서는 mysql_ * libary가 더 이상 사용되지 않기 때문에 PDO 나 MySQLi로 전환 할 것을 제안합니다.

  • die()를 사용하지 않는 :

    다른 팁은 코드를 향상시킬 수 있습니다. 실수하면 실수로 죽지 않을 것입니다. 왜 컴퓨터입니까? 좋은 오류를 처리하고 원하는 오류를 처리하는 것이 좋습니다.

  • mysql_close()은 필요하지 않습니다. PHP는 실행이 끝날 때마다 모든 연결을 닫습니다.
  • 쿼리에서 오류 처리를 사용합니다. 쿼리에서 false가 반환되면 문제가 발생합니다. 또한 쿼리가 완료되면 mysql_affected_rows() 또는 mysql_num_rows으로 확인하십시오.

나는이 답변에 대한 의견을 답변을 주문한다. 문자열의 경우에만 mysql_real_escape_ 문자열을 사용해야합니다. 당신이 mysql_real_escape_string()을 사용하는 경우 쿼리에서 문자열 따옴표 (')을 넣어 가지고해야합니다 :

$query = "SELECT foo FROM bar WHERE name = '".mysql_real_escape_string($_POST['name'])."'"; 

당신이 intergers를 사용하거나 다른 번호가이 이스케이프 기능 typecasting를 사용하지 않아야하는 경우 :

$query = "SELECT foo FROM bar WHERE id = ".(int) $_POST['id']; 
+0

mysql_real_escape_string을 사용할 수 있습니다. 즉, 따옴표로 묶인 값 (예 : _every_ 같은 값)에만 사용하고 클라이언트 측 (PHP) 및 서버/연결 측 (mysql)에 올바른 인코딩을 설정하십시오. 작은 일을 놓치고 다시 망칠 수있는 곳이 너무 많습니다. – knittl

+0

이 기능은 주사를 예방하는 것이 아닙니다. Go figure –

+0

의견을 주셔서 감사합니다. 몇 가지 정보로 답변을 업데이트했습니다. @ Col.Shrapnel이 함수는 SQL 주입을 방지하지 않는 이유는 무엇입니까? php.net에서 :'이 함수가 데이터를 이스케이프하는 데 사용되지 않으면 쿼리가 SQL 주입 공격에 취약합니다. ' –

0
내가 PDO를 사용하고

, 나는이 주사로부터 보호 있다고 생각 :

$db_user = "****"; 
$db_pass= "****"; 
$dsn = "mysql:dbname=yourdatabasename; host=localhost"; 
$dbh = new PDO($dsn, $db_user, $db_pass); 

$sql = 'INSERT INTO 
     emails(firstname, lastname, email, title, organization) 
     VALUES(:firstname,:lastname,:email,:title,:organization)'; 
$data = array(':firstname'=>$firstname, 
       ':lastname'=>$lastname, 
       ':email'=>$email, 
       ':title'=>$title, 
       ':organization'=>$organization); 

$sth = $dbh->prepare($sql); 
$sth->execute($data); 
+0

너무 느리게 입력합니다. – TerryProbert

관련 문제