PHP 사이트에서 xss 공격을 방지하기 위한 모범 사례는 무엇입니까?

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

  •  09-06-2019
  •  | 
  •  

문제

마법 따옴표가 켜져 있고 전역 등록이 꺼지도록 PHP를 구성했습니다.

나는 사용자 입력에서 파생된 출력물에 대해 항상 htmlentities()를 호출하기 위해 최선을 다합니다.

나는 또한 때때로 첨부된 xss에 사용되는 일반적인 항목을 찾기 위해 데이터베이스를 검색합니다.

<script

내가 또 무엇을 해야 하며, 내가 하려는 일이 제대로 이루어졌는지 어떻게 확인할 수 있나요? 언제나 완료.

도움이 되었습니까?

해결책

입력 이스케이프는 성공적인 XSS 방지를 위해 할 수 있는 최선의 방법이 아닙니다.또한 출력을 이스케이프해야 합니다.Smarty 템플릿 엔진을 사용하는 경우 다음을 사용할 수 있습니다. |escape:'htmlall' 모든 민감한 문자를 HTML 엔터티로 변환하는 수정자(나는 자신의 |e 위의 별칭인 수정자).

입력/출력 보안에 대한 나의 접근 방식은 다음과 같습니다.

  • 수정되지 않은 사용자 입력 저장(입력 시 HTML 이스케이프 없음, PDO 준비 문을 통해 DB 인식 이스케이프만 수행됨)
  • 사용하는 출력 형식에 따라 출력 시 이스케이프 처리합니다(예:HTML과 JSON에는 다른 이스케이프 규칙이 필요합니다.)

다른 팁

나는 입력하는 동안에는 아무것도 탈출해서는 안 되고 출력할 때만 탈출해야 한다고 생각합니다.(대부분의 경우) 해당 데이터가 어디로 가는지 알고 있다고 가정할 수 없습니다.예를 들어 나중에 보내는 이메일에 표시되는 데이터를 사용하는 양식이 있는 경우 다른 이스케이프 처리가 필요합니다(그렇지 않으면 악의적인 사용자가 이메일 헤더를 다시 작성할 수 있음).

즉, 데이터가 애플리케이션을 "떠나는" 마지막 순간에만 이스케이프할 수 있습니다.

  • 목록 항목
  • XML 파일에 쓰기, XML로 이스케이프
  • DB에 쓰기, 탈출(특정 DBMS의 경우)
  • 이메일 쓰기, 이메일 탈출

짧게 가려면:

  1. 데이터가 어디로 가는지 알 수 없습니다.
  2. 데이터는 실제로 두 곳 이상에 있을 수 있으며, 다른 이스케이프 메커니즘이 필요하지만 둘 다 필요하지는 않습니다.
  3. 잘못된 대상에 대해 이스케이프된 데이터는 실제로 좋지 않습니다.(예:"Tommy\'s bar로 가세요"라는 제목의 이메일을 받으세요.)

Esp #3은 입력 레이어에서 데이터를 이스케이프하는 경우(또는 다시 이스케이프를 해제해야 하는 경우 등) 발생합니다.

추신:나는 Magic_quotes를 사용하지 않는 것에 대한 조언을 두 번째로 할 것입니다. 그것은 순수한 악입니다!

XSS를 수행하는 방법에는 여러 가지가 있습니다(참조 http://ha.ckers.org/xss.html) 잡기가 매우 어렵습니다.

나는 개인적으로 이것을 내가 사용하고 있는 현재 프레임워크(예: Code Igniter)에 위임합니다.완벽하지는 않지만 내가 손으로 만든 루틴보다 더 많은 것을 포착할 수 있습니다.

이것은 좋은 질문입니다.

첫째, 저장을 위해 안전하게 만드는 경우(예: 데이터베이스에 저장하는 경우)를 제외하고는 입력 시 텍스트를 이스케이프 처리하지 마세요.그 이유는 입력된 내용을 유지하여 다양한 방식과 장소에서 상황에 맞게 표시할 수 있기 때문입니다.여기서 변경하면 이후 프레젠테이션이 손상될 수 있습니다.

데이터를 발표할 때 거기에 있어서는 안 되는 것을 필터링하세요.예를 들어, 자바스크립트가 있어야 할 이유가 없다면 해당 자바스크립트를 검색하여 제거하세요.이를 수행하는 쉬운 방법은 다음을 사용하는 것입니다. 스트립_태그 기능을 수행하고 허용하는 html 태그만 표시합니다.

다음으로, 가지고 있는 것을 가져와 htmlentities 또는 htmlspecialchars로 전달하여 거기에 있는 내용을 ASCII 문자로 변경합니다.상황과 전달하려는 내용을 바탕으로 이 작업을 수행하세요.

또한 Magic Quotes를 끄는 것이 좋습니다.이는 PHP 6에서 제거되었으며 사용하는 것은 나쁜 습관으로 간주됩니다.자세한 내용은 http://us3.php.net/magic_quotes

자세한 내용은 확인해 보세요. http://ha.ckers.org/xss.html

이는 완전한 답변은 아니지만 시작하는 데 도움이 되기를 바랍니다.

리크는 다음과 같이 씁니다:

나는 사용자 입력에서 파생된 출력물에 대해 항상 htmlentities()를 호출하기 위해 최선을 다합니다.

Joel의 에세이를 참조하세요. 코드를 잘못된 것처럼 보이게 만들기 이에 대한 도움을 받으려면

나는 의지한다 PHPTAL 그에 대한.

Smarty 및 일반 PHP와 달리 기본적으로 모든 출력을 이스케이프합니다.잊어버리더라도 사이트가 취약해지지 않으므로 이는 보안상 큰 승리입니다. htmlspecialchars() 또는 |escape 어딘가에.

XSS는 HTML 관련 공격이므로 HTML 출력이 이를 방지하는 데 적합합니다.HTML을 허용하지 않지만 자체적인 위험이 있는 다른 매체로 데이터를 출력해야 할 수 있으므로 데이터베이스에서 데이터를 사전 필터링하려고 시도해서는 안 됩니다.

템플릿 라이브러리. 아니면 적어도 그것이 템플릿 라이브러리가 해야 할 일입니다.XSS를 방지하려면 모두 출력을 인코딩해야 합니다.이는 기본 애플리케이션/제어 로직의 작업이 아니며 출력 방법에 의해서만 처리되어야 합니다.

코드 전체에 htmlentities()를 뿌리면 전체적인 디자인이 잘못됩니다.그리고 당신이 제안한 대로 한두 지점을 놓칠 수도 있습니다.그렇기 때문에 유일한 해결책은 엄격한 HTML 인코딩입니다. -> 언제 출력 변수는 html/xml 스트림에 기록됩니다.

불행하게도 대부분의 PHP 템플릿 라이브러리는 자체 템플릿 구문만 ​​추가할 뿐 출력 인코딩, 현지화, HTML 유효성 검사 또는 기타 중요한 사항에는 관심을 두지 않습니다.어쩌면 다른 사람이 PHP에 적합한 템플릿 라이브러리를 알고 있을까요?

대부분의 사이트에서는 모든 사용자 입력을 이스케이프하는 것으로 충분합니다.또한 세션 ID가 URL에 포함되지 않도록 하여 세션에서 도난당하지 않도록 하세요. Referer 다른 사이트로 링크하세요.또한 사용자가 링크를 제출하도록 허용하는 경우 javascript: 프로토콜 링크가 허용됩니다.이는 사용자가 링크를 클릭하자마자 스크립트를 실행합니다.

XSS 공격이 우려된다면 출력 문자열을 HTML로 인코딩하는 것이 해결책입니다.모든 단일 출력 문자를 HTML 형식으로 인코딩해야 한다는 것을 기억한다면 성공적인 XSS 공격을 실행할 방법이 없습니다.

더 읽어보세요:사용자 데이터 삭제:어떻게, 어디서 할 것인가?

개인적으로 나는 Magic_quotes를 비활성화하겠습니다.PHP5+에서는 기본적으로 비활성화되어 있으며 모든 것을 이스케이프하지 않고 PHP6에서 제거되므로 전혀 없는 것처럼 코딩하는 것이 좋습니다.

다음으로, 필터링하는 사용자 데이터 유형에 따라 다음에 수행할 작업이 결정됩니다.예를 들어 텍스트일 경우이름, 그럼 strip_tags(trim(stripslashes())); 또는 범위를 확인하려면 정규식을 사용하세요.

특정 범위의 값이 예상되는 경우 유효한 값의 배열을 만들고 해당 값만 (in_array($userData, array(...))).

숫자를 확인하는 경우 is_numeric을 사용하여 정수를 적용하거나 특정 유형으로 변환하면 사람들이 대신 문자열을 보내려고 하는 것을 방지할 수 있습니다.

PHP5.2 이상이면 다음을 살펴보십시오. 필터() 이메일 주소를 포함한 다양한 데이터 유형을 필터링할 수 있는 확장 프로그램을 사용합니다.문서화는 특별히 좋지는 않지만 개선되고 있습니다.

HTML을 처리해야 한다면 다음과 같은 것을 고려해야 합니다. PHP 입력 필터 또는 HTML 정수기.HTML Purifier는 또한 HTML의 적합성을 검증합니다.입력 필터가 아직 개발 중인지 잘 모르겠습니다.두 가지 모두 사용할 수 있는 태그 세트와 허용되는 속성을 정의할 수 있습니다.

무엇을 결정하든 항상 기억하십시오. 사용자(자신을 포함하여)로부터 PHP 스크립트로 들어오는 어떤 것도 절대 신뢰하지 마십시오.

이러한 답변은 모두 훌륭하지만 근본적으로 XSS에 대한 솔루션은 문자열 조작을 통한 HTML 문서 생성을 중단하는 것입니다.

입력 필터링은 모든 애플리케이션에 항상 좋은 아이디어입니다.

htmlentities() 및 친구들을 사용하여 출력을 이스케이프하는 것은 적절하게 사용되는 한 작동해야 하지만 이는 문자열을 mysql_real_escape_string($var)과 연결하여 SQL 쿼리를 생성하는 것과 HTML에 해당합니다. 작동해야 하지만 작업을 검증할 수 있는 일이 더 적습니다. , 말하자면 매개변수화된 쿼리를 사용하는 것과 같은 접근 방식과 비교됩니다.

장기적인 해결책은 애플리케이션이 DOM과 같은 표준 인터페이스를 사용하여 내부적으로 페이지를 구성한 다음 라이브러리(libxml과 같은)를 사용하여 XHTML/HTML/등에 대한 직렬화를 처리하는 것입니다.물론 대중화되고 충분히 빠른 속도를 내기까지는 아직 멀었지만 그 동안 문자열 작업을 통해 HTML 문서를 작성해야 하며 이는 본질적으로 더 위험합니다.

이 기능을 사용하면 가능한 많은 xss 공격을 제거하는 데 도움이 됩니다.http://www.codebelay.com/killxss.phps

"마법의 인용문"은 설계상 잘못된 입력의 모든 것을 이스케이프 처리하여 작동하는 최악의 XSS 결함 중 일부에 대한 완화적 치료법입니다.이를 사용하고 싶은 유일한 경우는 XSS와 관련하여 부주의하게 작성된 것으로 알려진 기존 PHP 애플리케이션을 반드시 사용해야 하는 경우입니다.(이 경우에는 "마법의 인용문"으로도 심각한 문제가 발생합니다.) 자체 애플리케이션을 개발할 때 "마법의 인용문"을 비활성화하고 대신 XSS 안전 관행을 따라야 합니다.

크로스 사이트 스크립팅 취약점인 XSS는 응용 프로그램이 적절한 이스케이프 없이 [X]HTML, CSS, ECMAscript 또는 기타 브라우저에서 구문 분석한 출력에 외부 소스(사용자 입력, 다른 웹 사이트에서 가져온 등)의 문자열을 포함할 때 발생합니다. 보다 작음([X]HTML), 작은따옴표 또는 큰따옴표(ECMAscript)와 같은 특수 문자는 절대 표시되지 않습니다.이에 대한 적절한 해결책은 출력 언어의 규칙에 따라 항상 문자열을 이스케이프하는 것입니다.[X]HTML의 엔터티, ECMAscript의 백슬래시 등을 사용합니다.

신뢰할 수 없고 이스케이프해야 하는 항목을 추적하기 어려울 수 있으므로 HTML과 같은 언어에서 "마크업이 있는 텍스트"가 아닌 "텍스트 문자열"인 모든 것을 항상 이스케이프하는 것이 좋습니다.일부 프로그래밍 환경에서는 호환되지 않는 여러 문자열 유형을 도입하여 작업을 더 쉽게 만듭니다."문자열"(일반 텍스트), "HTML 문자열"(HTML 마크업) 등.이렇게 하면 "문자열"에서 "HTML 문자열"로의 암시적 직접 변환이 불가능하며 문자열이 HTML 마크업이 될 수 있는 유일한 방법은 이스케이프 함수를 통해 문자열을 전달하는 것입니다.

"전역 등록"은 비활성화하는 것이 확실히 좋은 생각이지만 XSS와는 완전히 다른 문제를 다룹니다.

HttpOnly를 사용하는 모든 세션 쿠키(또는 모든 쿠키)를 만드세요.이 경우 대부분의 브라우저는 JavaScript에서 쿠키 값을 숨깁니다.사용자는 쿠키를 수동으로 복사할 수 있지만 이는 직접적인 스크립트 액세스를 방지하는 데 도움이 됩니다.StackOverflow는 베타 기간 동안 이 문제를 겪었습니다.

이것은 해결책이 아닙니다. 벽에 또 다른 벽돌이 있을 뿐입니다.

  • 사용자 입력을 신뢰하지 마세요
  • 모든 자유 텍스트 출력을 탈출하세요
  • Magic_quotes를 사용하지 마세요.DBMS 관련 변형이 있는지 확인하거나 PDO를 사용하십시오.
  • 악의적인 스크립트가 세션을 가로채는 것을 방지하려면 가능한 경우 HTTP 전용 쿠키를 사용하는 것이 좋습니다.

최소한 데이터베이스에 들어가는 모든 데이터의 유효성을 검사해야 합니다.그리고 데이터베이스에서 나가는 모든 데이터의 유효성도 검사해 보세요.

mysql_real_escape_string은 SQL 주입을 방지하는 데 좋지만 XSS는 더 까다롭습니다.가능하다면 preg_match, stip_tags 또는 htmlentities를 사용해야 합니다!

현재 PHP 애플리케이션에서 XSS를 방지하는 가장 좋은 방법은 HTML Purifier(http://htmlpurifier.org/)입니다.한 가지 사소한 단점은 라이브러리가 상당히 크고 APC와 같은 연산 코드 캐시와 함께 사용하는 것이 가장 좋다는 것입니다.신뢰할 수 없는 콘텐츠가 화면에 출력되는 모든 위치에서 이 기능을 사용할 수 있습니다.htmlentities, htmlspecialchars, filter_input, filter_var, Strip_tags 등이 훨씬 더 철저합니다.

기존 사용자 입력 삭제 라이브러리를 사용하여 정리 모두 사용자 입력.당신이 넣지 않는 한 많은 노력을 많이 한다고 스스로 구현하는 것은 결코 효과가 없을 것입니다.

가장 좋은 방법은 코드를 바인딩할 수 있는 클래스를 사용하여 데이터를 수동으로 이스케이프하는 것에 대해 걱정할 필요가 없다는 것을 알았습니다.

오경보가 발생하지 않는 사이트에서는 철저한 sql 주입/xss 주입 방지를 구현하기 어렵습니다.CMS에서 최종 사용자는 다음을 사용하고 싶어할 수 있습니다. <script> 또는 <object> 다른 사이트의 항목으로 연결되는 링크입니다.

모든 사용자에게 NoScript를 사용하여 FireFox를 설치하도록 권장합니다 ;-)

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