2011-11-21 3 views
0

나는 현재 만든 간단한 로그인 시스템을 테스트 중입니다. 스크립트가 수행하는 작업은 내 데이터베이스에 입력 한 사용자 이름과 암호를 확인하고 둘 다 일치하면 사용자 이름을 세션 변수로 설정합니다. '회원 전용'페이지로 이동하면 세션 변수가 존재하는지 확인하고, 존재하지 않으면 사용자가 콘텐츠를 볼 수 없습니다. 의도 한대로 작동하는 것 같습니다. 위의 정보를 바탕으로 여기 내 질문이 있습니다 :쿠키로 PHP 로그인 시스템을 개선 할 수 있습니까?

  1. 내 방법에는 어떤 취약점이 있습니까?

  2. 쿠키로 쿠키를보다 안전하게 만들 수 있습니까? 그렇다면 내 코드와 어떻게 관련이 있을까요? 여기

내가 지금까지 함께 일하고 있어요 무엇 :

사용자 이름 및 암호 확인 :

<? 
session_start(); 

$username = $_POST['username']; 
$password = $_POST['password']; 

if ($username && $password){ 
$query = mysql_query("SELECT * FROM user WHERE username='$username' "); 
$numrows = mysql_num_rows($query); 

    //if user exists 
    if ($numrows !=0){ 
     while ($row = mysql_fetch_array($query)){ 
       $dbusername = $row['username']; 
       $dbpassword = $row['password']; 
      } 

     if ($username == $dbusername && md5($password) == $dbpassword){ 
      echo 'You\'re in! <a href="member.php">Click</a> here to enter the member page.'; 
      $_SESSION['username'] = $dbusername; 

     } 
     else 
      echo "incorrect password!"; 
    } 
    else 
     die("sorry, that user doesn't exist!"); 
} 



?> 

회원 전용 페이지 :

<? 
session_start(); 


if ($_SESSION['username']){ 
echo "Welcome, ".$_SESSION['username']."!<br> 
<a href='changepassword.php'>Change password</a> 
"; 
} 
else{ 
echo "please log in"; 
} 
?> 
+0

1) 큰 취약점 : SQL 주입 !! 2) md5는 sha1() 또는 bcrypt와 같은 더 나은 대안을 가지고 있습니다. 3) 쿠키가 더 안전한 것은 아닙니다 (반대의 경우). 4) XSS 공격에주의하십시오. –

답변

5

가 현재 가장 큰 보안 문제입니다 SQL 주입은 현재 스크립트에서 큰 결함입니다. 누구든지 게시 한 스크립트로 자격 증명없이 로그인 할 수 있습니다. 이 줄을 변경 :

$username = $_POST['username']; 

의 모습을 : 당신이 이미를 사용하는, 그래서 지금까지 쿠키 가서

$username = mysql_real_escape_string($_POST['username']); 

, 세션, 쿠키를 사용합니다. 둘째, 쿠키에 넣은 모든 내용이 전선을 통해 전송되므로 안전하지 않습니다.

다른 보안 방법은 암호 해시를 위해 md5 대신 bcrypt 또는 적어도 sha2 변형을 사용하는 것이 좋습니다.

자바 스크립트를 사용하여 암호를 해시하는 것이 좋습니다. SSL을 사용하지 않는 경우 매우 중요합니다.

이제 시작하겠습니다. 이러한 문제를 처리 한 후에는 CSRF 및 세션 하이재킹 공격으로 이동할 수 있습니다.

1

난 당신이 많은 이유를 들어, 쿼리를 PHP의 PDO 클래스를 사용하는 운영자 추천 : 당신이 당신의 DBMS를 변경하는 경우

  • , 당신은 모든 mysql_query(), mysql_numrows()
  • 을 편집 할 필요가없는 것입니다
  • 보안상의 이유로 PDO에는 보안 문제를 방지하기위한 몇 가지 사전 통합 기능이 있기 때문에.
  • ...

그래서, PDO와 함께, 귀하의 코드는 다음과 같다 :

<?php 
session_start(); 

$db = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS); 

$username = $_POST['username']; 
$password = $_POST['password']; 

if ($username && $password){ 
$query = $db->prepare("SELECT * FROM user WHERE username = :usr"); 
$query->execute(array('usr' => $username)); 
$numrows = $query->rowCount(); 

    //if user exists 
    if ($numrows !=0){ 
     while ($row = $query->fetch()){ 
       $dbusername = $row['username']; 
       $dbpassword = $row['password']; 
      } 

     if ($username == $dbusername && md5($password) == $dbpassword){ 
      echo 'You\'re in! <a href="member.php">Click</a> here to enter the member page.'; 
      $_SESSION['username'] = $dbusername; 

     } 
     else 
      echo "incorrect password!"; 
    } 
    else 
     die("sorry, that user doesn't exist!"); 
} 
?> 

방법 prepare()은 SQL 주입으로부터 방지 할 수 있습니다. 뒤에 execute()이 필요하지만 execute()없이 query() 메서드를 사용할 수 있습니다.

fetch() 방법은 mysql_fetch_array()과 동일합니다. 내가 도움이 http://www.php.net/manual/en/book.pdo.php

희망 :

다음은 PDO의 문서입니다.

주의 : 나는 <? 대신에 <?php을 선호합니다.

관련 문제