gpt4 book ai didi

jquery - 对带有 URL 的数据属性进行 EncodeFor

转载 作者:行者123 更新时间:2023-12-01 04:36:26 25 4
gpt4 key购买 nike

我正在尝试将 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 输出

注意:您应该始终对 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&#x3f;Id&#x3d;&amp;a&#x3d;b&#x3f;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)时,对输出进行编码是不够的。

<小时/>

将查询字符串编码为 URL

<!--- 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%22data-href 属性的纯值。 URL 的范围转储将为我们提供键值对:

Id: a&b="><script>alert("my evil script");</script><div foo="

这一次,浏览器的查询字符串解析器可以区分字符的字面含义和技术用途。但是这里的 HTML 上下文又如何呢?好吧,encodeForUrl() 完成的百分比编码不会与 HTML 的保留字符冲突,因为 % 在 HTML 中没有技术目的,也不会破坏任何内容。

结论

理论上我们已经完成了。由于两种编码没有重叠,因此无需对 URL 编码值进行 HTML 编码。

<小时/>

将查询字符串编码为 URL - AND - 以 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&#x3f;Id&#x3d;a&#x25;26b&#x25;3D&#x25;22&#x25;3E&#x25;3Cscript&#x25;3Ealert&#x25;28&#x25;22my&#x2b;evil&#x2b;script&#x25;22&#x25;29&#x25;3B&#x25;3C&#x25;2Fscript&#x25;3E&#x25;3Cdiv&#x2b;foo&#x25;3D&#x25;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%22data-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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com