KWONKYU

PHP 시큐어 코딩 #6

May 15th, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.99 KB | None | 0 0
  1. #1.
  2. 인증(Authentication)은 사용자의 신원을 증명하기 위해 사용되는 과정을 의미한다. 일반적으로 로그인을 거친 사용자를 인증된 사용자라 할 수 있다.
  3. 권한 부여(Authorization)는 리소스에 대한 접근을 보호하는 방법, 즉 사용자가 특정 리소스에 접근할 수 있는 권한을 갖고 있는지를 결정하는 것이다. 접근 제어(Access Control)라고도 할 수 있다.
  4.  
  5. 접근 제어 취약점이 발생하는 원인은 대부분 부주의(적게 사용되는 부분에는 적은 관심)에 기인한다. 자주 사용되는 부분이라도 이 기능들은 인증된 사용자를 염두에 두고 쓰여지지 공격자가 무엇을 시도할지 고려하고 작성되지 않기 때문이다. 만약 공격자가 정상적인 사용자로 가장할 수 있다면 사용자 ID에 기반한 접근 제어는 쓸모없어지며 그렇기 때문에 접근 제어에도 신뢰할 수 있는 신분 확인 방법이 필요하다. 이외에도 세션 하이재킹 등을 염두에 두어야 하기 때문에... 아무튼 인증과 권한 부여와 관련된 4가지 공격은 다음과 같다.
  6.  
  7. #2.무차별 공격
  8. Brute Force. 사전 공격(Dictionary Attack. 무차별이 아니라 가능성이 높은 것들만 시도한다)과 비슷하다. 단순히 인증 시도를 제한하거나 실패 횟수를 제한하는 등은 일반 사용자에게까지 불이익을 주지 않고서는 공격자를 식별하고 막을 수 없다는 딜레마가 존재한다. 이에 대응해서 다른 방법은 일관성을 찾아내는 것이다. 이전에 세션 하이재킹에 대비하여 수행한 심층 방어 전략과 비슷하지만 이는 정상적인 사용자 식별이 아니라 공격자 식별에 그 목적이 있다는 차이점이 있다. 만약 공격자가 다음과 같은 스크립트를 사용하여 무차별 공격을 수행한다고 해 보자.
  9. <?php
  10. $username = 'victim';
  11. $password = 'guess';
  12.  
  13. $content = "username=$username&password=$password";
  14. $content_length = strlen($content);
  15.  
  16. $http_request = '';
  17. $http_response = '';
  18.  
  19. $http_request .= "POST /login.php HTTP/1.1\r\n";
  20. $http_request .= "Host: Example.org\r\n";
  21. $http_request .= "Content-Type: application/x-www-form-urlencoded\r\n";
  22. $http_request .= "Content-Length: $content_length\r\n";
  23. $http_request .= "Connection: close\r\n";
  24. $http_request .= "\r\n";
  25. $http_request .= $content;
  26.  
  27. if($handle = fsockopen('example.org', 80)){
  28. fputs($handle, $http_request);
  29.  
  30. while(!feof($handle)){
  31. $http_response .= fgets($handle, 1024);
  32. }
  33.  
  34. fclose($handle);
  35.  
  36. // Check result.
  37. } else {
  38. // ERROR!
  39. }
  40. 이를 이용했을 때 공격자는 비밀번호를 변경해가면서 인증을 시도해가면서 $http_response를 검사하여 변경 사항이 있는지만 검사하면 된다. 이는 최대 로그인 실패 횟수를 이용하여 계정을 정지시키는 방법 등이 있겠지만 이보다는 성공 확률을 낮추고 무차별 공격이 통하지 않도록 시간 지연(throttling)을 사용할 수 있다. time() 을 이용하여 마지막 로그인 실패 시간 이후 일정 시간 이내에 로그인 요청이 들어왔다면 인증에 성공했더라도 틀렸다고 표시하는 것이다. 물론 이는 출력에 차이가 없어야 공격자가 이를 눈치채지 못할 것이다.
  41.  
  42. #3.패스워드 스니핑
  43. 접근 제어에만 해당하는 것이 아니지만, 사용자와 응용프로그램 사이의 트래픽을 훔쳐보는것은, 특히 인증 정보와 관련된 데이터가 유출된다면 심각한 피해로 이어질 수 있다. 제일 효고적인 방법은 SSL, 즉 https를 사용하는 것인데 세션ID부터 모든 요청에 SSL을 사용하는 것이 제일 좋을 것이다. 이를 적용할 때는 폼의 action에 https를 사용하는 것 뿐 아니라 HTML 폼 자체도 SSL로 보호하면 신뢰감을 줄 수 있다(자물쇠 마크).
  44.  
  45. #4.리플레이 공격
  46. Playback Attack이라고도 한다. 이는 정상적인 사용자가 액세스 권한이나 특별한 권한을 얻기 위해 전송한 데이터를 공격자가 재전송하는 종류의 공격을 칭한다. 패스워드 스니핑과 마찬가지로 데이터 유출에 의해 일어날 가능성이 크며 이를 차단하려면 접근이 제한된 리소스에 대한 권한을 얻기 위해 사용되는 데이터가 공격자에 의해 캡처되지 않도록 조치해야 한다. 즉 접근이 제한된 리소스에 대한 액세스를 기억하는 데이터의 사용이나 액세스를 제공하는 데이터의 유출을 지양해야 한다. 즉 접근이 제한된 리소스에 대해서는 임시 액세스를 허용하는 데이터만 사용해야 하며 이것 역시 유출되지 않도록 해야 한다.
  47.  
  48. 전자의 경우 패스워드 해싱 스크립트를 클라이언트 기반으로 실행하는 것인데 이는 사용자의 본래 비밀번호는 보호할 수 있어도 공격자가 이 인증과정을 리플레이하는 것에는 여전히 취약하다는 문제를 안고 있다.
  49.  
  50. #5.로그인 정보 기억
  51. Persistent Login. 이는 브라우저 세션 사이에서 인증 정보를 유지하기 위한 방법으로 사용자의 세션이 만료된 경우에도 로그인 상태가 유지되는 것을 말한다. 이는 사용자 인증 구조의 보안 수준을 떨어뜨리지만 사용성을 증가시킨다. 이는 쿠키에 넣어서 사용할 수도 있겠지만 상당히 위험한 방법이기에 대책이 필요하다. 첫 번째로는 이 쿠키가 캡처당하는 경우에도 위험을 줄이는 방법을 고안해내는 것이다.
  52.  
  53. 이를테면 사용자 비밀번호를 사용하는 대신에 단 한번의 인증에 대해서만 유효한 토큰을 생성하는 것이다. 이 토큰은 특정 사용자와 연결하기 위해 사용자의 세션에 토큰을 저장할 수 있지만 이는 로그인을 유지하는 것 외에는 아무런 동작을 하지 않는다. 즉 토큰과 특정 사용자를 연결하려면 다른 방법을 사용해야 한다.
  54.  
  55. 이외에도 사용자의 이름이나 다른 정보를 이용해 2차 식별자를 이용하여 토큰과 같이 사용자의 인증 정보를 누출하지 않는 쿠키를 생성하여 사용할 수도 있다. 이 경우에는 잘못된 토큰, 잘못된 식별자, 시간 만료 등 여러 요인에 의해 로그인이 실패할 수 있을 것이다.
  56.  
  57. 중요한 것은 쿠키는 1주일 또는 그 이하의 기간 안에 만료되어야 하며 오직 한 번의 인증에 대해서만 유효해야 한다. 즉 로그인이 성공한 다음에는 삭제하거나 재생성해야 하며 기간 만료(timeout)는 서버에서 강제적으로 수행되어야 한다. 쿠키를 이상한 값으로 덮어쓴다던지 하는 방법으로 강제할 수 있을 것이다.
  58.  
  59. 하지만 중요한 기능에 대해서는 사용자에게 비밀번호를 다시 입력하도록 요구하는 것이 제일 바람직하다. 이런 로그인 정보 유지는 덜 중요하다고 여겨지는 애플리케이션들에 대해서만 적용되어야 할 것이다.
Add Comment
Please, Sign In to add comment