it-swarm-ko.tech

PHP 사이트에서 xss 공격을 피하는 모범 사례는 무엇입니까?

마술 따옴표가 켜져 있고 레지스터 전역이 꺼져 있도록 PHP 구성되어 있습니다.

사용자 입력에서 파생 된 출력에 대해 항상 htmlentities ()를 호출하는 것이 최선입니다.

또한 때때로 xss에 사용되는 일반적인 것들에 대해 데이터베이스를 검색합니다.

<script

내가해야 할 일과 내가하려는 일이 항상 완료되었는지 어떻게 확인할 수 있습니까?.

65
Rik Heywood

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

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

  • 사용자 입력을 수정하지 않음 (입력시 HTML 이스케이프 없음, PDO 준비 명령문을 통해 DB 인식 이스케이프 만 수행)
  • 사용하는 출력 형식에 따라 출력시 이스케이프 처리 (예 : HTML 및 JSON에 다른 이스케이프 규칙이 필요함)
58
Michał Rudnicki

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

다시 말해, 데이터가 애플리케이션을 "떠나는"마지막 순간에만 벗어날 수 있습니다.

  • 아이템 목록
  • XML 파일에 쓰기, XML을 위해 이스케이프
  • DB에 쓰기, 이스케이프 (특정 DBMS 용)
  • 이메일 작성, 이메일 탈출
  • 기타

짧게 가려면 :

  1. 당신은 당신의 데이터가 어디로 가고 있는지 모른다
  2. 데이터는 실제로 여러 장소에서 종료 될 수 있으며 다른 이스케이프 메커니즘의 BUT NOT BOTH가 필요합니다.
  3. 잘못된 대상에 대해 이스케이프 된 데이터는 실제로 니스가 아닙니다. (예 : 제목이 'Tommy 's bar'로 이동하십시오.)

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

추신 : 나는 magic_quotes를 사용하지 않는 것에 대한 조언을 두 번째로 할 것입니다.

18
Jilles

XSS를 수행하는 많은 방법이 있으며 ( http://ha.ckers.org/xss.html 참조) 포착하기가 매우 어렵습니다.

나는 이것을 현재 사용중인 현재 프레임 워크에 위임합니다 (예 : 코드 점화기). 완벽하지는 않지만, 내 손으로 만든 일상보다 더 많은 것을 잡을 수 있습니다.

12
Christian Studer

이것은 좋은 질문입니다.

첫째, 데이터베이스에 저장하는 것과 같이 저장하기에 안전한 경우를 제외하고 입력시 텍스트를 이스케이프 처리하지 마십시오. 그 이유는 입력 한 내용을 유지하여 상황에 따라 다른 방식으로 장소에 표시 할 수 있기를 원하기 때문입니다. 여기에서 변경하면 나중에 프리젠 테이션이 손상 될 수 있습니다.

당신이 당신의 데이터 필터를 제시하려고 할 때 거기에해서는 안되는 것을 걸러냅니다. 예를 들어, 자바 스크립트가있을 이유가없는 경우 자바 스크립트를 검색하여 제거합니다. 가장 쉬운 방법은 strip_tags 함수를 사용하고 허용하는 html 태그 만 표시하는 것입니다.

다음으로, 당신이 가지고있는 것을 가져 와서 htmlentities 또는 htmlspecialchars를 전달하여 ASCII 문자로 존재하는 것을 변경하십시오. 상황과 나가고 싶은 것을 기반으로하십시오.

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

자세한 내용은 http://ha.ckers.org/xss.html 을 확인하십시오.

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

10
Matt Farina

사용자 입력에서 파생 된 출력에 대해서는 항상 htmlentities ()를 호출하는 것이 최선입니다.

.

See Joel's essay on Making Code Look Wrong for help with this

7
Mason

나는 PHPTAL 에 의존합니다.

Smarty 및 일반 PHP와 달리 기본적으로 모든 출력을 이스케이프합니다. htmlspecialchars() 또는 |escape 어딘가에.

XSS는 HTML 관련 공격이므로 HTML 출력이이를 방지 할 수있는 적절한 장소입니다. HTML을 허용하지 않지만 자체 위험이있는 다른 매체로 데이터를 출력해야하므로 데이터베이스에서 데이터를 사전 필터링하지 마십시오.

4
Kornel

템플릿 라이브러리 최소한 템플릿 라이브러리가해야 할 일입니다. XSS 를 방지하려면 모든 출력을 인코딩해야합니다. 이것은 주 응용 프로그램/제어 논리의 작업이 아니며 출력 방법으로 만 처리해야합니다.

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

불행히도, 대부분의 PHP 템플릿 라이브러리는 자체 템플릿 구문 만 추가하지만 출력 인코딩, 현지화, HTML 유효성 검사 또는 중요한 것에 신경 쓰지 않습니다. 다른 누군가가 PHP에 적합한 템플릿 라이브러리를 알고 있습니까?

4
user319490

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

더 읽기 : 사용자 데이터의 위생 화 : 방법과 장소

2
Niyaz

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

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

특정 범위의 값이 필요한 경우 유효한 값으로 구성된 배열을 만들고 (in_array($userData, array(...)))을 통해서만 해당 값을 허용하십시오.

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

PHP5.2 +를 사용하는 경우 filter () 를보고 전자 메일 주소를 포함한 다양한 데이터 유형을 필터링 할 수있는 해당 확장을 사용하는 것이 좋습니다. 문서는 특히 좋지는 않지만 개선되고 있습니다.

HTML을 처리해야하는 경우 PHP 입력 필터 또는 HTML Purifier . HTML Purifier는 또한 HTML이 적합한 지 확인합니다. 입력 필터가 아직 개발 중인지 잘 모르겠습니다. 둘 다 사용할 수있는 태그 세트와 허용되는 속성을 정의 할 수 있습니다.

무엇을 결정하든 항상 자신을 포함하여 사용자로부터 PHP 스크립트로 들어오는 것을 믿지 마십시오.).

2
Dave

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

2
barce

"매직 따옴표"는 입력에서 모든 것을 이스케이프하여 작동하는 최악의 XSS 결함 중 일부를 완화시키는 치료법입니다. 설계 상 잘못된 것입니다. 사용하려는 유일한 경우는 XSS와 관련하여 부주의하게 작성된 기존 PHP 응용 프로그램을 절대적으로 사용해야하는 경우)입니다 (이 경우 심각한 문제가 있습니다) 자체 응용 프로그램을 개발할 때는 "매직 인용 부호"를 비활성화하고 대신 XSS 안전 사례를 따라야합니다.

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

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

“글로벌 등록 (Global Registers)”은이를 비활성화하는 것이 좋은 생각이지만 XSS와는 완전히 다른 문제를 다룬다.

2
Alexey Feldgendler

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

2
Konrad Rudolph

이 모든 대답은 훌륭하지만 기본적으로 XSS의 해결책은 문자열 조작으로 HTML 문서 생성을 중지하는 것입니다.

필터링 입력은 항상 모든 응용 프로그램에 좋습니다.

Htmlentities () 및 friends를 사용하여 출력을 벗어나면 올바르게 사용되는 한 작동해야하지만 mysql_real_escape_string ($ var)으로 문자열을 연결하여 SQL 쿼리를 작성하는 것과 동등한 HTML입니다. 말하자면 매개 변수화 된 쿼리를 사용하는 것과 같은 접근 방식과 비교할 수 있습니다.

장기적인 해결책은 애플리케이션이 아마도 DOM과 같은 표준 인터페이스를 사용하여 페이지를 내부적으로 구성한 다음 라이브러리 (예 : libxml)를 사용하여 XHTML/HTML/etc 로의 직렬화를 처리하는 것이어야합니다. 물론, 우리는 그렇게 인기 있고 빠르지 않은 방법과는 거리가 멀지 만, 문자열 조작을 통해 HTML 문서를 작성해야하며, 이는 본질적으로 더 위험합니다.

2
Daniel Papasian
  • 사용자 입력을 신뢰하지 마십시오
  • 모든 자유 텍스트 출력 탈출
  • Magic_quotes를 사용하지 마십시오. DBMS 특정 변형이 있는지 확인하거나 PDO를 사용하십시오.
  • 악의적 인 스크립트가 세션을 가로 챌 수 없도록 HTTP 전용 쿠키 사용을 고려하십시오.
1
Rob

최소한 데이터베이스에 들어가는 모든 데이터의 유효성을 검사해야합니다. 또한 데이터베이스를 떠나는 모든 데이터의 유효성을 검사하십시오.

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

1
Abeon

PHP 응용 프로그램에서 XSS를 방지하는 가장 좋은 최신 방법은 HTML Purifier (http://htmlpurifier.org/)입니다. 그에 대한 한 가지 작은 단점은 라이브러리가 크며 가장 많이 사용된다는 것입니다 신뢰할 수없는 컨텐츠가 화면에 출력되는 모든 위치에서이를 사용할 수 있습니다 .htmlentities, htmlspecialchars, filter_input, filter_var, strip_tags 등이 훨씬 더 철저합니다.

1
Night Owl

HttpOnly를 사용하는 모든 세션 쿠키 (또는 모든 쿠키)를 만드십시오. 이 경우 대부분의 브라우저는 JavaScript에서 쿠키 값을 숨 깁니다. 사용자는 여전히 쿠키를 수동으로 복사 할 수 있지만 이는 직접 스크립트 액세스를 방지하는 데 도움이됩니다. StackOverflow는 베타 버전에서이 문제가 발생했습니다.

이것은 해결책이 아니며 벽에 또 다른 벽돌

1
basszero

가장 좋은 방법은 코드를 바인딩 할 수있는 클래스를 사용하는 것이므로 수동으로 데이터를 벗어날 염려가 없습니다.

0
Darren22

기존 사용자 입력 살균 라이브러리를 사용하여 all 사용자 입력을 정리하십시오. lot 노력을 기울이지 않으면 직접 구현해도 효과가 없습니다.

0
dbr