2012-07-10 2 views
2

localhost에 간단한 등록 양식 (아직 테스트 중)이 있는데 SQL 인젝션으로 공격받을 수 있는지 궁금합니다.등록 양식에 SQL 삽입 피하기

코드 :

$name = mysql_real_escape_string($_POST['name']); 
$password = mysql_real_escape_string($_POST['password']); 
$password = md5($password); 
$email = mysql_real_escape_string($_POST['email']); 
$refId = $_GET['refid']; 
$ip = $_SERVER['REMOTE_ADDR']; 


$add = mysql_query("INSERT INTO `users` (`name`, `password`, `email`, `refId`, `ip`) 
VALUES('$name','$password','$email','$refId', '$ip')") or die(mysql_error()); 

가 안전 아니면 누군가가 (나는 방법을 알고 싶습니다) SQL 주입을 사용할 수 있습니까? 어떻게 주사를 피할 수 있습니까?

+0

이미 읽었습니까? [읽었습니다.] (http://stackoverflow.com/questions/60174/best-way-to-prevent-sql-injection-in-php) already? master 및 slave DB, 저장 프로 시저를 사용하고, 필요에 따라 자신의 함수로 문자열을 구문 분석하십시오. –

+2

mysql_ 라이브러리를 사용하여 주입을 피하면 모든 단일 쿼리에 대해 지루한 작업이 필요합니다. 질의, 그리고 심지어 당신은 안전하다는 보장이 없습니다. 주입을 피하는 표준 방법은 준비된 쿼리를 사용하는 것입니다.이 준비 쿼리는 db 엔진에 전달한 문자열을 지정한 쿼리의 인수가 아닌 다른 것으로 처리하면 안됩니다. PHP에는 mysqli와 PDO를위한 두 개의 라이브러리가있다. 구글 그들과 준비된 쿼리를 읽어보십시오. 설정하는 데 조금 더 시간이 걸리지 만 그만한 가치가 있습니다. – octern

+0

SQL 인젝션을 피하기 위해 저장 프로 시저가 필요하지는 않습니다. 준비된 진술은 가장 쉬운 접근법이거나 Doctrine이나 Propel과 같은 ORM입니다. – halfer

답변

5

실제로 이것은 취약합니다. 너는 $_GET['refid']을 피하지 않았다. 예를 들어,이 URL을 가지고 :

yourpage.php?refid='%2C'')%3B%20DROP%20TABLE%20users%3B-- 

방지 SQL 주입이 용이하다. 준비된 진술과 PDO를 사용하십시오. 예를 들어 :

$query = $dbh->prepare("INSERT INTO `users`(`name`, `password`, `email`, `refId`, `ip`) 
VALUES(:name, :password, :email, :refId, :ip)"); 
$query->bindValue(':name', $_POST['name']); 
$query->bindValue(':password', md5($_POST['password'])); # Do not use MD5 for password hashing, and especially not without salt. 
$query->bindValue(':email', $_POST['email']); 
$query->bindValue(':refid', $_GET['refid']); 
$query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); 
$query->execute(); 
+0

Md5를 결코 사용하지 않고 두 번째로 염분 . 적어도 sha2와 같은 것을 사용하십시오. PBKDF2를 사용하십시오. – CountMurphy

+1

@CountMurphy : 개인적으로, 필자는 bcrypt를 권장합니다. –

+0

은 bcrypt를 잊어 버렸습니다. 잘 했어. – CountMurphy

4

당신은이 $_GET에서 잡고에도 불구하고, $refIdmysql_real_escape_string을하지 않았다. 기본적으로 다른 모든 주사 예방 조치를 취하지 않습니다. 탄젠트에서 md5-ing 전에 암호를 이스케이프하면 해시가 변경됩니다.

6

주사를 피하는 가장 좋은 방법은 Prepared Statements입니다.
준비된 진술에 대해서는 모든 DB 항목을 처리하기 위해 PDO를 사용하는 것을 선호합니다. PDO에 대한 자세한 내용은

$sql=new PDO("mysql:host=127.0.0.1;dbname=name","user","password"); 
     $user=$_POST[user]; 

     $query="select Salt,Passwd from User 
       where Name=:user"; 
     $stmt=$sql->prepare($query); 
     $stmt->bindParam(':user',$user); 
     $stmt->execute(); 
     $dr=$stmt->fetch();   
     $sql=null; 
     $password=$_POST[pass]; 
     $salt=$dr['Salt']; 

... 등

읽기 this 페이지 : 여기에 내가 몇 가지 기본 로그인 정보를 검색 할 쓴 일부 PDO 샘플 코드입니다. 여기서 각 코드 행이 무엇인지 알고 싶다면 this 답장을 읽고 다른 게시물에 답하십시오.

+0

당신은 사용자마다 다른 소금을 가지고 있습니까 ??? 나는 그것을 좋아한다. – jcho360

+0

음, 모두가 같은 소금을 가지고 있다면 목적을 이겨내는 것입니다.) – CountMurphy

관련 문제