2013-10-18 1 views
4

는 다음과 같은 고전적인 문제의 경우를 생각해 $_GET['f']의 값이 해당 파일의 ../etc/shadow 내용이 공격자에게 공개 될 경우디렉터리 트래버스 공격을 막기 위해 디렉토리 이름이 적절합니까?

<?php 
$filename = "/tmp/".$_GET['f']; 
readfile($filename); 

이 코드는 예를 들어, directory traversal attack에 취약합니다.

이러한 유형의 공격을 막는 데는 잘 알려진 방법이 있습니다. 나는 그것을하는 법을 묻지 않고있다. 질문 : 은 다음과 같은 공격을 막기 위해 방탄 방법 인 dirname을 사용하고 있습니까? 그것이 있어야처럼

<?php 
if (dirname($_GET['f']) != '.') die ('Attack prevented'); 

그것은 소리 dirname 가입일 : (입력 경로에 슬래시가없는 경우에만 및 온라인 설명서가 덜 엄격한 보장하지만 the source을 만드는 경우

  • 반환 . 명시 적 임)
  • 은 이진 안전합니다 (따라서 포함 된 널 (null)로 속일 수 없음)

그래서 지금까지 내가 말할 수있는, 공격 가능한 유일한 수단은 인코딩 $_GET['f']에 데이터를 전달하는 것 같은 캐릭터 / 또는 \ (의 Windows를 잊지 말자) 중 하나는 하지이 포함되어 있습니까 뭔가 인코딩 것을 대응하는 문자 의 ASCII 값은이 인코딩이 기본 C 런타임 라이브러리의 fopen 기능에 의해 투명하게 지원되어야합니다.

no-ASCII 값 제한은 모든 1 바이트 인코딩, UTF-8 및 UTF-16의 두 가지 맛을 배제합니다. 또한 C 런타임의 사양이 플랫폼 독립적 인 경우 공격은 이름을 나타 내기 위해 "취약한"인코딩을 사용하는 일부 파일 시스템에만 적용될 수 있습니다. 그러한 파일 시스템은 내 지식으로는 존재하지 않는다. 그것은 누군가가 그것을 창조하는 것이 거의 불가능합니다. 마지막으로 PHP는 존재한다고하더라도 가상의 이국적인 시스템에서 호스팅되지 않습니다.

결론적으로이 검사는 100 % 안전하다고 생각됩니다. 내가 놓친 것이 있습니까?

+0

나는 (http://stackoverflow.com/a/4205278/453348) 또한 그 질문에 – tttony

+0

@tttony에서'MainMa' 답변을 확인할 수 있습니다이 [답]의 코드를 사용했습니다 : 감사합니다,하지만 위에서 말했듯이 공격을 막는 방법을 알고 있습니다. 문제는 자신감있게 * 이렇게 할 수 있습니까? – Jon

+0

내 테스트에 따르면, 당신의 방법은 작동하지만 간단하게 보입니다. – tttony

답변

1

저는 100 % 안전하다고 주장 할 수 있을지 확신하지 못합니다. 즉, 이것은 안전하지 않은 명백한 사례를 생각할 수 없으며 그에 대한 많은 순열을 시도했습니다. 즉 $ _GET [ 'f']가 비어 있지 않다는 검사를 추가하고 싶을 것입니다. 위의 코드를 사용하여 f 값이없는 페이지를 방문하면 "Attack prevent"메시지가 나타났습니다. 이는 아마도 원하는 효과가 아닙니다.

<?php 
if (!empty($_GET['f']) && dirname($_GET['f']) != '.') die ('Attack prevented'); 
+0

예를 들어 설명 할 최소한의 코드가 들어 있습니다. 어떤 종류의 순열을 시도 했습니까? – Jon

+0

필자는 1 레벨 위로 파일을 만들었고 그 파일을 참조 할 수 있다고 생각할 수있는 모든 방법으로 입력했습니다 (예 :? f = ../test.txt? f = .. \ test.txt? f = .. % 2Ftest). txt? f =/test.txt? f = % 2Ftest.txt? f = asdf) 목록이 계속 켜져 있습니다.스크립트에 실제로 로컬 인 파일 경로 만 오류를 발생시키지 않았습니다. 다시 말하지만, 나는 "100 % 안전"을 사용하는 것을 싫어하지만 과거를 지나치게 분명하게 볼 수는 없습니다. –

관련 문제