2009-05-12 6 views
0

저는 몇 년 전에 작성한 회사 사이트에서 일부 오류를 정리해야했습니다. 나는 여기에 내가 작성하지 않은주의 사항을 게시하는 코드를 소개하고자한다. 그리고 그것은 매우 안전한 로그인 시스템이 아니라는 것을 알고있다. 그러나 나는 그 버그를 바로 잡기 위해 할당되었다.HTML 로그인 양식 반환 오류

문제 : 사용자가 로그인하면 양식을 제출 한 후 페이지가 새로 고쳐진 것으로 보이므로 자격 증명을 다시 입력해야합니다. 로그인 오류가보고되지 않습니다. 지금까지 Firefox와 Safari에서만이 문제를 복제 할 수있었습니다. 로그인에 성공한 후 로그 아웃하고 다시 로그인하면 모든 것이 정상적으로 작동하는 것 같습니다. 브라우저를 처음 시작하고 처음 로그인을 시도한 직후입니다. 나는 이것을 다른 Mac/Windows PC에서도 복제했다.

다음은 기본 로그인 페이지 HTML입니다. 나는 불필요한 것들을 잘라 내고 있지만 필요한 경우 더 많은 코드를 제공 할 수 있습니다.

<?php 
$db = mysql_connect('***', '***', '***') or die("Couldn't connect to the database."); 
mysql_select_db('***') or die("Couldn't select the database"); 

$result = mysql_query("SELECT count(id) FROM merchants WHERE passw='$_POST[password]' AND usern='$_POST[username]'") or die("Couldn't query the user-database."); 
$num = mysql_result($result, 0); 

if (!$num) { 

// When the query didn't return anything, 
// display the login form. 

$message = "Login Failed: Incorrect username or password"; 

header('Location: login.php?message='.$message); 


} else { 

// Start the login session 
session_start(); 


// All output text below this line will be displayed 
// to the users that are authenticated. Since no text 
// has been output yet, you could also use redirect 
// the user to the next page using the header() function. 
header('Location: merchants/index.php'); 
} 

사람이 내가보고 시작해야하는 위치에서 아이디어가 있습니까

: 여기
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
... 

<body> 
      <form name="login" method="post" id="mainform" action="clogin.php"> 
       <label for="username">Username:</label> 
       <input type="text" id="username" name="username"><br /> 
       <label for="password">Password:</label> 
       <input type="password" id="password" name="password"><br /> 
       <input type="submit" name="Submit" class="button" style="float:right;" value="Login">     
      </form> 
</body> 

는 PHP, 또한 지방에 대한 손질입니까? 내 첫 번째 생각은 양식이 실제로 완전히 제출하지 않는다는 것입니까? 그 일이 벌어지고 있는지 어떻게 알 수 있습니까? 모든 힌트 또는 포인터가 좋을 것입니다. 개인적으로이 문제를 일으킬 수있는 "코드"문제를 찾을 수 없습니다.

+0

양식이 "새로 고침"되면 주소 표시 줄에 무엇이 표시됩니까? "? message = ..."텍스트가 주소 끝에 추가 되었습니까? 아니면 그냥 "login.php"입니까? –

+0

? message = ...가 추가되지 않았습니다. 그래서 그 양식이 실제로 그 스크립트를 전혀 치는 것이 아닐 수도 있습니다. 문제는 복제하기가 매우 어렵 기 때문에 어떤 조건에서 발생하는지 완전히 정의하는 데 어려움이 있습니다. 처음에는 깨끗한 브라우저 시작으로 복제 할 수있게 된 후 이제는 내 컴퓨터에 다시 표시되기까지 2-3 회의 재시작이 필요합니다. 그러나 제 동역자는 항상 그럴 시간이 있습니다. – Mesidin

답변

0

Firefox 용 Tamper Data add on을 받으십시오. 그러면 서버에서 양식 게시물과 응답을 다시 볼 수 있습니다. 동일한 작업을 수행 할 다른 추가 기능이 있거나 IE에서 동일한 데이터를 볼 필요가있는 경우 Fiddler을 얻을 수 있습니다.

+0

이 도구들은 분명 내가 생각하는 데 도움이 될 것입니다. 물론, 내가 가지고 있기 때문에, 다시 나타나기 위해 오류를 얻는데 어려움을 겪고있다. 그것은 여전히 ​​동료의 컴퓨터에서 일어나고 있지만 내 것이 아닙니다. – Mesidin

0

무엇 대신에, 당신은 대신 *을 선택 mysql_num_rows에 대한 mysql_result 교체 COUNT(id)을 선택하는 여전히 오류가 발생하는 경우? 양식이 제대로 제출되지처럼 오히려 보는가 말하는대로 소리 충동에 저항 'SQL 인젝션 공격을 !!!! 1111'

$result = mysql_query("SELECT * FROM merchants WHERE passw='$_POST[password]' AND usern='$_POST[username]'") or die("Couldn't query the user-database."); 
$num = mysql_num_rows($result); 

if ($num < 1) { 
+0

이것은 효과가없는 것으로 보입니다. 솔직히 말해서, 나는 페이지가 단지 상쾌 해 보이는 것처럼 보입니다. 그리고 그것은 전혀 스크립트하지 않을 것입니다. 이 문제가 실제로 발생했는지 확인하기 위해 불법 복제품 파이어 폭스 플러그인 문제를 복제하려고합니다. – Mesidin

1

.

아이디어의 몇 :

당신이 데이터베이스를 쿼리하기 전에 양식이 코드에 제출 된 것을 어떤 방법으로 확인합니까? 그렇다면이 값은 확실히 게시됩니까?

<button type="submit"> 태그가 해당 버튼에 할당 된 값없이 양식을 제출하기 전에 Firefox/Safari에서이 문제가 발생했습니다. IE (< 8)는 문제가 없었지만 다른 브라우저는 그렇지 않았습니다. .

die('<pre>'.print_r($_POST,true).'</pre>'); 
+0

ㅎ. 이제 내가 왜주의해야하는지 알겠 군. 문제가 해결되지 않으면 취약점에 항의하는 경우에도 코드를 변경하지 말라는 특별 요청을 받았습니다. 가! 나뿐만 아니라 그것을 보면서 견과를 몰아 라. 그것은 말도 안돼. 나는 그것을 시험해보고 내가 생각해 낼 수있는 것을 보게 될 것이다! – Mesidin

0

그냥 여기 재 작성에 대한 가서 어떻게 작동하는지 볼 수 있습니다 :

<?php 
$db = mysql_connect('***', '***', '***') or die("Couldn't connect to the db."); 
mysql_select_db('***') or die("Couldn't select the db"); 

$result = mysql_query("SELECT id FROM merchants WHERE passw='%s' AND usern='%s'", 
         mysql_real_escape_string($_POST['username']), 
         mysql_real_escape_string($_POST['password'])) 
     or die("Couldn't query the user table."); 

if (mysql_num_rows($result) != 0) { 
    $user = mysql_fetch_assoc($result); 
    $userId = $user['id']; 

    // Destroy any old session data from before for a fresh session 
    session_destroy(); 
    session_start(); 

    header('Location: merchants/index.php'); 
    exit(); 
} else { 
    $message = "Login Failed: Incorrect username or password"; 

    header('Location: login.php?message='.$message); 
    exit(); 
} 
?> 

가 슛 것을 부여

제출됩니다 정확히 확인하기 위해 제출 페이지에 다음 코드를 넣습니다 . 더 이상 코드가 실행되지 않도록하기 위해 헤더의 위치를 ​​설정 한 후에 항상 exit()를 throw하는 것이 좋습니다.

당신이 그것에있는 동안 당신은 쿼리 문자열을 통해 반대로였습니다 세션 배열에서 설정 한 오류 메시지를 다시 보낼 수도 있습니다 : 다음

... 
} else { 
    $message = "Login Failed: Incorrect username or password"; 
    $_SESSION['login_error'] = $message; 
    header('Location: login.php'); 
    exit(); 
} 

를 바로 액세스 $ _SESSION [ 'login_message']를 클릭하여 오류를 표시하십시오.

Id이 코드를 사용하면 $ _POST 배열의 일부 var_dump()을 양식에 입력하려고 시도하지 않습니다.