前端必备的 web 安全知识手记

前言

安全这种东西就是不发生则已,一发生则惊人。作为前端,平时对这方面的知识没啥研究,最近了解了下,特此沉淀。文章内容包括以下几个典型的 web 安全知识点:XSS、CSRF、点击劫持、SQL 注入和上传问题等(下文以小王代指攻击者),话不多说,我们直接开车🚗(附带的例子浅显易懂哦😯)。

XSS(Cross-site scripting)

XSS 中文叫做跨站脚本攻击。
一句话解释:小王在网页中注入恶意代码,当用户访问页面时,代码会自动运行。
具体点说:凡是在页面中可输入的地方(如地址栏、搜索框和评论区等等)都有隐藏的风险,小王可以在这些地方输入一些特殊的代码(形如 <script>alert(1)</script>),于是乎本来只是单纯的文本变成了可执行的代码,从而造成了攻击。你可能会觉得 alert(1) 能有多大点事,但把它换成别的威力就不一样了,它可以重定向到一个由小王控制的页面、冒充用户发送请求、窃取用户信息发送到小王的服务器上等等。当然了,这还不够具体,例子才是最直白的👇。

举个栗子

因为 XSS 攻击有反射型、存储型和 DOM 型三种类型,所以我们每种都举个简单的栗子🌰:

反射型

反射型 XSS 主要有以下两个步骤:

  1. 假设我们访问一个 www.a.com/?name=hh 页面,后端会把其中的 name 参数取出来并拼接到 html 中(形如 <p>你好啊,hh</p>)返回给用户。
  2. 这时如果我们访问 www.a.com/?name=hh<script>alert(1)</script> 页面,此时后端会返回形如 <p>你好啊,hh<script>alert(1)</script></p> 这样的一个 html,其中的 script 脚本就会在我们的浏览器上加载执行,从而造成攻击。

你可能会觉得这种 url 看起来就有嫌疑,我们一般不访问,但如果把这个 url 转成一个短网址(所谓短网址就是把 url 转成一个 看起来简约又正常的链接),并在网上散播(通常伴随一些美女图片、外挂和金钱💰等一些具有诱惑力的内容),从而骗取用户点击这个 url,造成攻击。所以日常生活中不要乱扫二维码、乱点链接。

当然了,拼接的形式多种多样:

拼接前拼接字符串拼接后
<div>#{msg}</div><script>alert(1)</script><div><script>alert(1)</script></div>
<img src="#{image}" />1" onerror="alert(1)<img src="1" onerror="alert(1)" />
var data = "#{data}"hello";alert(1);"var data = "hello";alert(1);""
存储型

这种类型一般出现在评论区、论坛、留言等类似的地方,基本流程是小王提交了一个恶意评论(就是包含一些恶意代码,和上面类似,形如这样的评论 <img src="1" onerror="alert(1)" />),只不过该评论被保存到了数据库中,而评论对大家又都是可见的,所以任何用户访问该页面时,恶意代码就会从数据库中取出,拼接在 html 中返回给用户,页面加载评论的同时也执行了其中的恶意代码。与反射型相比,存储型的辐射范围更加广泛,处理起来也较为麻烦,有时还需要查好多库删好几张表。

DOM 型

典型的例子就是你连接了一个公共 wifi,浏览页面的时候在底部或者四周有时会有一些小广告的出现,因为这种网络劫持会动态修改页面的内容,比如在 html 中追加一些广告或暗链(暗链就是偷偷加入几个 a 标签,一般可用来增加搜索排名),要注意的是这种攻击是不涉及到服务器的,它的核心是动态修改 dom。

小小总结

总的来说就是页面可输入或拼接显示的地方就可能会有潜在的风险。我们演示个小的 demo,虽然实际上不是这样的😂,但意思到了: 当我们第一次输入 <script>alert(1)</script> 的时候,alert 不生效是因为 H5 中规定用 innerHTML 插入的 script 将不被执行,但是我们可以写别的,比如 <img src='x' onerror="alert(1)">,此时 alert 就被执行了,这个在 MDN 上有明确的说明,这里给大家截图看一下👀: 作为前端平时要注意 innerHTML 等一些有字符串拼接并展示的地方。

防御措施

转义和过滤:

一般来可以使用编码或转义的方式来防御 XSS 攻击,就像下面这样:

function escape(str) {if (!str) return ''str = str.replace(/&/g, '&amp;')str = str.replace(/</g, '&lt;')str = str.replace(/>/g, '&gt;')str = str.replace(/"/g, '&quot;')str = str.replace(/'/g, '&#39;')return str
}

对于富文本内容,因为其需要保留 html,所以不好直接使用转义的方法,通常使用白名单过滤(就是允许特定的 html 标签和属性),以抵御 XSS 攻击。当然了更不要相信用户的任何输入,对用户的输入进行特殊字符(如尖括号)的检查也是有必要的。

CSP(Content Security Policy)

这个其实就是设置个响应头信息(Content-Security-Policy),告诉浏览器哪些资源是可加载执行的(实质就是白名单制度),为对应的内容指定相应的策略。具体设置大家可以查阅 MDN,这里截个 github 的图作为示例: 或者加个 meta 标签:

<meta http-equiv="Content-Security-Policy" content="img-src 'self';">
其他
  • HttpOnly:禁止 js 读取 cookie
  • 限制输入内容长度:提高门槛
  • 敏感操作使用验证码

CSRF(Cross-site request forgery)

CSRF 中文叫做跨站请求伪造。 一句话解释:小王盗用你的身份,以你的名义发送恶意请求(发邮件、转账之类的)。

举个栗子

这个没有分类,所以我们直接上栗子🌰:

  1. 用户登录了 www.a.com,登录态被保存在 cookie 中(这是前提)。
  2. 假设 www.a.com 页面有个转账的功能,形如:https://www.a.com/index.php?money=100&to=xx,这个请求能够把 100 块转到 xx 同学的账户上。
  3. 小王引诱用户打开了 www.b.com 页面,而这个页面有一个形如 <img src="https://www.a.com/index.php?money=100&to=wo"> 这样的标签,于是浏览器就会自动发起一个转账请求,并且这个请求会携带上 a 网站的 cookie(即便这个标签根本不在 www.a.com 内),所以能请求成功。
  4. 用户并不晓得,这很可怕😱。所以有些网站会要求已登录的用户在一些关键步骤时再次输入密码就有一定道理了。

防御措施

CSRF 攻击通常有以下两个特点:

  • 通常发生在第三方网站。
  • 小王并不能获取到 cookie,他只是借用请求,有点借刀杀人的意思。

针对以上两点我们可以有以下几种预防措施:

referer

因为请求头中的 referer 记录了请求的来源地址,referer 会指向 b 网站,所以我们可以对 referer 进行检测,以此来禁止来自第三方网站的请求。 但每个浏览器对于 referer 的具体实现可能有差别,也不能保证浏览器自身没有安全漏洞。在有些情况下,攻击者甚至可以隐藏、修改自己请求的 referer。另外 origin 也是一样的道理(origin 只包含了域名信息,不包括具体的 url 路径)

token

由于 CSRF 是利用了浏览器自动携带 cookie 的特性,所以我们可以多加一个校验的字段(不通过 cookie 传递),简单点说就是:

  1. 登录的时候服务端会返回一个 token 值给前端。
  2. 前端在发送请求的时候再把这个 token 当作请求数据传递或者放在请求头里。
  3. 后端会对这个 token 值进行校验。而由 CSRF 的请求是没有携带 token 的,所以不会成功。

至于 token 是啥,这里简单说明以下,其实它是个字符串,你可以当做个临时 id,一般由 userId、随机数、时间戳通过散列算法得到(形如:let token = md5('userId' + 'time' + 'Math.random() + '...'),其实就是调用一个函数)。

加验证码

加验证码的本质和 token 是一样的,这两种类型的原理都是在 cookie 之外的某个地方多增加一个字段供后端校验,这里增加的字段就是验证码。这样一来第三方只能携带上 cookie 但是带不上这个验证码字段,也就预防了 csrf 攻击。

SameSite

可以通过设置 SameSite 的值来禁止第三方网站携带 cookie。SameSite 有三个值可以设置:Strict、Lax、None。具体作用如下:

  • Strict:完全禁止第三方 cookie,跨站点时,任何情况下都不会发送 cookie。
  • Lax:大多数情况也是不发送第三方 cookie,但是导航到目标网址的 get 请求除外。Chrome 计划将 Lax 变为默认设置。
  • None:可以显式关闭 SameSite 属性,不过必须同时设置 Secure 属性,因为 cookie 只能通过 https 协议发送),否则无效。 大概这样设置:Set-Cookie: CookieName=CookieValue; SameSite=Strict;

点击劫持

这个比较好理解,我们直接看例子: 其实就是通过覆盖不可见的页面,诱导用户点击而造成的攻击行为。稍微高级一点的伪装可以怎么样呢,就是做成一个游戏界面,让你在页面上狂点,而实际上呢,则会触发一些攻击事件,比如打开摄像头、发送邮件之类的。至于我们为什么会点击,因为骗子通常知道你想要什么😎,好奇心也驱使你这样做,并且我们当时并不觉得会有什么危险,所以我们都愿意试试看。

防御措施

禁止内嵌 iframe

让自己的网站不要被目标网站内嵌,可以通过 js 和设置头部 X-Frame-Options 实现:

  1. if (top.location !== window.location) top.location = window.location
  2. setHeader('X-Frame-Options', 'DENY')
验证码

增加攻击成本。

SQL 注入

因为这个和 XSS 有点小像,所以在这里稍微提及一下😯。
一句话解释:小王利用潜在的数据库漏洞访问或修改数据。

举个栗子

  1. 用户填写了用户名和密码,点击登录发送了一个请求。
  2. 后端接收到请求并解析参数,将其拼装成一个 SQL 语句执行,形如 select * from user where username = '${data.username}' and pwd='${data.pwd}',并返回登录成功。
  3. 结果小王在填写密码的时候写上了 1' or '1'='1,结果后端一拼接 SQL 语句就变成了 select * from user where username = 'xiaowang' and pwd = '1' or '1'='1',显然这是成立的,也会返回成功。

是不是和 XSS 的拼接漏洞很像呢,本来是数据的东西变成程序执行了。

防御措施

以下内容可跳过,仅作为了解:

  • 不要给出具体的错误信息,越具体越给了小王方向
  • 检查数据类型
  • 对数据进行转义
  • 使用参数化查询:相当于分成两条语句,第一步明确目的,不能再被修改;第二步不管传啥只当作数据处理
  • 使用 ORM(对象关系映射):就是可以不用拼 SQL 语句的意思

上传问题

一句话解释:上传的文件被当做程序解析执行。

举个栗子

  1. 小王上传了一个恶意文件 xx.php,内容如下:
<?phpphpinfo();
?>
  1. 如果我们点击该文件的下载链接,就会执行该 php 文件(前提是服务器可以解析 php 文件,并且文件所在目录要有执行的权限)。

防御措施

  • 限制上传后缀 if (ext === 'js') throw new Error('xxx')
  • 文件类型检测 if (file.type !== 'images/png') throw new Error('xxx')
  • 检查文件内容以什么开头
  • 程序输出:就是不运行,有个读写的过程
  • 权限控制:可写可执行互斥原则

DoS 攻击

DoS(Denial of Service)攻击就是利用合理的服务请求来占用过多的服务资源,从而使得合法用户无法得到服务的响应。比如 SYNflood 攻击、IP 欺骗、带宽DoS攻击、塞满服务器的硬盘等攻击手段,这个作为了解就行,具体可自行百度。

其他相关措施

主要都是提高攻击门槛:

  • 明文变换成密文,虽然我们很多密码明文都是一样的,但不同网站的密文一般是不一样的
  • https 传输
  • 频率限制
  • 验证码

总结

没有绝对安全的网站,我们要做的就是提高攻击成本,问题的关键也不在于小王能不能破译,而是值不值得,毕竟付出与收获不成正比,谁愿意倒贴呢?🙌

CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享🎁

😝朋友们如果有需要全套《黑客&网络安全入门&进阶学习资源包》,可以扫描下方二维码免费领取
点击链接也可直接获取 CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
在这里插入图片描述

1️⃣零基础入门

① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

img

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

img

因篇幅有限,仅展示部分资料

2️⃣视频配套资料&国内外网安书籍、文档

① 文档和书籍资料

img

② 黑客技术

img

因篇幅有限,仅展示部分资料

3️⃣网络安全源码合集+工具包

img

4️⃣网络安全面试题

面试题
上述所有资料 ⚡️ ,朋友们如果有需要全套 📦《网络安全入门+进阶学习资源包》,可以扫描下方二维码免费领取 🆓
点击链接也可直接获取 CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php脚本开头注释_PHP文件注释标记及规范小结

PHP文件注释标记及规范小结发布时间&#xff1a;2016-06-17 来源&#xff1a; 点击:次PHP 注释标记access使用范围&#xff1a;class,function,var,define,module该标记用于指明关键字的存取权限&#xff1a;private、public或protecedauthor指明作者copyright使用范围&#xf…

Salesforce宣布5.82亿美元收购文件编辑公司Quip

北京时间8月2日消息&#xff0c;据路透社报道&#xff0c;云软件开发商Salesforce.com周一宣布&#xff0c;已同意以大约5.82亿美元收购文件编辑创业公司Quip。 Salesforce此前已经对Quip进行了投资。Quip开发的文字处理平台供企业员工用于在移动设备、可穿戴设备以及台式机上编…

Java中的main()方法是强制性的吗?

The question is that "Is main() method is compulsory in Java?" 问题是“ main()方法在Java中是强制性的吗&#xff1f;” Yes, we can write a java program without main() method but there is a condition if and only if java JDK version till JDK 5. 是的…

php date( w ),PHP Date()函数详解

页面的最上方加上&#xff1a;date_default_timezone_set(PRC); /*把时间调到北京时间,php5默认为格林威治标准时间*/date ()a: "am"或是"pm"A: "AM"或是"PM"d: 几日&#xff0c;两位数字&#xff0c;若不足则补零&#xff1b…

10.6-全栈Java笔记:常见流详解(四)

上节我们讲到「Java中常用流&#xff1a;数据流和对象流」&#xff0c;本节我们学习文件字符流和文件缓冲流~文件字符流前面介绍的文件字节流可以处理所有的文件&#xff0c;但是字节流不能很好的处理Unicode字符&#xff0c;经常会出现“乱码”现象。所以&#xff0c;我们处理…

python 示例_带有示例的Python File open()方法

python 示例文件open()方法 (File open() Method) open() method is an inbuilt method in Python, it is used to create, open or append a file. open()方法是Python中的内置方法&#xff0c;用于创建&#xff0c;打开或附加文件。 Syntax: 句法&#xff1a; file_object …

php属于脚本,php是脚本语言吗

PHP即“超文本预处理器”&#xff0c;是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言&#xff0c;与C语言类似&#xff0c;是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习&#xff0c;使用广泛&#xff0c;主要适用于Web开发领…

NetMarketShare:本月桌面浏览器市场份额几乎没有变化

NetMarketShare之前关于台式机浏览器市场份额的报告表示&#xff0c;Google Chrome市场份额正在快速上升&#xff0c;而Edge浏览器市场份额正在以蜗牛的速度前进。而该公司的最新统计数据显示&#xff0c;几乎所有浏览器的市场份额或多或少保持不变。 NetMarketShare的最新统计…

treeset java_Java TreeSet add()方法与示例

treeset javaTreeSet类的add()方法 (TreeSet Class add() method) add() method is available in java.util package. add()方法在java.util包中可用。 add() method is used to add the given object(ob) to this TreeSet when it does not already exist otherwise it ignore…

php fpm www.conf,PHP7中php.ini、php-fpm和www.conf 配置

PHP7中php.ini、php-fpm和www.conf 配置php.ini是php运行核心配置文件,下面是一些常用配置extension_dir""● 设置PHP的扩展库路径expose_php Off● 避免PHP信息暴露在http头中display_errors Off● 避免暴露php调用mysql的错误信息log_errors On● 在关闭display…

服务器电流源泉ups电源的三大形式

还记得此前12306官网瘫痪&#xff0c;回家心切急于购票的我们只能感到无比心累。双十一前夕&#xff0c;守在购物车边准备疯狂购物的剁手党们&#xff0c;遇到一直呈现加载状态的页面&#xff0c;不得不感叹想要做马云背后的那个人也要大费周折。作为一个资深网民&#xff0c;不…

timer purge_Java Timer purge()方法与示例

timer purge计时器类purge()方法 (Timer Class purge() method) purge() method is available in java.util package. purge()方法在java.util包中可用。 purge() method is used to remove all canceled tasks from the task queue of this Timer. purge()方法用于从此Timer的…

大话Linux内核中锁机制之原子操作、自旋锁【转】

转自&#xff1a;http://blog.sina.com.cn/s/blog_6d7fa49b01014q7p.html 多人会问这样的问题&#xff0c;Linux内核中提供了各式各样的同步锁机制到底有何作用&#xff1f;追根到底其实是由于操作系统中存在多进程对共享资源的并发访问&#xff0c;从而引起了进程间的竞态。这…

hashmap put方法_Java HashMap put()方法与示例

hashmap put方法HashMap类的put()方法 (HashMap Class put() method) put() method is available in java.util package. put()方法在java.util包中可用。 put() method is used to link the given value element with the given key element in this HashMap. put()方法用于在…

java中jdom,java – JDOM中的命名空间(默认)

我正在尝试使用最新的JDOM包生成XML文档.我遇到了根元素和命名空间的问题.我需要生成这个根元素&#xff1a;xmlns"http://www.energystar.gov/manageBldgs/req"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://www.…

java enummap_Java EnumMap get()方法与示例

java enummapEnumMap类的get()方法 (EnumMap Class get() method) get() method is available in java.util package. get()方法在java.util包中可用。 get() method is used to get the value mapped with the given key element (key_ele) otherwise it returns null when no…

java后台json传递,后台json传递

json除了可以用于前台传递&#xff0c;还可用于后台之间传递。它可以传递List,Map,Bean等类型的数据。例如&#xff1a;User u1new User();u1.setUsername("zy");u1.setPassword("123");User u2new User();u2.setUsername("msl");u2.setPassword…

专家呼吁建安全漏洞信息共享机制并强化管控

近日&#xff0c;由中国网络空间安全协会主办&#xff0c;中国网络空间安全协会网络空间安全法律与公共政策专业委员会、北京邮电大学互联网治理与法律研究中心、公安部第三研究所网络安全法律研究中心、西安交通大学信息安全法律研究中心承办的《网络安全法&#xff08;草案二…

java的equals方法_Java Date equals()方法与示例

java的equals方法日期类equals()方法 (Date Class equals() method) equals() method is available in java.util package. equals()方法在java.util包中可用。 equals() method is used to check whether this date and the given object (o) are equals or not. equals()方法…

lnmp解析php,LNMP之 php解析

[rootLNMP ~]# vim /usr/local/nginx/conf/nginx.conf打开以下PHP 相关项且更改 scripts$fastcgi_script_name;> /usrlocal/nginx/html$fastcgi_script_name;location ~ \.php$ {root html;fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;fastcgi_param…