我们已经准备好了,你呢?

2024我们与您携手共赢,为您的企业形象保驾护航!

跨站脚本(XSS,Cross Site)攻击是指攻击者可以让网站执行非法脚本。这种情况很常见。例如,在提交修改用户名的表单时,我们可以在文本框中输入一些特殊字符,如'、"等,来检查用户名是否被正确修改。

XSS是如何发生的

XSS一定是由用户输入引起的。无论是提交表单还是点击链接(参数),只要将用户输入不进行任何转义写入数据库,或者写入html或js,就会非常轻松。可能会出问题。举两个例子。

假设您需要显示新闻标题列表。对于服务端渲染来说,可能是用jade这样来实现的。

h1 娱乐速递
ul
  each val in newslist
    li= val

只需将其视为格式为 ['News1', 'News2', ...] 的数组。如果直接将内容迭代渲染为HTML,一旦新闻标题有特殊字符,例如标题中恰好包含

标签,则不会显示。

再比如,如果用户正在写博客,我们就不要考虑实时保存。现在我们只需要预览它。那么可能的代码是

var preview = document.getElementById('#preview'),
    title   = document.getElementById('#blog-title'),
    content = document.getElementById('#blog-content');
preview.innerHTML = 
  '

' + title.value + '

' + '
' + content.value + '

';

这里,用户的输入也直接显示在html上。如果恰好输入了用户的输入,则提前结束该标签,然后再次输入,直接执行js代码。

XSS的发生至少需要一个条件,那就是这些非法脚本必须在浏览器中被解析。

从发出请求到浏览器显示内容,有3个地方与XSS相关:URL、HTML。至于后端,它有两个功能。一是向数据库写入数据。这时数据也必须进行转义,但它不属于XSS的范畴。更多的是防止数据破坏SQL语句的结构;另一种是转义数据库读取数据直接生成HTML或者以JSON的形式传给前端。这些数据必须先转义才能显示在浏览器中。

HTML 特殊字符

HTML本身是一个文本文档,但它可以以多种方式出现在浏览器中,因为许多字符对于浏览器来说具有特殊的含义。例如,浏览器会对HTML中的内容做一些动画。那么转义这些特殊字符就意味着让浏览器将它们视为普通字符。例如,文本≶>将在浏览器中正常显示。

当我们在代码中生成HTML时,一定要注意变量是否被转义。像这样

el.innerHTML = title.value;

这是非常危险的。因为输入框的内容来自于用户,而用户的输入是不可靠的。不管是前端还是后端,一定有类似的方法,然后在代码中这样使用

el.innerHTML = escapeHTML(title.value);

这是转义 HTML 的简单方法。

function encodeHTML (a) {
  return String(a)
    .replace(/&/g, "&")
    .replace(//g, ">")
    .replace(/"/g, """)
    .replace(/'/g, "'");
};

那么哪些字符需要转义呢?以下是一些常见的。

“-->”

# --> #

$ --> $

& --> &

' --> '

( --> (

) --> )

; -->;

< --> <

> --> >

在方法中,我使用别名方法进行转义,因为这样更容易记住。无论是别名还是十六进制数,它们所代表的含义都是一样的。例如&和&都代表&符号。如果您想查看更具体的列表,可以参考这个网站。

浏览器收到HTML后,首先会解码所有内容。它将所有可识别的编码符号解码为文字值。例如,有

my name is: 名一

经过浏览器解码后变成

my name is: 名一

这里我想说的是,浏览器只会解码两个地方,一是标签的内容(即除了 and 标签),二是标签的属性值。属性名称不会被解码。

网址

此前,服务器不支持在URL中直接传输。例如,服务器无法识别“hello”值,因此必须在传输之前对其进行编码。

所以对于URL,我们只需要对参数的值进行编码即可。例如上面的链接,编码后为%E4%BD%A0%E5%A5%BD。

如果整个 URL 都经过编码,则该链接将不起作用。

编码方法非常简单。浏览器提供了一个全局方法,调用后可以实现转义。

重要的一点是,URL 中具有特殊含义的字符(例如:、/、?、&、=)不会被转义。如果参数恰好包含这些字符,则它们不会被转义。例如

encodeURI('http://jchen.cc/login?name=名一&from=http://other.com'); 
// -> http://jchen.cc/login?name=%E5%90%8D%E4%B8%80&from=http://other.com

from 参数的值不会被转义。这时候就需要用到另外一个方法了。

var param = encodeURIComponent('http://other.com');
encodeURI('http://jchen.cc/login?name=名一&from=') + param;
// -> http://jchen.cc/login?name=%E5%90%8D%E4%B8%80&from=http%3A%2F%2Fother.com

所以结论是,如果你想转义整个URL,就使用,如果你想转义参数的值,就使用。

当动态生成的链接地址需要分配给href或src属性时,需要对这些地址进行URL转义。当然,如果服务器支持URL中的UTF-8字符,那么不转义它们也没有问题。这就是为什么我们通常不太关注转义表单和URL参数,因为服务器性能良好。

特殊字符

JS中的转义都是通过反斜杠来完成的。分为三种,以 ' 和 " 为例。

一般情况下,可以直接通过反斜杠转义,但是有一些字符我们不知道怎么输入。很常见,比如Web Font。你可以在 CSS 中看到这样的代码。

.glyphicon-home::before {
    content: "";
}

其中的值可以用十六进制或替换。

JS转义一般用在显示用户输入的时候。例如用户输入反斜杠,需要显示,alert('\\');必须使用。

解码顺序

浏览器绘制时,首先解码HTML,然后解码URL,最后执行时解码JS。

现在考虑这三种编码同时存在的情况

click

首先是HTML解码,结果是

click

然后对URL进行解码,结果为

click

最后进行JS解码,结果为

click

单击链接后,应出现一个弹出窗口,其中显示内容。

这篇文章更多的是关于如何防止XSS的发生,而不是它的危害。核心是使用适当的方法来转义HTML和JS。

二维码
扫一扫在手机端查看

本文链接:https://by928.com/7448.html     转载请注明出处和本文链接!请遵守 《网站协议》
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。

项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13761152229

上班时间

周一到周五

公司电话

二维码
微信
线