![](/img/trans.png)
[英]HTML5 game connecting to database safely (stopping manual JavaScript by user)
[英]What is the right way to safely and accurately insert user-provided URL data into an HTML5 document?
给定URL的Web表单中的任意客户输入,我想在href
生成包含该URL的新HTML文档。 我的问题是我应该如何在HTML中保护该URL。
对于未知最终用户输入的以下URL,应该在HTML中呈现的内容:
http://example.com/?file=some_19%affordable.txt
http://example.com/url?source=web&last="foo"&bar=<
https://www.google.com/url?source=web&sqi=2&url=https%3A%2F%2Ftwitter.com%2F%3Flang%3Den&last=%22foo%22
如果我们假设URL已经是uri编码的,我认为如果它们从URL栏复制它是合理的,那么简单地将它传递给attr()
会产生一个有效的URL和文档,它在验证器处传递Nu HTML检查器。 w3.org/nu。
为了看到它的实际效果,我们在https://jsfiddle.net/kamelkev/w8ygpcsz/2/设置了一个JS小提琴,用这些例子替换其中的URL可以显示正在发生的事情。
为了将来参考,这包含一个HTML代码段
<a>My Link</a>
这个JS:
$(document).ready(function() {
$('a').attr('href', 'http://example.com/request.html?data=>');
$('a').attr('href2', 'http://example.com/request.html?data=<');
alert($('a').get(0).outerHTML);
});
因此,对于URL 1,通过机械方式查看它是不可能判断它是否是URI编码的。 您可以根据您的人类知识猜测它不是,并且指的是名为some_19%affordable.txt
的文件。 当它通过小提琴时,会产生
<a href="http://example.com/?file=some_19%affordable.txt">My Link</a>
哪个传递HTML5验证器没问题。 它可能不是用户想要的。
第二个URL显然不是URI编码的。 问题变成了什么是放入HTML以防止HTML解析问题的正确方法。
通过小提琴运行它,Safari 10产生这个:
<a href="http://example.com/url?source=web&last="f o o"&bar=<">My Link</a>
几乎所有其他浏览器都会产生这样的:
<a href="http://example.com/url?source=web&last="f o o"&bar=<">My Link</a>
这些都没有通过验证器。 可能有三种抱怨:文字双引号(来自未转义的HTML),空格或尾随<
字符(也来自未转义的HTML)。 它只是向您展示它找到的第一个。 这显然不是有效的HTML。
尝试解决此问题的两种方法是a)在将URL提供给attr()
之前对URL进行html-escape。 然而,这导致每一个&
成为&
以及&
等实体 和<
由attr()
双重转义,文档中的URL完全不准确。 它看起来像这样:
<a href="http://example.com/url?source=web&amp;last=&quot;f+o+o&quot;&amp;bar=&lt;">My Link</a>
另一种是在传递给attr()
之前对其进行URI编码,这会产生一个正确的验证URL,实际点击到预期的目的地。 它看起来像这样:
<a href="http://example.com/url?source=web&last=%22f%20o%20o%22&bar=%3C">My Link</a>
最后,对于正确进行URI编码的第三个URL,确实会出现验证的正确HTML。
<a href="https://www.google.com/url?source=web&sqi=2&url=https%3A%2F%2Ftwitter.com%2F%3Flang%3Den&last=%22foo%22">My Link</a>
并且它会执行用户在单击时期望发生的事情。
基于此,算法应该是:
if url is encoded then
pass as-is to attr()
else
pass encodeURI(url) to attr()
然而,基于这两个先前的讨论(实际上,参见示例URL 1),“编码”测试似乎无法在肯定的情况下检测到:
如何确定字符串是否已经过URL编码? 如何知道URL是否被解码/编码?
如果我们绕过attr()
方法并强制将示例URL 2的HTML转义版本插入到文档结构中,它将如下所示:
<a href="http://example.com/url?source=web&last="f+o+o"&bar=<">My Link</a>
看似有效的HTML,但HTML5验证器失败,因为它无法使用无效的URL字符。 但是,浏览器似乎并不介意。 不幸的是,如果你的对象的任何其他操作时,浏览器会重新逃避所有的&
反正的。
如您所见,这一切都非常令人困惑。 这是我们第一次使用浏览器本身生成HTML,我们不确定我们是否正确使用它。 以前,我们使用模板对服务器端进行了操作,并且只进行了HTML-escape过滤器。
将用户提供的URL数据安全准确地插入HTML5文档(使用JavaScript)的正确方法是什么?
如果您可以假设URL是编码的或未编码的,那么您可以通过这种方式获得某些东西。 尝试解码URL,将错误视为未编码的URL,并且应该留下解码的URL。
<script>
var inputurl = 'http://example.com/?file=some_19%affordable.txt';
var myurl;
try {
myurl = decodeURI(inputurl);
}
catch(error) {
myurl = inputurl;
}
console.log(myurl);
</script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.