문제

다음 인증 스크립트가 완료되어야합니다. PHP/PDO에서 약해서 행의 수를 묻는 방법을 모르고 쿼리 결과에서 세션 ID를 설정하는 방법을 모릅니다. 결과에서 $ _session [ 'userId']뿐만 아니라 [ 'Company']와 [ 'security_id']를 설정해야합니다.

다음은 다음과 같습니다.

$userid   = $_POST['userid'];
$password = $_POST['pass'];
if ( $userid != "" || $password != "" )
{
  $sql = "SELECT * FROM contractors WHERE userid = '" . $userid . "' AND password = '" . $password . "'";
  $result = $dbh->query( $sql );
} else
{
  echo "login failed. Your fingers are too big";
}

선택 정보 : 브라우저 : Firefox

도움이 되었습니까?

해결책

그 코드를 사용하지 마십시오!

당신은 매우 심각한 SQL 주입이 열려 있습니다. 쿠키 나 CGI 또는 대체 어디에, 소독해야합니다 SQL 문에 사용되기 전에. 다음과 같은 사용자 이름으로 로그인을 시도하여 해당 시스템에 쉽게 침입 할 수 있습니다.

user'; UPDATE contractors SET password = '1337'

... 그 후에 나는 누군가로 로그인 할 수있었습니다. 내가 공격적으로 들리면 죄송하지만 코드가하는 일은 경보 시스템이 포함되어 있지 않은 회사에 정문을 고정시키는 것을 잊어 버리는 것과 같습니다.

입력이 실제로 사용자에게서 나오는지 여부는 중요하지 않습니다 (아마도 미리 채워진 숨겨진). 보안 관점에서 아무것 그것은 외부의 어느 곳에서나 나옵니다 가지다 사용자가 악의적 인 입력을 포함하는 것으로 간주됩니다.

내가 아는 한, 당신은 quote 문자열을 올바르게 소독하기위한 pdo의 함수. (MySQL에서는이 작업이 완료됩니다 mysql_real_escape_string().) 나는 PDO의 전문가가 아닙니다. 당신을 염두에 두십시오. 누군가 내가 여기서 틀렸다면 수정하십시오.

또한 비밀번호를 데이터베이스에 직접 저장해서는 안되며 해시 기능을 사용하여 마스크 된 암호를 만들고 사용자가 제공 한 비밀번호에서 해시를 생성하고 해시와 일치시킵니다. PHP를 사용할 수 있습니다 hash 이 작업을 수행하는 기능.

다른 문제에 관해서는, SQL Select에있는 접근 방식이 최선의 방법인지 모르겠습니다. 해당 사용자의 비밀번호를 선택하고 프로그램에서이를 일치시킵니다. 나는 당신이 사용하는 방법에 어떤 결함이 있다고 생각하지 않지만, 그것은 논리적으로 보이지 않으므로 더 큰 기회가 있습니다. 일부 버그 누락 - 암호와 로그인의 경우 익스플로잇을위한 창이 생성됩니다.

당신의 길을하려면, 당신은 당신이 얻은 결과가 pdo query a PDOStatement, 그것은 결과 행의 양을 다리로 계산할 수있는 신뢰할 수있는 기능이없는 것 같습니다. 사용해야 할 것은 fetchAll 행의 배열을 반환하고 계산합니다. 그러나 내가 말했듯이,이 모든 것이 실패에 열려있는 것처럼 느껴지므로 코드에서 암호를 더 안전하게 확인하는 느낌이 들었습니다. 그런 보안 크리티컬 한 곳에서 실제 암호 일치하는 Compasion과 너무 멀리 떨어져 있습니다.

따라서 userID의 결과 비밀번호를 얻으려면 PDOSTATEMENT를 사용할 수 있습니다. fetch() 결과에서 열 내용을 반환합니다. 예를 들어 사용하십시오 PDO::FETCH_ASSOC 열 이름을 기준으로 연관 배열로 가져 오기 위해.

다음은 해결 방법입니다.

$userid_dirty   = $_POST['userid'];
$password_dirty = $_POST['pass'];
$success = false; // This is to make it more clear what the result is at the end
if ($userid != "" || $password != "") {
  $userid = $dbh->quote($userid_dirty);
  $passwordhash = hash('sha256',$password_dirty);
  $sql = "SELECT userid, passwordhash, company, security_id FROM contractors WHERE userid = ".$userid;
  $result = $dbh->query( $sql );
  if ($result) { // Check if result not empty, that userid exists
    $result_array = $result->fetch(PDO::FETCH_ASSOC);
    if ($result_array['PASSWORDHASH'] == $passwordhash) {
       // login success
       $success = true;

       // do all the login stuff here...
       // such as saving $result_array['USERID'], $result_array['COMPANY'], $result_array['SECURITY_ID'] etc. 

    } // else fail, wrong password
  } // else fail, no such user
} else {
  // fail, userid or password missing
  echo ' please enter user id and password.';
}
if (!$success) {
  echo ' login failed.';
}

물론 코드는 약간 정리할 수 있지만 수행해야 할 작업을 설명해야합니다. 비밀번호는 해시되고 SQL에는 사용되지 않았습니다, 실제로 청소가 필요하지 않습니다. 그러나 나는 원래 코드에서 그것을 대신하여 거기에 두었습니다. ~였다 쿼리에 사용됩니다.

비밀번호 저장에 관한 모든 코드는 암호 대신 해시를 저장하려면 변경해야합니다. 또한 사용하는 것이 아주 좋은 생각입니다. 소금 해싱 전에 비밀번호에 추가되었습니다.

또한 교육 목적으로 단순히 코드를 제공했습니다. 단지 코드 가이 작업을 수행하는 방법을 설명하는 가장 분명한 방법이라고 생각했습니다. 따라서이 사이트를 코드를 요청하는 서비스로 착각하지 마십시오. :)

다른 팁

그만큼 PHP 매뉴얼 PHP 학습을위한 훌륭한 리소스입니다. 그것은 당신이 약간의 SQL을 알고있는 것처럼 보이고, 당신은 좋은 출발 인 PDO에 대해 들었습니다. "PDO"를 Google을 검색하거나 용어를 위해 PHP 매뉴얼을 검색하면 PDO 섹션 매뉴얼의. 당신이 찾은 것 같습니다 ->query 기능, 이제 그 반환이 무엇인지 확인해야합니다. 그 기능으로 이동합니다 수동 페이지, 우리는 그것이 반환되는 것을 본다 PDOStatement 물체. 단어 PDOStatement 매뉴얼의 관련 페이지에 도움이되며 해당 객체에서 사용 가능한 메소드가 나열되어 있습니다. 이있다 rowCount() 원하는 작업을 수행 할 수있는 방법.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top