Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何安全地处理Scala中的unicode用户输入(esp XML实体)_Xml_Scala_Xml Serialization - Fatal编程技术网

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

如何安全地处理Scala中的unicode用户输入(esp XML实体),xml,scala,xml-serialization,Xml,Scala,Xml Serialization,在我的网站上,我有一个表单,它接受一些文本用户输入。对于“普通”字符,所有这些都可以正常工作。但是,当输入unicode字符时。。。嗯,情节越来越复杂了 用户输入类似于 やっぱ死にかけてる 这将作为包含XML实体引用的文本传入服务器 やっぱ死にかけてる? 现在,当我想用HTM

在我的网站上,我有一个表单,它接受一些文本用户输入。对于“普通”字符,所有这些都可以正常工作。但是,当输入unicode字符时。。。嗯,情节越来越复杂了

用户输入类似于

やっぱ死にかけてる
这将作为包含XML实体引用的文本传入服务器

やっぱ死にかけてる?
现在,当我想用HTML将其返回给客户机时,我该怎么做

如果我只是按原样输出字符串,可能会发生脚本攻击。如果我尝试使用
scala.xml.Text
对其进行编码,它会转换为:

やっぱ死にかけてる?

Scala中是否有更好的现成解决方案可以检测实体引用,而不是转义实体引用,但转义XML标记?

好的,我正在尝试这个简单的方法。欢迎评论:

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
}
def secureEscape(文本:字符串)={
val s=新的StringBuilder()
对于(c s.附加(“”)
大小写'>'=>s.append(“”)
case=>s.append(c)
}
s、 托斯特林
}
这将基本上转义


然后,我使用此函数解析传入的表单输入,然后将其发送出去,而无需对客户端进行进一步处理。

实际上,浏览器应该负责字符的正确UTF-8编码和转义(这似乎正在发生)。然后,您的web框架应该处理转义和解码

这可能是一项棘手的业务,涉及到几个步骤,所有这些步骤都必须明确配置以实现正确的UTF-8操作。尤其是在使用较旧的框架和服务器、缓存代理、内容交付网络等时

关键是,在内部,您希望看到预期的unicode字符,而不是实体引用。同样,您应该在系统边界处输出本机unicode和句柄以及所需的编码,最好由您选择的web框架自动处理


为了给您提供正确的解决方案,有必要了解您正在使用的软件堆栈以及表单的提交方式(即GET/POST/AJAX+JSON)

将包含实体引用的字符串作为XML片段进行分析。为了安全地在XML中输出Unicode字符,您可以根据函数
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>
scala>导入xml.parsing.ConstructingParser
导入xml.parsing.ConstructingParser
scala>导入io.Source
导入io.Source
scala>val d=ConstructingParser.fromSource(Source.fromString(や;“”),true).documnent
d:scala.xml.Document=や
scala>valt=d(0).text
res0:String=や
scala>导入xml_
导入xml_
scala>def转义(xmlText:String):NodeSeq={
|def escapeChar(c:Char):xml.Node=
|如果(c>0x7F | |字符isISOControl(c))
|xml.EntityRef(“#”+Integer.toString(c,10))
|否则
|Text(c.toString)
| 
|新的xml.Group(xmlText.map(escapeChar())))
| }
转义:(xmlText:String)scala.xml.NodeSeq
scala>{escape(t)}
res3:scala.xml.Elem=や;

浏览器仅在输入字符位于页面所用字符集之外时,才将输入字符编码为数字字符引用实体。省去了很多麻烦,并使用UTF-8(正确标记为UTF-8)为页面提供服务。Scala、Java和Javascript字符串处理均采用Unicode,并且仅限于iso-8859-1网页在各个方向都会引发类似的转换问题。如果您现有的内容是ASCII,那么转换应该是无痛的。

这既相关又是一本好书:是的,为UTF8配置整个链是一件痛苦的事。我有一个在servlet引擎上运行的home brewn堆栈。因此,这是一个回归基础的问题。表单I这是通过POST.Bingo提交的!谢谢。我仍在消化偏执的那一半。但前一半是正确的。如果您不信任XML输出的客户端正确解码UTF-8(例如,如果它可能被记事本编辑!),您可以将自己限制为ASCII输出,并使用XML实体引用转义其他内容。JDOM使这非常容易。我在Scala XML中没有找到相应的机制,因此上面的手动函数escape.JDOM:
format.setEscapeStategy(new EscapeScapeStategy(){public boolean shouldEscape(char ch){return!isAscii(ch)| | defaultEscapeStrategy.shouldEscape(ch);}}
@retronym-ah-ok。我错误地认为scala.xml.Text()是我没有完全理解你,或者你错过了关于脚本攻击的部分吗?如果你的页面是UTF-8或日语字符集,你将收到用户输入的实际日语字符,而不是实体转义。如果你没有首先得到实体,你将不会输出因此不易受到这种脚本攻击。