如果网页表单中有任意客户输入的网址,我想在href
内生成一个包含该网址的新HTML文档。我的问题是如何在HTML中保护该URL。
对于未知最终用户输入的以下网址,应在HTML中呈现的内容:
http://example.com/?file=some_19%affordable.txt
http://example.com/url?source=web&last="f o o"&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验证者在验证者.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()
之前对其进行html-escape。但是,这会导致每&
成为&
,而&
和<
等实体会被attr()
双重转义,并且文档中的网址为完全不准确。它看起来像这样:
<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()
然而,&#34;编码&#34;基于这两个先前的讨论(实际上,参见示例URL 1),似乎无法在肯定的情况下检测到测试:
How to find out if string has already been URL encoded? How to know if a URL is decoded/encoded?
如果我们绕过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)?
答案 0 :(得分:0)
如果您可以假设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>