PHP에서 mysql 주입을 피하기 위해 사용자로부터 얻은 모든 쿠키를 mysql_real_escape_string해야 합니까?

StackOverflow https://stackoverflow.com/questions/90517

  •  01-07-2019
  •  | 
  •  

문제

사용자가 내 사이트를 방문하면 내 스크립트는 사용자 ID + 비밀번호 일부를 저장하는 2개의 쿠키를 확인하여 자동으로 로그인합니다.

쿠키 편집기를 통해 쿠키의 내용을 편집하는 것이 가능하므로, 작성된 쿠키에 일부 악성 콘텐츠를 추가하는 것도 가능하지 않을까요?

추가할까 mysql_real_escape_string (또는 다른 것)을 내 모든 쿠키 호출에 적용하거나 이러한 일이 발생하지 않도록 하는 내장된 절차가 있습니까?

도움이 되었습니까?

해결책

당신은 무엇을 정말 해야 할 일은 애초에 해킹 가능한 쿠키 값을 보내지 않는 것입니다.대신, 사용자 이름과 비밀번호, (비밀) 솔트를 해시하고 이를 쿠키 값으로 설정하는 것은 어떨까요?즉.:

define('COOKIE_SALT', 'secretblahblahlkdsfklj');
$cookie_value = sha1($username.$password.COOKIE_SALT);

그런 다음 쿠키 값이 항상 40자의 16진수 문자열이라는 것을 알고 사용자가 다시 보내는 값을 데이터베이스에 있는 값과 비교하여 유효한지 여부를 결정할 수 있습니다.

if ($user_cookie_value == sha1($username_from_db.$password_drom_db.COOKIE_SALT)) {
  # valid
} else {
  #not valid
}

mysql_real_escape_string BTW 데이터베이스에 추가 히트를 가합니다(많은 사람들이 DB 연결이 필요하고 MySQL을 쿼리해야 한다는 사실을 깨닫지 못합니다).

앱을 변경할 수 없고 해킹 가능한 쿠키 값을 사용해야 하는 경우 원하는 작업을 수행하는 가장 좋은 방법은 다음을 사용하는 것입니다. 바인딩된 매개변수가 있는 준비된 문.

다른 팁

mysql_real_escape_string의 요점은 주입 공격으로부터 보호하는 것이 아니라 데이터가 데이터베이스에 정확하게 저장되도록 하는 것입니다.따라서 소스에 관계없이 데이터베이스로 들어가는 모든 문자열에 대해 호출되어야 합니다.

그러나 다음을 수행해야 합니다. 또한 SQL 주입으로부터 자신을 보호하려면 mysqli 또는 PDO를 통해 매개변수화된 쿼리를 사용해야 합니다.그렇지 않으면 다음과 같이 끝날 위험이 있습니다. 리틀 바비 테이블의 학교.

저는 SQL 문에 변수를 삽입하기 전에만 mysql_real_escape_string을 사용합니다.변수 중 일부가 다음과 같다면 혼란스러울 것입니다. 이미 탈출했고, 그런 다음 다시 탈출했습니다.초보자의 블로그 웹앱에서 볼 수 있는 전형적인 버그입니다.

누군가 아포스트로피를 쓰면 계속 슬래시가 추가되어 블로그\\\\\\\ 페이지가 망가집니다.

변수의 값 자체는 위험하지 않습니다.위험한 물 속으로 빠져들기 시작하는 것은 끈이나 이와 유사한 것에 넣을 때만 가능합니다.

물론, 클라이언트 측에서 제공되는 어떤 것도 신뢰하지 마십시오.

준비된 명령문과 매개변수 바인딩은 항상 좋은 방법입니다.

PEAR::MDB2는 준비된 문을 지원합니다. 예:

$db = MDB2::factory( $dsn );

$types = array( 'integer', 'text' );
$sth = $db->prepare( "INSERT INTO table (ID,Text) (?,?)", $types );
if( PEAR::isError( $sth ) ) die( $sth->getMessage() );

$data = array( 5, 'some text' );
$result = $sth->execute( $data );
$sth->free();
if( PEAR::isError( $result ) ) die( $result->getMessage() );

이렇게 하면 적절한 데이터와 미리 설정된 양의 변수만 데이터베이스에 들어갈 수 있습니다.

물론 여기까지 오기 전에 데이터의 유효성을 검사해야 하지만, 명령문을 준비하는 것이 최종 유효성 검사입니다.

mysql_real_escape_string을 수행해야 합니다. 아무것 잠재적으로 해로울 수 있습니다.사용자가 변경할 수 있는 모든 유형의 입력을 절대 신뢰하지 마십시오.

나는 당신에게 동의합니다.쿠키를 수정하여 악성 데이터를 전송할 수 있습니다.

쿠키를 사용하기 전에 쿠키에서 얻은 값을 필터링하는 것이 좋은 습관이라고 생각합니다.경험상 변조될 수 있는 다른 입력은 모두 필터링합니다.

Yegor, 사용자 계정이 생성/업데이트될 때 해시를 저장할 수 있으며, 로그인이 시작될 때마다 서버에 게시된 데이터를 해시하고 해당 사용자 이름에 대해 데이터베이스에 저장된 데이터와 비교할 수 있습니다.

(느슨한 PHP의 내 머리 꼭대기에서 - 의사 코드로 취급):

$usernameFromPostDbsafe = LimitToAlphaNumUnderscore($usernameFromPost);
$result = Query("SELECT hash FROM userTable WHERE username='$usernameFromPostDbsafe' LIMIT 1;");
$hashFromDb = $result['hash'];
if( (sha1($usernameFromPost.$passwordFromPost.SALT)) == $hashFromDb ){
    //Auth Success
}else{
   //Auth Failure
}

인증에 성공하면 해시를 $_SESSION 또는 캐시된 인증된 사용자 이름/해시의 데이터베이스 테이블에 저장할 수 있습니다.그런 다음 해시를 브라우저(예: 쿠키)로 다시 보내면 후속 페이지 로드에서 해시를 서버로 다시 보내 선택한 세션 저장소에 보관된 해시와 비교할 수 있습니다.

mysql_real_escape_string은 너무 구식입니다...요즘에는 매개변수 바인딩을 대신 사용해야 합니다.

내가 언급한 내용을 언급하면서 자세히 설명하겠습니다. 준비된 진술 때로는 mysl_real_escape_string이 충분하지 않음을 보여주는 기사에 대한 링크를 제공하십시오. http://www.webappsec.org/projects/articles/091007.txt

mysql_real_escape_string 대신 htmlentities($input, ENT_QUOTES)를 사용하는 것이 좋습니다. 이렇게 하면 실수로 실제 HTML 코드가 출력되는 것을 방지할 수 있습니다.물론 mysql_real_escape_string과 htmlentities를 사용할 수도 있지만 왜 그럴까요?

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