学编程,来源栈;先学习,再交钱
当前系列: 框架&架构 修改讲义

复习:代码安全

HTTPS

HTTP协议是明文传递的,而互联网上的信息传递会经过很多网络节点(复习:路由,每一个节点都可能存在安全隐患,所以,更安全的做法需要对信息进行加密(复习)。于是现在主流推荐的是采用HTTPS协议。其中的S,代表SSL(Secure Sockets Layer),安全套接字层。

很多浏览器(比如chrome和火狐),访问非HTTPS协议的网址,会给予警告:

要用户手动操作确认允许访问才行,而且会一直用图标标注:不安全。

是否使用HTTPS协议,和我们开发没关系,使用HTTPS协议也只需要简单部署,但其底层原理可能是#高等级面试题#。

互联网中加密

但在互联网中使用加密,有更具体的问题:一台服务器要响应无数的不确定用户的访问,如何和他们“约定”加密?算法可以公开,秘钥呢?不用说用户A可能无法妥善保管秘钥,就是给秘钥这个过程,都可能是不安全的呀!

所以必然引入不对称加密(复习):

  • 公钥:公开的,任何人都可以获得
  • 私钥:只有服务器端持有

从客户端到服务器

用户使用公钥将敏感信息加密,发送给服务器。

于是,只有服务器能获取其正确信息,因为服务器才有私钥。

这就是:防泄漏,客户的信息不会被泄露。

通常,这些信息都不大,加密和解密都不费劲。

从服务器端到客户端

服务器用私钥将信息加密,发送给用户。

@想一想@:为什么?能不能防泄漏?不能。因为哪怕是用私钥加密,但公钥是公开的,所以任何人都可以解密。

但是,可以:防篡改

哪怕信息被劫持被解密然后修改,因为没有私钥,它无法正确加密。被错误加密的信息,用正确的公钥无法解开。

数字签名

服务器发送给客户端的信息通常比较大,全部加密的话可能有性能压力。(这就是很多项目不愿意HTTPS的原因!)

但是,既然服务器端加密的目的只是“防篡改”,我们就有了一个好主意:

  1. 用Hash函数,在整个信息的基础上,生成一段“摘要(abstract)”
  2. 用私钥加密这段“摘要”,形成一个“数字签名(digit signature)”,和信息一起发送给客户端
  3. 客户端收到信息后,用公钥解密“数字签名”,得到“解密的摘要”
  4. 然后,对整个信息使用同样的Hash函数,获得“生成的摘要”,和我的“解密的摘要”相对比
  5. 如果两份摘要一致,表明数据未经篡改;否则,……

认证证书

@想一想@:还有没有问题?有的,客户端怎么拿到公钥?

一种是直接由服务器给,这种方式不够“权威”。因为服务器可能已经被“劫持”了,用户拿到的可能是一个“假”的公钥。浏览器还是会报警告:“未认证的SSL证书”云云。

所以更常见的是从使用一个权威的第三方(认证机构,CA)获取,具体的流程包括:

  1. 服务器向认证机构申请为某域名认证
  2. 认证机构给服务器一个私钥(一长串字符),服务器上配置访问该域名时告诉用户到哪里获取公钥
  3. 用户使用浏览器访问该网站,浏览器会根据服务器指示向认证机构申请公钥


MD5加密

JavaC#有不同的类库实现方式

脚本注入

病从口入:小心用户输入!

Web2.0开始,大量未认证的用户可以通过网站“操纵”数据库,这就给了恶意用户可乘之机:

SQL注入

详见数据库章节

Script注入

又被称之为XSS(Cross Site Scripting,为了避免和样式的CSS混淆,改为XSS)攻击。

其实就是在发布内容中输入一段恶意的(Java)Script代码,比如:
<script>
  location = "http://17bang.ren"
</script>

这样当程序将这段代码当做文章内容发布的时候,@想一想@:会发生什么?

所以后台需要对用户输入进行处理:

一种方式是转义,把用户输入中的尖括号变成&lt;和&gt;(复习:HTML)。

但是,很多时候我们是要允许用户输入的HTML标签生效的(演示:富文本编辑器),这就需要过滤:去掉有潜在危害的,只保留允许使用的标签和属性(JavaScript也可以通过属性的方式存在)。

过滤又两种策略:

  • 黑名单:过滤掉黑名单中出现的标签和属性;
  • 白名单:只允许使用白名单中的标签和属性,其他一律过滤掉,推荐!
如何过滤呢?使用正则表达式(复习)匹配


跨域请求欺骗

漏洞

无论从哪个页面访问目标网站(比如:http://17bang.ren/),浏览器都会自动将其存放的该网站cookie发送过去;

而这cookie当中,存储了用户身份验证信息……

演示:百度搜素“一起帮”,点击我们网站连接,自动登录

@想一想@:于是你能干什么坏事?^_^

CSRF

Cross-Site Request Forgery:CSRF,或者XSRF:

  1. 攻击方(黑客)可以做一个“陷阱网站”,里面放上诸如:妹妹好寂寞,阿泰快来之类的链接,诱使其他用户点击。这个链接可以通过url参数或JavaScript代码给目标网站指令,比如点赞/转账/发布评论等等
  2. 如果该用户之前曾经访问/登录过目标网站,且该网站使用cookie存放用户授权信息,浏览器就会把自动的cookie也传递到被攻击网站
  3. 被攻击网站无法辨别用户是:真正的想进行链接指示的操作,还是受欺骗后由陷阱网站生成的指令(#再次体会:HTTP无状态)

演示:

<a class="appraise-status-item text-success" href="http://sample.17bang.ren/Article/Appraise?id=50&amp;direction=1" data-author-id="7">
    肤白貌美,夜深人静,寂寞难耐……
</a>


解决方案

让服务器确保该HTTP请求确实由“我”自己生成的HTML页面/链接……所产生的。

怎么确定?八仙过海各显神通,但ASP.NET(core)和SpringWeb都提供了几乎是现成的方案:

  1. 在生成表单时在其中插入一个hidden input,里面存储一个服务器生成的token做签名,
  2. 表单提交时会自动附上该签名
  3. 服务器在表单提交后对其中的签名进行验证……


其他

DDoS

Distributed Denial of Service Attack,分布式拒绝服务攻击。

DoS攻击是(通过程序)不断的向网站发起请求,使网络或系统不胜负荷以至于瘫痪而停止提供正常的网络服务。与DoS攻击由单台主机发起攻击相比,分布式拒绝服务攻击是借助无数台被(木马)入侵后安装了攻击进程的电脑同时发起的,所以规模更大、欺骗性更强、防御难度更大……最管用的解决办法就是:提高自身服务器的吞吐能力,来多少我干多少!^_^

防盗链

简单的说,就是在别人使用了由你的服务器/网站提供的资源(比如:图片)

演示:<img src="https://pic2.zhimg.com/v2-1d934807c57b0bbdc08fd40ea0f503d5_720w.jpg?source=c8b7c179" />

如果你不想当这种“活雷锋”,就可以使用一些技术禁止掉这种情况。一种简单的办法就是在响应这种请求之前,检查其referrer是否是本站网址!

演示:

反爬虫/机器人

爬虫其实也是一种机器人,对付他们最好的办法就是:图像验证。

专业的说法:captcha,Completely Automated Public Turing Test to Tell Computers and Humans Apart ,全自动区分计算机和人类的图灵测试),顾名思义,利用电脑和人脑的差异,用一张人类轻松识别的图片,考一考电脑:嗨,兄弟,这是啥?如果电脑/程序能够通过这个测试,他/她就通过了图灵测试,是强人工智能了!

服务器管理

权限:不是任何人都可以直接登录服务器的!

白名单:端口、服务、驱动……要用才开,不用就关。

备份/回滚:……


最后的啰嗦

HTTP本身是一个不安全的协议,

前端没有任何安全性可言,

后端永远不要相信前端!

学习笔记
源栈学历
键盘敲烂,月薪过万作业不做,等于没学

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 框架&架构 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码