2010-01-16 6 views
21

플랫폼 : PHP & MySQL을 내 실험의 목적PHP & mySQL : 정확히 htmlentities를 사용할 때?

, 나는 내 자신의 웹 사이트에 XSS 주사 나 자신의 몇 가지를 시도했습니다. 양식 텍스트 입력이있는 상황을 고려하십시오. 이것은 텍스트 영역이므로 텍스트 및 모든 종류의 (영문) 문자를 입력 할 수 있습니다. 내 관찰 결과는 다음과 같습니다.

A). strip_tags와 mysql_real_escape_string 만 적용하고 데이터베이스에 데이터를 삽입하기 직전에 입력에 htmlentities를 사용하지 않으면 쿼리가을 깨고 비정상 종료로 인해 내 테이블 구조를 표시하는 오류가 발생합니다.

B). 데이터베이스에 데이터를 삽입하기 전에 strip_tags, mysql_real_escape_string 및 htmlentities를 입력 할 경우 쿼리가을 깨뜨리지 않아 성공적으로 데이터 영역의 데이터를 데이터베이스에 삽입 할 수 있습니다.

그래서 나는 htmentities를 반드시 사용해야 만하지만 정확하게 사용해야하는지 확신 할 수 없다는 것을 알고 있습니다. 위를 염두에두고 다음과 같이 알고 싶습니다.

  1. 정확히 htmlentities를 사용해야합니까? 데이터를 DB에 삽입하기 전에 사용해야하거나 DB에 데이터를 가져 와서 DB에서 데이터를 표시하려고 할 때 htmlentities를 적용해야합니까?

  2. 위의 B)에서 설명한 방법 (필자가 가장 분명하고 효율적인 해결책이라고 생각합니다)을 따르면 DB에서 데이터를 표시하려고 할 때 htmlentities를 적용해야합니까? ? 그렇다면 왜? 그렇지 않다면 왜 안 되겠습니까? 의 html_entity_decode : http://shiflett.org/blog/2005/dec/google-xss-example

  3. 그런이라는 또 하나의 PHP 함수가 : 나는에 게시물을 거친 후에 정말 나를 위해 혼란 있기 때문에 나는이를 부탁드립니다. htmlentities가 입력에 적용 되었기 때문에 DB에서 내 데이터를 표시 할 수 있습니까 (B 단계에 표시된 절차를 따른 후)? 어느 것이 좋습니다 : html_entity_decode 및 htmlentities 언제?

미리보기 페이지 : 내가 여기에 특정 상황을 좀 더 구체적인 세부 사항을 추가하는 데 도움이 될 생각

. '미리보기'페이지가 있다고 가정하십시오. 이제 텍스트 영역의 입력을 제출하면 미리보기 페이지가 입력을 받아 HTML로 표시하고 숨겨진 입력이이 입력을 수집합니다. 미리보기 버튼의 제출 버튼을 누르면 숨겨진 입력의 데이터가 새 페이지로 POST되고 해당 페이지는 숨겨진 입력에 포함 된 데이터를 DB에 삽입합니다. 양식을 처음 제출할 때 htmlentities를 적용하지 않고 (strip_tags 및 mysql_real_escape_string 만 적용) 텍스트 영역에 악의적 인 입력이있는 경우 숨겨진 입력이 손상되고 숨겨진 입력의 마지막 몇 문자가 페이지에서 " />으로 표시됩니다 이는 바람직하지 못하다. 이를 염두에두고, 미리보기 페이지에서 숨겨진 입력의 무결성을 유지하고 숨겨진 입력에서 데이터를 수집하여 손상시키지 않도록해야합니다. 어떻게해야합니까? 이 정보 게시 지연에 대해 사과하십시오.

미리 감사드립니다.

+7

팁 : 대부분의 경우 htmlentities는 사용하지 말고 htmlspecialchars를 사용해야합니다. htmlentities는 많은 문자를 변환하지만 htmlspecialchars는 변환해야하는 문자 만 변환합니다. –

+0

@Michael Madsen : 팁 주셔서 감사합니다. 이 양식은 미국 기반 키보드를 사용하여 입력 할 수있는 모든 입력을 허용합니다. 그래서 htmlentities를 사용하면 다른 웹 사이트 나 자체 시스템의 일부 이상한 문자를 수동으로 복사하여 붙여 넣으려고 할 때 htmlentities를 사용하면 더 안전하게 만들 수 있다는 생각이 들었습니다. 그래서 htmlentities를 사용하기로했습니다. 어떻게 생각해? – Devner

+1

아무런 의미가 없습니다. 네, 이상한 캐릭터가 보일 수 있습니다 ... 음, 사이트에서 이상합니다. 그러나 엔티티는 동일한 문자를 표현하는 다른 방식 일 뿐이므로 htmlentities를 사용하여 피할 수는 없습니다. 그들은 HTML에서 특별한 의미가 없기 때문에 번역 할 때 이점이 없습니다. 최종 결과는 똑같이 보일 것이며, 더 많은 바이트를 사용하게 될 것입니다. –

답변

51

다음은 일반적인 경험 법칙입니다.

마지막으로 가능한 순간에서 의 이스케이프 변수.

데이터를 깨끗한 표현으로 나타내기를 원할 때. 그런 다음 당신은 확실히 다음 싶지 않아 "오브라이언"라는 사람의 성을 저장하려는 경우 즉, :

O'Brien 
O\'Brien 

.. 음, 그의 이름이 아니다, 이유는 앰퍼샌드 나 슬래시가 없습니다. 해당 변수를 가져 와서 특정 컨텍스트 (예 : SQL 쿼리에 삽입하거나 HTML 페이지로 인쇄)로 출력하면 으로 수정할 수 있습니다.

$name = "O'Brien"; 

$sql = "SELECT * FROM people " 
    . "WHERE lastname = '" . mysql_real_escape_string($name) . "'"; 

$html = "<div>Last Name: " . htmlentities($name, ENT_QUOTES) . "</div>"; 

당신은 당신의 데이터베이스에 저장 htmlentities로 인코딩 된 문자열을 갖고 싶어하지 않습니다. CSV 또는 PDF 또는 HTML이 아닌 것을 생성하려는 경우 어떻게됩니까?

데이터를 깨끗하게 유지하고 특정 상황에 대해서만 이스케이프 처리하십시오.

+1

사용자가 임의의 html을 사용할 수 없도록 항목이 있다면, htmlent가 아닌 텍스트를 mysql에 저장하기 위해 htmlentities()를 사용해야합니까? – JasonDavis

+0

비 -HTML 텍스트를 정의 하시겠습니까? 어떤 것은 이것을 HTML로 생각할 것입니다 :'foo'. 그들은 또한이 HTML을 고려할 것입니다 :'x z'. 사용자가 HTML을 입력하는 것을 원하지 않는다면 HTML로 입력 한 내용을 그대로 취급하지 마십시오. 즉, 그대로 데이터베이스에 저장하고 화면에 표시 할 때 HTML로 처리합니다. – nickf

+0

답장을 보내 주셔서 감사합니다. 나는 원래의 게시물을 편집하여 상황에 대해 더 자세히 알려줄 수있는 정보를 포함시켰다. 친절하게 그것을 참조하고 회신을 게시하십시오. 감사. – Devner

5

기본적으로 mysql_real_escape_string은 데이터베이스 삽입 (SQL 삽입을 방지하기 위해)을 수행 한 다음 htmlentities 등을 출력 시점에 사용해야합니다.

숫자 값이 실제로 숫자 등임을 확인하기 위해 모든 사용자 입력에 온 전성 검사를 적용 할 수도 있습니다.이 시점에서 is_int, is_float 등과 같은 기능이 유용합니다. (이 기능 및 기타 유사한 것들에 대한 자세한 내용은 PHP 매뉴얼의 variable handling functions 섹션을 참조하십시오.)

+0

@middaparka 감사합니다. 당신 말이 맞아요. 하지만 CSS/XSS 공격으로부터 안전 할 수 있는지 확인하려고했습니다. Textarea는 모든 종류의 입력, 숫자, 문자 등을 허용합니다. 즉, 미국 기반 키보드를 사용하여 입력 할 수있는 모든 입력을 허용합니다. 그래서 is_int 등 다른 종류의 입력도 허용되므로 많은 도움이되지 않습니다. 나는 심지어 더 구체적인 정보를 포함하기 위해 나의 원래 게시물을 편집했다. 친절하게 회신하고 답장을 해당 사항에 게시하십시오. 감사합니다. – Devner

5
  1. 당신이 (DB 또는 $ _GET/$ _ POST에서 상관없이) HTML에 값을 인쇄 전에 만. htmlentities는 데이터베이스와 아무 관련이 없습니다.
  2. B는 잔인합니다. DB에 삽입하기 전에 mysql_real_escape_string을, HTML로 출력하기 전에 htmlentities를 사용해야한다. 를 htmlentities 태그 등 < BR /> 이론적으로

당신이 DB에 삽입하기 전에를 htmlentities을 할 수 있기 때문에 화면에 표시됩니다 한 후, 태그를 제거 할 필요가 없습니다, 그러나 당신이 경우이는 열심히 추가 데이터 처리를 할 수 있습니다 원본 텍스트가 필요할 것입니다.

3. See above 
+0

제 의견으로는 DB에 삽입하기 전에 htmlentities를 사용하지 마십시오. 원래 데이터를 그대로 보존하지 않습니다. –

+0

예, 저는 똑같은 것을 말하고 있습니다. 그러나 실제로이를 원한다면 추가적인 보안 위험을 감수하지는 않을 것이며 약간의 지연이있을 것입니다. – BarsMonster

+0

@ d03boy : 답장을 보내 주셔서 감사합니다. 나는 원래의 게시물을 편집하여 상황에 대해 더 자세히 알려줄 수있는 정보를 포함시켰다. 친절하게 그것을 참조하고 회신을 게시하십시오. 감사. – Devner

0

나는 전에이 겪었 두 가지 중요한 것들을 배웠어요 :

당신이 $ _POST/$ _ GET/$ _ REQUEST에서 값을 받고 값을 소독하기 위해 DB를 사용는 mysql_real_escape_string 기능을 추가 할 계획하는 경우를 . 그들을 htmlentities로 인코딩하지 마십시오.

htmlentities로 인코딩하여 데이터베이스에 저장하는 것이 어떨까요? 음, 여기에 목표가 있습니다. 가능한 한 데이터를 의미 있고 깨끗하게 만드는 것이 목표이며 Jeff 's Dog와 같은 htmlentities로 데이터를 인코딩하면 Jeff &이됩니다. 데이터의 컨텍스트가 의미를 잃게됩니다. . 그리고 REST 서비스를 구현하기로 결정한 후 DB에서 해당 문자열을 가져 와서 JSON에 넣으면 Jeff & "예쁜 개가 아닌 것처럼 생긴다.디코딩 할 다른 함수를 추가해야합니다.

SQL "select * from table where field = 'Jeff \'Dog" "를 사용하여"Jeff 's Dog "를 검색하려는 경우"Jeff 's Dog "가"Jeff \\\ "Dog"와 일치하지 않으므로 찾을 수 없습니다. "Jeff & "개." 나쁜?

CHAR 유형에서 영숫자 문자열을 웹 페이지로 출력하려면 htmlentities - ALWAYS!를 사용하십시오.

+0

의견을 보내 주셔서 감사합니다. 나는 너에게 동의한다. 우리 친구들이 제안한 이후로 나는 mysql_real_escape_string을 사용 해왔다. 그렇다면 우리는 htmlentities 또는 htmlspecialchars를 사용하여 영숫자 문자열 (CHAR, VARCHAR 유형)을 웹 페이지에 출력하도록 제안합니까? – Devner

관련 문제