2017-02-26 12 views
0

간략하지만 흥미로운 것은 여기입니다. 나는 이상하게 여기고 있을지 모르지만, 지금은 몇 시간을 잃었고 그 문제가 무엇인지 알 수 없습니다.값이 일치 할 때 random_bytes 비교가 실패합니다.

나는 넌스를 생성하는 함수를 가지고있다. 지금은별로 복잡하지 않지만 새로운 개념의 실험입니다. 과 같이, 동시에 내 양식에 사용되는 동안

$session->add('nonce',$token); 

(which is essentially....) 
$_SESSION[$var] = $val; 

:

$token = random_bytes(16); 

이 다음과 같이 저장됩니다 : 나는 PHP7 +에 대한 mcrypt_create_iv에 자연의 후계자로 random_bytes을 사용하고

<input name="token" type="hidden" value="<?=$token?>"> 

양식이 제출되고 일부 유효성 검사 등이 통과됩니다. 이 중 하나의 값으로 두 값을 모두 가져옵니다.

$token = $_POST['token']; 
$nonce = $session->get('nonce'); 

다음에 두 값이 일치하는 경우에만 진행됩니다. 문제는 실제로 유효성을 검사 할 수 없다는 것입니다. 사실 이러한 전류 출력의 어느 :

if(hash_equals($nonce, $token)) 
if($nonce === $token) 

var_dump 보여줍니다 모두 동일한 길이의 문자열하지만, ​​어떤 이유로 그들은 비교할 수 없습니다. 두 값은 일치하는 것처럼 보입니다. $_POST 또는 문자 그대로 단지에서 읽어 내 검색 기능 (을 통해 중,

if(hash_equals($nonce, $nonce)) 

는 (예상대로) true로 동일, 그래서 나는 단지 값 중 하나가 길을 따라 변경되고 있다고 가정 할 수 있습니다 세션).

나는 어떤 도움이나 제안도 주시면 고맙겠습니다. 저는 분명히 뭔가를 간과하거나 너무 경험이 없습니다.

답변

3

모든 임의의 바이트 값이 HTML에서 직접 유효하지는 않습니다. 문자열에 ASCII 문자와 숫자 ([0-9a-zA-z])의 정규 시퀀스 이외의 값이 포함되어 있으면 HTML 컨텍스트에서 이스케이프하지 않으면 아무 일도 발생할 수 없습니다. 필요한 경우 htmlspecialchars을 사용하여 값을 이스케이프하거나 해시 또는 base64로 인코딩 된 임의의 바이트를 대신 사용할 수 있습니다.

ascii 값이 " 인 경우 좋은 예는 16 개의 임의 바이트에 HTML 속성이 일찍 끝나는 것입니다. HTML은 제어 시퀀스 (낮은 ascii 문자) 또는 현재 인코딩 외부의 문자를 사용하지 않습니다 (UTF-8 인 경우 127보다 큰 값은 여러 바이트로 볼 때 유효한 UTF-8 코드 포인트 여야합니다).

+1

우수 - 이제'$ token = base64_encode (random_bytes (16));'에 대한 기능이 수정되었습니다. 그럼에도 불구하고 전설에 불과합니다. –