- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将 URL 放入 data-
属性中。特别是
<tr data-href="/page.cfm?Id=#EncodeForHTMLAttribute(ID)#">
...
或者也许应该是
<tr data-href="/page.cfm?Id=#EncodeForURL(ID)#">
...
请注意,ID 可以包含特殊字符
编辑:
很久以后我会去
$("tr").click(function() { window.location = $(this).data("href"); });
最佳答案
让我们分析一些场景:
<!--- our "tricky" ID --->
<cfset ID = '"><script>alert("my evil script");</script><div foo="'>
<!--- we are closing the data-href attribute, injecting our JS and start a new tag to complete the remaining tag --->
<cfoutput>
<div data-href="page.cfm?Id=#ID#"></div>
<!--- [data-href] is printed as: page.cfm?Id="><script>alert("my evil script");</script><div foo=" --->
</cfoutput>
出现一个警告对话框,其中显示“我的邪恶脚本”。
永远不要让用户输入未编码!(您已经知道了。)
<小时/>注意:您应该始终对 HTML 属性的完整值进行编码,而不仅仅是其部分值。
<!--- our "tricky" ID --->
<cfset ID = "&a=b?c">
<!--- we are having some reserved characters here that will confuse the browser's query string parser --->
<cfoutput>
<div data-href="#encodeForHtmlAttribute("page.cfm?Id=#ID#")#"></div>
<!--- [data-href] is printed as: page.cfm?Id=&a=b?c --->
<script>
var attr = document.getElementsByTagName('div')[0].getAttribute('data-href');
console.log(attr); <!--- page.cfm?Id=&a=b?c --->
<cfif structIsEmpty(URL)> <!--- test related: to prevent infinite redirection --->
location.href = attr;
</cfif>
</script>
</cfoutput>
<cfdump var="#URL#">
当请求page.cfm
时,我们将被重定向到page.cfm?Id=&a=b?c
,即data-的纯值href
属性。但是,URL
的范围转储将为我们提供键值对:
Id: [empty string]
a: b?c
这是可以预料的,因为浏览器的查询字符串解析器无法区分字符的字面含义和技术目的。 I recently answered this here.
当具有多个上下文(此处:HTML 和 URL/QueryString)时,对输出进行编码是不够的。
<小时/><!--- our "tricky" ID --->
<cfset ID = 'a&b="><script>alert("my evil script");</script><div foo="'>
<!--- we are mixing in both contexts now --->
<cfoutput>
<div data-href="page.cfm?Id=#encodeForUrl(ID)#"></div>
<!--- [data-href] is printed as: page.cfm?Id=a%26b%3D%22%3E%3Cscript%3Ealert%28%22my+evil+script%22%29%3B%3C%2Fscript%3E%3Cdiv+foo%3D%22 --->
<script>
var attr = document.getElementsByTagName('div')[0].getAttribute('data-href');
console.log(attr); <!--- page.cfm?Id=a%26b%3D%22%3E%3Cscript%3Ealert%28%22my+evil+script%22%29%3B%3C%2Fscript%3E%3Cdiv+foo%3D%22 --->
<cfif structIsEmpty(URL)> <!--- test related: to prevent infinite redirection --->
location.href = attr;
</cfif>
</script>
</cfoutput>
<cfdump var="#URL#">
当请求page.cfm
时,我们将被重定向到page.cfm?Id=a%26b%3D%22%3E%3Cscript%3Ealert%28%22my+evil+ script%22%29%3B%3C%2Fscript%3E%3Cdiv+foo%3D%22
,data-href
属性的纯值。 URL
的范围转储将为我们提供键值对:
Id: a&b="><script>alert("my evil script");</script><div foo="
这一次,浏览器的查询字符串解析器可以区分字符的字面含义和技术用途。但是这里的 HTML 上下文又如何呢?好吧,encodeForUrl()
完成的百分比编码不会与 HTML 的保留字符冲突,因为 %
在 HTML 中没有技术目的,也不会破坏任何内容。
理论上我们已经完成了。由于两种编码没有重叠,因此无需对 URL 编码值进行 HTML 编码。
<小时/><!--- our "tricky" ID --->
<cfset ID = 'a&b="><script>alert("my evil script");</script><div foo="'>
<!--- we are mixing in both contexts again --->
<cfoutput>
<div data-href="#encodeForHtmlAttribute("page.cfm?Id=#encodeForUrl(ID)#")#"></div>
<!--- [data-href] is printed as: page.cfm?Id=a%26b%3D%22%3E%3Cscript%3Ealert%28%22my+evil+script%22%29%3B%3C%2Fscript%3E%3Cdiv+foo%3D%22 --->
<script>
var attr = document.getElementsByTagName('div')[0].getAttribute('data-href');
console.log(attr); <!--- page.cfm?Id=a%26b%3D%22%3E%3Cscript%3Ealert%28%22my+evil+script%22%29%3B%3C%2Fscript%3E%3Cdiv+foo%3D%22 --->
<cfif structIsEmpty(URL)> <!--- test related: to prevent infinite redirection --->
location.href = attr;
</cfif>
</script>
</cfoutput>
<cfdump var="#URL#">
当请求page.cfm
时,我们将被重定向到page.cfm?Id=a%26b%3D%22%3E%3Cscript%3Ealert%28%22my+evil+ script%22%29%3B%3C%2Fscript%3E%3Cdiv+foo%3D%22
,data-href
属性的纯值。 URL
的范围转储将为我们提供键值对:
Id: a&b="><script>alert("my evil script");</script><div foo="
似乎什么都没有改变,对吧?不完全是。这就是我们的 data-href
现在在最终 HTML 输出中的样子:page.cfm?Id=a%26b%3D%22%3E%3Cscript%3Ealert%28%22my+evil%28%22my+evil% #x2b;脚本%22%29%3B%3C%2Fscript%3E%3Cdiv+foo%3D%22
正如您所看到的,百分比编码现在还针对 HTML 进行了编码(%
已编码为其十六进制表示形式 %
)。
该值现在对于两种上下文都是安全的。
<小时/>还有更多的编码可以混合(想想encodeForJavaScript()
),但你明白了。它总是关于值中的哪些字符需要编码,以免因其技术目的而被误解。这最终可能会像 3 到 4 个嵌套编码一样疯狂。但话又说回来:通常这些编码不会相互冲突,因此不一定需要针对所有上下文对它们进行编码。
关于jquery - 对带有 URL 的数据属性进行 EncodeFor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52768056/
应该使用哪个EncodeForlocation()? 如果我想通过位置推送一些数据,它应该是什么样的? location("obtainBDK.cfm?message=#ErrorMessage#",
我正在尝试将 URL 放入 data- 属性中。特别是 ... 或者也许应该是 ... 请注意,ID 可以包含特殊字符 编辑: 很久以后我会去 $("tr").click(functi
我是一名优秀的程序员,十分优秀!