.html() 方法是否自动编码 HTML?
Does .html() method automatically encode HTML?
上下文
我有一个网站,用户可以在其中撰写自己的文章。我使用 contenteditable div 允许用户标记他们的 HTML(粗体、斜体等),我想确保我防止 XSS 攻击。为此,我在将数据输出到页面时使用 htmlspecialchars()
。我想单独留下用户的输入数据并在输出时对其进行编码。但是,我使用.html()
方法获取contenteditablediv中的HTML内容,貌似用户插入的标签是通过.html()
方法自动编码的,或者令人满意 div.
contenteditable div 的结构是
<div class="article" contenteditable="true"></div>
例如,如果用户尝试通过插入 <script>alert('hi')</script>
在 contenteditable div 上执行 XSS,如下所示:
<div class="article" contenteditable="true">
<script>alert('hi')</script>
</div>
当我将数据提交到数据库时(使用 var article = $(".article").html();
),我在数据库中看到的数据不是 <script>alert('hi')</script>
,而是 <script>alert('hi')</script>
,尽管事实上我没有自己编码任何东西。然后,我必须避免在输出文章内容时使用 htmlspecialchars()
,以便 div 将字符串编码回其原始形式,而不是保持编码状态。
问题
.html()
方法是否自动编码 HTML,如果是,如何防止此功能(如果建议这样做)?
好的Carson D,下面的代码让我在旅途中受益匪浅
这是来源 link。如前所述,他们可能已将其更新为现代方法。如果您只需要一个独立的功能,那么从 link 中的代码中删除 module.exports =
位,如下所示:
https://locutus.io/php/strings/htmlspecialchars_decode/
link 可能会在 SO 的未来历史中变得陈旧,所以这里是代码形式的代码,所有学分都已到期。这是我至少从 2013/14 开始使用的代码,因此它可能确实与 link 中的代码不匹配,但我相信作者是相同的。
function htmlspecialchars_decode (string, quoteStyle) { // eslint-disable-line camelcase
// discuss at: https://locutus.io/php/htmlspecialchars_decode/
// original by: Mirek Slugen
// improved by: Kevin van Zonneveld (https://kvz.io)
// bugfixed by: Mateusz "loonquawl" Zalega
// bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
// bugfixed by: Brett Zamir (https://brett-zamir.me)
// bugfixed by: Brett Zamir (https://brett-zamir.me)
// input by: ReverseSyntax
// input by: Slawomir Kaniecki
// input by: Scott Cariss
// input by: Francois
// input by: Ratheous
// input by: Mailfaker (https://www.weedem.fr/)
// revised by: Kevin van Zonneveld (https://kvz.io)
// reimplemented by: Brett Zamir (https://brett-zamir.me)
// example 1: htmlspecialchars_decode("<p>this -> "</p>", 'ENT_NOQUOTES')
// returns 1: '<p>this -> "</p>'
// example 2: htmlspecialchars_decode("&quot;")
// returns 2: '"'
var optTemp = 0
var i = 0
var noquotes = false
if (typeof quoteStyle === 'undefined') {
quoteStyle = 2
}
string = string.toString()
.replace(/</g, '<')
.replace(/>/g, '>')
var OPTS = {
'ENT_NOQUOTES': 0,
'ENT_HTML_QUOTE_SINGLE': 1,
'ENT_HTML_QUOTE_DOUBLE': 2,
'ENT_COMPAT': 2,
'ENT_QUOTES': 3,
'ENT_IGNORE': 4
}
if (quoteStyle === 0) {
noquotes = true
}
if (typeof quoteStyle !== 'number') {
// Allow for a single string or an array of string flags
quoteStyle = [].concat(quoteStyle)
for (i = 0; i < quoteStyle.length; i++) {
// Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
if (OPTS[quoteStyle[i]] === 0) {
noquotes = true
} else if (OPTS[quoteStyle[i]]) {
optTemp = optTemp | OPTS[quoteStyle[i]]
}
}
quoteStyle = optTemp
}
if (quoteStyle & OPTS.ENT_HTML_QUOTE_SINGLE) {
// PHP doesn't currently escape if more than one 0, but it should:
string = string.replace(/�*39;/g, "'")
// This would also be useful here, but not a part of PHP:
// string = string.replace(/'|�*27;/g, "'");
}
if (!noquotes) {
string = string.replace(/"/g, '"')
}
// Put this in last place to avoid escape being double-decoded
string = string.replace(/&/g, '&')
return string
}
上下文
我有一个网站,用户可以在其中撰写自己的文章。我使用 contenteditable div 允许用户标记他们的 HTML(粗体、斜体等),我想确保我防止 XSS 攻击。为此,我在将数据输出到页面时使用 htmlspecialchars()
。我想单独留下用户的输入数据并在输出时对其进行编码。但是,我使用.html()
方法获取contenteditablediv中的HTML内容,貌似用户插入的标签是通过.html()
方法自动编码的,或者令人满意 div.
contenteditable div 的结构是
<div class="article" contenteditable="true"></div>
例如,如果用户尝试通过插入 <script>alert('hi')</script>
在 contenteditable div 上执行 XSS,如下所示:
<div class="article" contenteditable="true">
<script>alert('hi')</script>
</div>
当我将数据提交到数据库时(使用 var article = $(".article").html();
),我在数据库中看到的数据不是 <script>alert('hi')</script>
,而是 <script>alert('hi')</script>
,尽管事实上我没有自己编码任何东西。然后,我必须避免在输出文章内容时使用 htmlspecialchars()
,以便 div 将字符串编码回其原始形式,而不是保持编码状态。
问题
.html()
方法是否自动编码 HTML,如果是,如何防止此功能(如果建议这样做)?
好的Carson D,下面的代码让我在旅途中受益匪浅
这是来源 link。如前所述,他们可能已将其更新为现代方法。如果您只需要一个独立的功能,那么从 link 中的代码中删除 module.exports =
位,如下所示:
https://locutus.io/php/strings/htmlspecialchars_decode/
link 可能会在 SO 的未来历史中变得陈旧,所以这里是代码形式的代码,所有学分都已到期。这是我至少从 2013/14 开始使用的代码,因此它可能确实与 link 中的代码不匹配,但我相信作者是相同的。
function htmlspecialchars_decode (string, quoteStyle) { // eslint-disable-line camelcase
// discuss at: https://locutus.io/php/htmlspecialchars_decode/
// original by: Mirek Slugen
// improved by: Kevin van Zonneveld (https://kvz.io)
// bugfixed by: Mateusz "loonquawl" Zalega
// bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
// bugfixed by: Brett Zamir (https://brett-zamir.me)
// bugfixed by: Brett Zamir (https://brett-zamir.me)
// input by: ReverseSyntax
// input by: Slawomir Kaniecki
// input by: Scott Cariss
// input by: Francois
// input by: Ratheous
// input by: Mailfaker (https://www.weedem.fr/)
// revised by: Kevin van Zonneveld (https://kvz.io)
// reimplemented by: Brett Zamir (https://brett-zamir.me)
// example 1: htmlspecialchars_decode("<p>this -> "</p>", 'ENT_NOQUOTES')
// returns 1: '<p>this -> "</p>'
// example 2: htmlspecialchars_decode("&quot;")
// returns 2: '"'
var optTemp = 0
var i = 0
var noquotes = false
if (typeof quoteStyle === 'undefined') {
quoteStyle = 2
}
string = string.toString()
.replace(/</g, '<')
.replace(/>/g, '>')
var OPTS = {
'ENT_NOQUOTES': 0,
'ENT_HTML_QUOTE_SINGLE': 1,
'ENT_HTML_QUOTE_DOUBLE': 2,
'ENT_COMPAT': 2,
'ENT_QUOTES': 3,
'ENT_IGNORE': 4
}
if (quoteStyle === 0) {
noquotes = true
}
if (typeof quoteStyle !== 'number') {
// Allow for a single string or an array of string flags
quoteStyle = [].concat(quoteStyle)
for (i = 0; i < quoteStyle.length; i++) {
// Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
if (OPTS[quoteStyle[i]] === 0) {
noquotes = true
} else if (OPTS[quoteStyle[i]]) {
optTemp = optTemp | OPTS[quoteStyle[i]]
}
}
quoteStyle = optTemp
}
if (quoteStyle & OPTS.ENT_HTML_QUOTE_SINGLE) {
// PHP doesn't currently escape if more than one 0, but it should:
string = string.replace(/�*39;/g, "'")
// This would also be useful here, but not a part of PHP:
// string = string.replace(/'|�*27;/g, "'");
}
if (!noquotes) {
string = string.replace(/"/g, '"')
}
// Put this in last place to avoid escape being double-decoded
string = string.replace(/&/g, '&')
return string
}