programing

HTML/PHP에 의한 XSS 방지 방법

bestcode 2022. 9. 25. 00:29
반응형

HTML/PHP에 의한 XSS 방지 방법

HTML과 PHP만으로 XSS(크로스 사이트 스크립팅)를 방지하려면 어떻게 해야 합니까?

이 주제에 대한 다른 게시물은 많이 보았지만 XSS를 실제로 예방하는 방법에 대해 명확하고 간결하게 기술한 기사는 찾지 못했습니다.

기본적으로 사용자 입력에서 나온 브라우저로 출력하려면 이 기능을 사용해야 합니다.

이 기능을 올바르게 사용하는 방법은 다음과 같습니다.

echo htmlspecialchars($string, ENT_QUOTES, 'UTF-8');

Google Code University에서는 Web Security에 관한 매우 교육적인 비디오도 제공하고 있습니다.

가장 중요한 절차 중 하나는 사용자 입력을 처리하거나 브라우저로 다시 렌더링하기 전에 삭제하는 것입니다.PHP에는 사용할 수 있는 몇 가지 "필터" 함수가 있습니다.

XSS 공격이 보통 갖는 형식은 사용자에 대한 악의적인 의도를 포함하는 오프사이트 Javascript에 대한 링크를 삽입하는 것입니다.자세한 내용은 여기를 참조하십시오.

사이트 테스트도 필요합니다.Firefox 애드온 [XSS Me]를 추천합니다.이제 Easy XSS가 최선인 것 같습니다.

오프라인으로 전환되는 SO Documentation 베타에서 통합된 참조로 교차 게시합니다.

문제

사이트 간 스크립팅은 웹 클라이언트가 의도하지 않게 원격 코드를 실행하는 것입니다.웹 응용 프로그램이 사용자로부터 입력을 받아 웹 페이지에 직접 출력하면 웹 응용 프로그램이 XSS에 노출될 수 있습니다.입력에 HTML 또는 JavaScript가 포함되어 있는 경우 웹 클라이언트가 이 콘텐츠를 렌더링할 때 원격 코드를 실행할 수 있습니다.

예를 들어 서드파티 측에 JavaScript 파일이 포함되어 있는 경우:

// http://example.com/runme.js
document.write("I'm running");

또한 PHP 애플리케이션은 전달된 문자열을 직접 출력합니다.

<?php
echo '<div>' . $_GET['input'] . '</div>';

되지 않은 에 GET이 포함되어 있는 <script src="http://example.com/runme.js"></script>PHP를 사용하다

<div><script src="http://example.com/runme.js"></script></div>

서드파티 JavaScript가 실행되고 웹 페이지에 "I'm running"이 표시됩니다.

솔루션

일반적으로 클라이언트로부터의 입력은 신뢰하지 마십시오.모든 GET 파라미터, POST 또는 PUT 콘텐츠 및 cookie 값은 모두 사용할 수 있으므로 검증해야 합니다.이러한 값을 출력할 때는 예기치 않은 방법으로 평가되지 않도록 이스케이프를 실시합니다.

가장 단순한 애플리케이션에서도 데이터를 이동할 수 있어 모든 소스를 추적하기가 어렵습니다.따라서 항상 출력을 회피하는 이 좋습니다.

PHP는 컨텍스트에 따라 출력을 이스케이프하는 몇 가지 방법을 제공합니다.

필터 기능

PHP 필터 기능을 사용하면 php 스크립트에 대한 입력 데이터를 여러 가지 방법으로 검사하거나 검증할 수 있습니다.클라이언트 입력을 저장하거나 출력할 때 유용합니다.

HTML 인코딩

htmlspecialchars임의의 ""를 변환합니다.HTML 특수 문자"를 HTML 인코딩으로 변환합니다. , HTML 특수 문자는 표준 HTML로 처리되지 않습니다.이 방법을 사용하여 이전 예를 수정하려면:

<?php
echo '<div>' . htmlspecialchars($_GET['input']) . '</div>';
// or
echo '<div>' . filter_input(INPUT_GET, 'input', FILTER_SANITIZE_SPECIAL_CHARS) . '</div>';

출력:

<div>&lt;script src=&quot;http://example.com/runme.js&quot;&gt;&lt;/script&gt;</div>

에 것<div>태그는 브라우저에 의해 JavaScript 태그로 해석되지 않고 단순한 텍스트노드로 해석됩니다.사용자는 다음을 안전하게 볼 수 있습니다.

<script src="http://example.com/runme.js"></script>

URL 인코딩

URL을 할 때 는 "URL"을 합니다.urlencode효을 URL 。예를 들어, 사용자가 다른 GET 파라미터의 일부가 되는 데이터를 입력할 수 있는 경우:

<?php
$input = urlencode($_GET['input']);
// or
$input = filter_input(INPUT_GET, 'input', FILTER_SANITIZE_URL);
echo '<a href="http://example.com/page?input="' . $input . '">Link</a>';

악의적인 입력은 인코딩된 URL 매개 변수로 변환됩니다.

전용 외부 라이브러리 또는 OWASP AntiSamy 목록 사용

HTML 등의 코드 입력을 송신하고 싶은 경우가 있습니다.승인된 단어 목록(화이트리스트)과 승인되지 않은 단어 목록(블랙리스트)을 유지해야 합니다.

표준 목록은 OWASP AntiSamy 웹 사이트에서 다운로드할 수 있습니다.각 목록은 특정 종류의 상호작용(ebay api, tiny MCE 등)에 적합합니다.오픈 소스입니다.

HTML을 필터링하고 일반적인 케이스에 대한 XSS 공격을 방지하기 위해 존재하는 라이브러리가 있으며 AntiSamy 목록뿐만 아니라 최소한 매우 쉽게 사용할 수 있습니다.를 들어 HTML Pursure가 있습니다.

우선 순위:

  1. 템플릿 엔진(예: Twig, Smarty, Blade)을 사용하는 경우 상황에 맞는 이스케이프를 제공하는지 확인합니다.나는 트위그가 그렇게 한다는 것을 경험으로 알고 있다. {{ var|e('html_attr') }}
  2. HTML을 허용하려면 HTML Pursure를 사용하십시오.Markdown 또는 ReStructuredText만 허용한다고 생각되더라도 HTML 이러한 마크업 언어 출력을 삭제해야 합니다.
  3. 이외의 경우는, 「 」, 「 」를 사용합니다.htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)은 반드시 해야 합니다.$charset대부분의 경우,'UTF-8'원하는 문자 집합입니다.

또한 입력이 아닌 출력으로 이스케이프해야 합니다.

많은 프레임워크가 다양한 방법으로 XSS를 처리하는 데 도움이 됩니다.자신의 롤링을 하거나 XSS에 문제가 있는 경우 filter_input_array(PHP 5 >= 5.2.0, PHP 7에서 사용 가능)를 활용할 수 있습니다.일반적으로 이 스니펫을 세션 컨트롤러에 추가합니다.다른 컨트롤러가 데이터와 상호 작용하기 전에 모든 콜이 해당 스니펫을 통과하기 때문입니다.이렇게 하면 모든 사용자 입력이 1개의 중앙 위치에서 삭제됩니다.프로젝트 시작 시 또는 데이터베이스 오염 전에 이 작업을 수행할 경우 출력 시 문제가 발생하지 않습니다.쓰레기 더미, 쓰레기 더미.

/* Prevent XSS input */
$_GET   = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST  = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
/* I prefer not to use $_REQUEST...but for those who do: */
$_REQUEST = (array)$_POST + (array)$_GET + (array)$_REQUEST;

위의 HTML 태그와 스크립트태그가 모두 삭제됩니다.화이트리스트를 기반으로 안전한 태그를 허용하는 솔루션이 필요한 경우 HTML Pureator를 확인하십시오.


데이터베이스가 이미 포이즈닝되어 있거나 출력 시 XSS를 처리할 경우 OWASP는 다음 용 커스텀래퍼 기능을 작성할 것을 권장합니다.echoEveryWHERE를 사용하여 사용자 지정 값을 출력합니다.

//xss mitigation functions
function xssafe($data,$encoding='UTF-8')
{
   return htmlspecialchars($data,ENT_QUOTES | ENT_HTML401,$encoding);
}
function xecho($data)
{
   echo xssafe($data);
}
<?php
function xss_clean($data)
{
// Fix &entity\n;
$data = str_replace(array('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;gt;'), $data);
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');

// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);

// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);

// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);

// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);

do
{
    // Remove really unwanted tags
    $old_data = $data;
    $data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);

// we are done...
return $data;
}

또, XSS 관련의 HTTP 응답 헤더를 설정할 수도 있습니다.header(...)

X-XSS-보호 "1; 모드=블록"

브라우저의 XSS 보호 모드가 유효하게 되어 있는 것을 확인합니다.

Content-Security-Policy "default-src 'self";"

브라우저측 콘텐츠보안을 유효하게 합니다.Content Security Policy(CSP; 콘텐츠보안 정책)의 상세한 것에 대하여는, 다음의 문서를 참조해 주세요.http://content-security-policy.com/ 특히 인라인 및 외부 스크립트소스를 차단하도록 CSP 를 설정하면, XSS 에 도움이 됩니다.

웹 앱의 보안에 관한 유용한 HTTP 응답 헤더의 일반적인 번들에 대해서는 OWASP를 참조하십시오.https://www.owasp.org/index.php/List_of_useful_HTTP_headers 를 참조해 주세요.

사용하다htmlspecialcharsPHPHTML 에서는, 다음의 사용을 회피합니다.

element.innerHTML = “…”; element.outerHTML = “…”; document.write(…); document.writeln(…);

어디에var사용자에 의해 제어됩니다.

그리고 확실히 피하려고 노력해라eval(var)어느쪽인가를 사용할 필요가 있는 경우는, JS가 그것들을 이스케이프 해, HTML이 그것들을 이스케이프 해, 한층 더 작업을 실시할 필요가 있는 경우가 있습니다만, 기본적인 것은 이것만으로 충분합니다.

사용 중인 입력을 보호하는 최선의 방법htmlentities기능.예제:

htmlentities($target, ENT_QUOTES, 'UTF-8');

자세한 내용은 이쪽에서 확인하실 수 있습니다.

언급URL : https://stackoverflow.com/questions/1996122/how-to-prevent-xss-with-html-php

반응형