如何安全地处理Scala中的unicode用户输入(esp XML实体)

HRJ*_*HRJ 4 xml scala xml-serialization

在我的网站上,我有一个表单,其中包含一些文本用户输入.一切都适用于"普通"字符.但是当输入unicode字符时......好吧,情节会变粗.

用户输入类似的东西

?????????
Run Code Online (Sandbox Code Playgroud)

这作为包含XML实体引用的文本进入服务器

やっぱ死にかけてる?
Run Code Online (Sandbox Code Playgroud)

现在,当我想以HTML格式向客户端提供服务时,我该怎么做?

如果我只是按原样输出字符串,则可能存在脚本攻击的可能性.如果我尝试对其进行编码,则将scala.xml.Text其转换为:

やっぱ死にかけてる?
Run Code Online (Sandbox Code Playgroud)

在Scala中是否有更好的现成解决方案可以检测实体引用而不是逃避它们,但是还是逃避XML标记?

ret*_*nym 5

将包含实体引用的字符串解析为XML片段.为了安全地输出XML中的Unicode字符,您可以偏执并根据函数使用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>
Run Code Online (Sandbox Code Playgroud)