发布自 Kindem的博客,欢迎你们转载,可是要注意注明出处。另外,该文章收纳在 Kindem的我的的 IT 知识整理仓库,欢迎 Star、Fork、投稿
这一点可能都被说烂了,只要是动态网站,能够说基本上第一个必须考虑的点就是SQL注入。javascript
那什么是SQL注入呢,先举一个例子吧:php
这是一个典型的登陆场景:html
-------------------------------- | Username: | -------------------------------- | Password: | --------------------------------
网站要求用户输入用户名和密码以登陆,这时候一般后端的SQL语句是:前端
select * from user_t where user_t.username = '...' and user_t.password = '...';
看起来好像没有什么问题,当获取到匹配用户名和密码的表项时,判断结果集的数量是否为1,再进行一些其余的逻辑判断,便可断定用户成功登录,可是吧,这样会有一个问题,若是后端代码采用了字符串拼接,这里将出现一个致命的问题:java
好比我按照以下方式输入:git
-------------------------------- | Username: John Kindem'; -- | -------------------------------- | Password: mypassword | --------------------------------
此时SQL语句就会变成:github
select * from user_t where user_t.username = 'John Kindem'; --' and user_t.password = '...';
整理一下,就会变成这样:数据库
select * from user_t where user_t.username = 'John Kindem'; --' and user_t.password = '...';
可见本来密码这一条件,直接被注释掉了,而原来的SQL语句被提早结束了,这样你随意使用一个密码就能登陆为站点任意一个用户,是否是很恐怖,设想一下,假如这个框中包含有管理员用户的登陆功能,这一条语句将毁掉多少数据......后端
因此这就是SQL注入,这一点每每是Web开发中最危险的一个点,因为其每每与权限有关,一旦被攻破就会致使数据库遭到破坏或者是站点控制权的丢失。跨域
SQL注入每每经过构建特殊的输入来进行,这些特殊的输入每每有如下的想法:
SQL的防范其实也很好作,在现代的Web开发中,每每遵循如下几条规则开发就能很好地避免被SQL注入:
对于后者,基本上全部的语言都支持这一点,拿JavaScript来讲:
// Nodejs 链接 MySQL 进行查询 connection.query('select * from student where id = ?', 5, () => { ... });
这样能够查询到 student 表中 id = 5 的表项的全部信息,但同时可以防范SQL注入,由于这样的语句在使用以前就会被预编译,你没法再随意改变SQL语句的构成。
XSS的全称是 Cross Site Scripting,意为跨站脚本攻击,为了区别于 CSS (Cascading Style Sheets) 而特地写成 XSS。这一攻击方法也是很常见的Web攻击之一,并且因为须要在写 JavaScript 的时候特别注意,这一攻击每每容易被忽略。
固然随着前端的发展,如今这一攻击的防范方法每每都会被集成在框架中,好比 React、Vue 中,不少地方就集成了 XSS 防范,你在使用框架的时候,不少地方每每都不须要注意这一点,框架每每帮你作了防御。
这里简单介绍一下 XSS,先举一个例子:
如今有这样一个博客网站:
那么,假如用户在富文本编辑器上写:
hello world <script>alert(0);</script>
富文本编辑器的原理每每是将用户输入的内容转义成带有格式的html文本而且输出,颇有可能它的输出结果是这样的:
<div class="post-editor"> hello world <script>alert(0);</script> </div>
想一想看,若是这样的一段文本,若是原封不动地被显示在看博客的页面,会致使什么?
很显然,其中的 script 标签中的内容,将会直接被当成脚本执行,想一想这会有很危险,有心的攻击者能够利用这一漏洞,为所欲为地写本身的攻击脚本,好比获取用户的 cookie、进行恶意请求、监听用户输入等......
这就是 XSS,在平日写 JavaScript 的过程当中很容易就会产生这一的漏洞,XSS 的生效每每有两个条件:
最简单的例子,就是网站直接将用户的输入做为输出显示在页面上,再或者,站点中有一些 eval() 之类的函数,可以直接执行用户输入......
固然 XSS 的防范也不是不无方法可循,最重要的一点是:
转义这一点,讲的是针对那些可以影响到原有代码的特殊符号,好比 <、> 等,这里给出一些经常使用的转义规则:
--------------------- | < | < | --------------------- | > | > | --------------------- | ' | & | --------------------- | " | " | ---------------------
进行完转义以后,这些字符会被当成普通显示的字符,而不是具备特殊意义的字符
CSRF 全称为 Cross Site Request Forgery,即跨域请求伪造。这一点攻击每每容易被人一楼,在一些老一些的网站,基本上都没有考虑到这一点,就连百度、亚马逊这一些大型网站,在 CSRF 被人大规模利用进行攻击以前甚至都没有作这一方面的防范。隐蔽性高是这一攻击最大的特色。
这一攻击主要利用的是网站对用户身份的绝对信任,CSRF 有一些难以理解,这里用一个例子简单地说清楚:
举一个例子,如今这里有一个网购网站,通常来讲,每每当用户登陆以后,验证了身份后,站点在一次会话结束前,都是信任用户的,也就是说,站点相信用户是本人,可是吧,如今有这样一次操做:
如今想想,会出现什么问题?因为用户没有关闭网购网站的标签页,上一次会话并无结束,恶意网站发送的请求的 cookie 中将会带有与上一次会话相同的 sessionId,也就是说在网购网站的那一端将会认为这一次请求任然是用户的请求,因此会欣然接受。
是否是很可怕?你明明没有作任何操做,你的一切却已经属于了别人。不少时候,被 CSRF 攻击以后,用户每每都不知道发生了什么,本身的钱包就空了。CSRF 最可怕的地方就在于这里,它的攻击目标每每不是站点,而是站点的用户,再者,它的隐蔽性也让人忌惮。
CSRF 的防范,也是有规律可循的,最重要的一点是,站点永远不要信任任何一个用户,须要对用户进行时刻验证,通常来讲如今都是这样操做的:
在平时咱们的开发中,每每静态资源的命名都是有规律的,好比吧,一些同一页面引用的js脚本,会被咱们如此命名:
一样的,图片、CSS 文件都会像这样命名,有心人就能够写一个脚本,遍历整个站点目录,获取一些文件。固然,这些静态文件给他也无妨,毕竟你摁 F12 也是同样的效果......
可是设想一下,假如站点文件服务器上有一些特殊的文件,好比哪个傻傻的开发者使用 bak 格式备份了某一个后端文件,可是忘了删除而后一直存在了服务器上,好比:
这些文件要是给弄到了,至关于网站的后端逻辑直接暴露在了用户面前,有心人就能够经过这些文件来分析获取该站点的一些漏洞。
总的来讲危害仍是不大,可是平日里必定要注意:
跨域问题,自如其名,就是在站点域外获取站点的服务,这样的危害其实不是很大,由于站点通常都有访问控制,每个身份都有本身能作的事情和不能作的事情,并且通常来讲,浏览器和框架对这一攻击都有着严格的防范,基本上来讲,非本域下的请求基本上不可能成功。
可是吧这里仍是提一句吧,仍是以一个例子来讲明:
虽然通常是不太可能成功的......可是咱们仍是假设站点真的傻到这种地步
跨域问题通常经过使用 http response header 中的 Access-Control-Allow-Origin 来防范,这一字段能够声明该 response 容许的域,好比:
Access-Control-Allow-Origin: www.kindemh.cn
那么非本域的全部请求,就算你请求了,你也没法获取到 response
这里值得一提的是,在现代开发中,咱们每每会使用 Ajax 技术来发送异步请求,可是实际上,若是你使用 Ajax 技术,十有八九都会由于跨域限制被拦截,这时候你就须要使用上述字段来容许你本身的服务。因此说这一点其实原本没多大危害,要说真正的危害,仍是对你的开发效率会形成必定的影响。