2010-01-09 4 views
4

내 웹 사이트에서 일부 텍스트 사용자 입력이 필요한 양식이 있습니다. 모든 "정상적인"문자를 잘 작동합니다. 그러나 유니 코드 문자가 입력되면 ... 음, 음모가 두꺼워집니다. 나는 HTML, 방법의 클라이언트이 다시 서비스를 제공하고자 할 때스칼라에서 유니 코드 사용자 입력을 안전하게 처리하는 방법 (XML 엔티티의 경우)

やっぱ死にかけてる 

같은

사용자 입력 뭔가 이것은

やっぱ死にかけてる? 

이제 텍스트 포함 된 XML 엔티티 심판으로 서버에 온다 나는 그것을합니까?

문자열을 그대로 출력하면 스크립트 공격의 가능성이 있습니다.

やっぱ死にかけてる? 

엔티티 심판을 감지하고 하지 그들을 탈출, 아직 XML 태그를 탈출 할 수 스칼라에서 더 나은 기성품 솔루션이 있습니까 : 나는 scala.xml.Text로 인코딩하려고하면 그것은 변환됩니다?

+1

이것은 관련성이 높고 좋은 읽을 거리입니다. http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-strings-problem –

답변

5

는 구문 분석 엔티티 참조를 XML 조각으로 포함하는 문자열입니다. 안전하게 출력 XML에서 유니 코드 문자, 당신은 편집증이 될 수 있고, 기능에 따라, 그들을 위해 XML 엔티티 참조를 사용하여 escape

scala>import xml.parsing.ConstructingParser                
import xml.parsing.ConstructingParser 

scala>import io.Source                     
import io.Source 

scala> val d = ConstructingParser.fromSource(Source.fromString("<dummy>&#12420;</dummy>"), true).documnent 
d: scala.xml.Document = <dummy>や</dummy> 

scala>val t = d(0).text                       
res0: String = や 

scala> import xml._ 
import xml._ 

scala> def escape(xmlText: String): NodeSeq = { 
    | def escapeChar(c: Char): xml.Node = 
    |  if (c > 0x7F || Character.isISOControl(c)) 
    |  xml.EntityRef("#" + Integer.toString(c, 10)) 
    |  else 
    |  xml.Text(c.toString) 
    | 
    | new xml.Group(xmlText.map(escapeChar(_))) 
    | } 
escape: (xmlText: String)scala.xml.NodeSeq 

scala> <foo>{escape(t)}</foo>        
res3: scala.xml.Elem = <foo>&#12420;</foo> 
+0

빙고! 감사. 나는 편집 성 반을 아직도 소화하고있다. 그러나 상반기는 막을 내리고있다. – HRJ

+1

XML 출력의 클라이언트가 UTF-8을 올바르게 디코딩하지 못하는 경우 (예 : 메모장으로 편집 할 수있는 경우) ASCII 출력으로 제한하고 XML 엔터티 참조를 사용하여 다른 모든 것을 이스케이프 처리 할 수 ​​있습니다 . JDOM은 이것을 매우 쉽게 만듭니다. Scala XML에서 해당 메커니즘을 찾지 못했습니다. 따라서 위의 함수가 위에 나와 있습니다. JDOM : 'format.setEscapeStrategy (새 EscapeStrategy() {! 공공 부울 shouldEscape (숯불 채널) { 반환 isAscii (CH) || defaultEscapeStrategy.shouldEscape (CH) } })' – retronym

+0

@retronym 그래. 나는 틀린 것으로 scala.xml.Text()가 그것을 처리했다고 가정했지만 분명히 그렇게하지 않았습니다. – HRJ

1

좋아,이 간단한 해킹을 시도하고있다. 댓글 환영 :

def secureEscape(text: String) = { 
    val s = new StringBuilder() 
    for (c <- text.elements) c match { 
    case '<' => s.append("&lt;") 
    case '>' => s.append("&gt;") 
    case _ => s.append(c) 
    } 
    s.toString 
} 

이 기본적으로 <>을 탈출합니다.

그런 다음이 함수를 사용하여 들어오는 양식 입력을 구문 분석 한 다음 추가 처리없이 클라이언트에 출력합니다.

0

정말로 UTF-8 인코딩과 문자 이스케이프가 브라우저에서 이루어져야합니다. 그런 다음 웹 프레임 워크에서 이스케이프 처리 및 디코딩을 처리해야합니다.

몇 가지 단계가 포함 된 까다로운 비즈니스 일 수 있습니다. 모두 올바른 UTF-8 작동을 위해 명시 적으로 구성되어야 할 수 있습니다. 특히 이전 프레임 워크와 서버, 프록시, 컨텐트 전달 네트워크 등을 캐싱 할 때

요점은 내부적으로 엔티티 참조가 아닌 예상 된 유니 코드 문자를보고 싶다는 것입니다. 마찬가지로 네이티브 유니 코드를 출력하고 시스템의 경계에서 필요한 인코딩과 인코딩을 수행해야합니다.이 작업은 원하는 웹 프레임 워크에서 자동으로 처리하는 것이 가장 바람직합니다. 당신에게 정확한 솔루션을 제공하기 위해

, 그것은 형태로 제출되는 방식이 사용중인 소프트웨어 스택 (들)을 알고하는 것이 필요 (예 : GET/POST/AJAX + JSON)

+0

그래, 점점 UTF8 용으로 구성된 전체 체인은 고통입니다. 서블릿 엔진에서 실행되는 스택이 있습니다. 그래서 이것은 기본적인 질문입니다. 양식이 POST를 통해 제출됩니다. – HRJ

0

브라우저에만 문자가 문자를 벗어나면 숫자 문자 참조 엔티티에 입력 문자를 인코딩 페이지가 게재 된 것으로 설정합니다. 많은 문제를 방지하고 UTF-8로 페이지를 제공하여 UTF-8로 태그가 올바르게 지정되었습니다. Scala, Java 및 Javascript 문자열 처리는 모두 유니 코드로되어 있으며 웹 페이지에 iso-8859-1로 제한하는 것은 모든 방향에서 이와 같은 변환 문제를 유발합니다. 기존 콘텐츠가 ASCII이면 변환이 쉽지 않습니다.

+0

완전히 이해하지 못했거나 스크립트 공격에 대해 그 부분을 놓쳤습니까? – HRJ

+0

페이지가 UTF-8 또는 일본어 문자 세트 인 경우 엔티티 이스케이프가 아닌 실제 일본어 문자로 사용자 입력을 받게됩니다. 처음 엔 엔티티를 얻지 못하면 엔티티를 출력하지 않으므로 그런 종류의 스크립트 공격에 취약하지 않습니다. –

관련 문제