此篇文章对常见的web安全问题进行了分析,同时也是面试中常遇到的问题

1、CSRF攻击

本人面试腾讯三面期间的面试题

CSRF(Cross Site Request Forgery),即跨站请求伪造,是一种常见的Web攻击,它利用用户已登录的身份,在用户毫不知情的情况下,以用户的名义完成非法操作。

1.1、攻击原理

下面先介绍一下CSRF攻击的原理:

【面试系列】常考web安全问题总结_sql

1.2、攻击条件

完成 CSRF 攻击必须要有三个条件

  1. 用户已经登录了站点 A,并在本地记录了 cookie

  2. 在用户没有登出站点 A 的情况下(也就是 cookie 生效的情况下),访问了恶意攻击者提供的引诱危险站点 B (B 站点要求访问站点A)。

  3. 站点 A 没有做任何 CSRF 防御

1.3、攻击实例

我们来看一个例子: 当我们登入转账页面后,突然眼前一亮惊现"XXX隐私照片,不看后悔一辈子"的链接,耐不住内心躁动,立马点击了该危险的网站(页面代码如下图所示),但当这页面一加载,便会执行submitForm这个方法来提交转账请求,从而将10块转给黑客。
【面试系列】常考web安全问题总结_面试_02

1.4、防御手段

防范 CSRF 攻击可以遵循以下几种规则:

  1. Get 请求不对数据进行修改

  2. 不让第三方网站访问到用户 Cookie

  3. 阻止第三方网站请求接口

  4. 请求时附带验证信息,比如验证码或者 Token

1) SameSite

  • 可以对 Cookie 设置 SameSite 属性。该属性表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。

2) Referer Check

  • HTTP Referer是header的一部分,当浏览器向web服务器发送请求时,一般会带上Referer信息告诉服务器是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。可以通过检查请求的来源来防御CSRF攻击。正常请求的referer具有一定规律,如在提交表单的referer必定是在该页面发起的请求。所以通过检查http包头referer的值是不是这个页面,来判断是不是CSRF攻击

  • 但在某些情况下如从https跳转到http,浏览器处于安全考虑,不会发送referer,服务器就无法进行check了。若与该网站同域的其他网站有XSS漏洞,那么攻击者可以在其他网站注入恶意脚本,受害者进入了此类同域的网址,也会遭受攻击。出于以上原因,无法完全依赖Referer Check作为防御CSRF的主要手段。但是可以通过Referer Check来监控CSRF攻击的发生。

3) Anti CSRF Token

  • 目前比较完善的解决方案是加入Anti-CSRF-Token。即发送请求时在HTTP 请求中以参数的形式加入一个随机产生的token,并在服务器建立一个拦截器来验证这个token。 服务器读取浏览器当前域cookie中这个token值,会进行校验该请求当中的token和cookie当中的token值是否都存在且相等,才认为这是合法的请求。否则认为这次请求是违法的,拒绝该次服务。

  • 这种方法相比Referer检查要安全很多,token可以在用户登陆后产生并放于session或cookie中,然后在每次请求时服务器把token从session或cookie中拿出,与本次请求中的token 进行比对。由于token的存在,攻击者无法再构造出一个完整的URL实施CSRF攻击。但在处理多个页面共存问题时,当某个页面消耗掉token后,其他页面的表单保存的还是被消耗掉的那个token,其他页面的表单提交时会出现token错误。

4) 验证码

  • 应用程序和用户进行交互过程中,特别是**账户交易这种核心步骤,强制用户输入验证码,才能完成最终请求。**在通常情况下,验证码够很好地遏制CSRF攻击。但增加验证码降低了用户的体验,网站不能给所有的操作都加上验证码。所以只能将验证码作为一种辅助手段,在关键业务点设置验证码。

2、sql注入

2.1、原理

  1. **sql注入的原理是将sql代码伪装到输入参数中,传递到服务器解析并执行的一种攻击手法。**也就是说,在一些对server端发起的请求参数中植入一些sql代码,server端在执行sql操作时,会拼接对应参数,同时也将一些sql注入攻击的“sql”拼接起来,导致会执行一些预期之外的操作。

  2. SQL注入,是从正常的 WWW 端口访问,而且表面看起来跟一般的 Web 页面访问没什么区别,如果管理员没查看日志的习惯,可能被入侵很长时间都不会发觉。

2.2、实例

   1. 比如我们使用的登录接口:在登录界面包括用户名和密码输入框,以及提交按钮,输入用户名和密码,提交。**登录时调用接口/user/login/ 加上参数username、password,首先连接数据库,然后后台对请求参数中携带的用户名、密码进行参数校验,即sql的查询过程。**
   2. 假设正确的用户名和密码为``admin``和``123456``,输入正确的用户名和密码、提交,相当于调用了以下的SQL语句。
SELECT * FROM user WHERE username = 'admin' AND password = '123456'
  1. sql中会将#及以后的字符串当做注释处理,如果我们使用or 1=1 # 作为用户名参数,那么服务端构建的sql语句就如下:
select * from users where username='' or 1=1#' and password='123456'
  1. 而**#会忽略后面的语句**,因此上面的sql也等价于:
select * from users where username='' or 1=1
  1. 1=1属于常等型条件,因此这个sql便成为了如下,查询出所有的登陆用户。
select * from users

​ 其实上面的sql注入只是在参数层面做了些手脚,如果是引入了一些功能性的sql那就更危险了,比如上面的登陆接口,如果用户名使用这个or 1=1;delete * from users; #,那么在;之后相当于是另外一条新的sql,这个sql是删除全表,是非常危险的操作,因此sql注入这种还是需要特别注意的。

2.3、解决方案

1)sql预编译

在知道了sql注入的原理之后,我们同样也了解到mysql有预编译的功能,指的是在服务器启动时,mysql client把sql语句的模板(变量采用占位符进行占位)发送给mysql服务器,mysql服务器对sql语句的模板进行编译,编译之后根据语句的优化分析对相应的索引进行优化,在最终绑定参数时把相应的参数传送给mysql服务器,直接进行执行,节省了sql查询时间,以及mysql服务器的资源,达到一次编译、多次执行的目的,除此之外,还可以防止SQL注入。

​ 具体是怎样防止SQL注入的呢?实际上当将绑定的参数传到mysql服务器,mysql服务器对参数进行编译,即填充到相应的占位符的过程中,做了转义操作。 我们常用的Mybatis就有预编译功能,不仅提升性能,而且防止sql注入。

String sql = "select id, no from user where id=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, id);
ps.executeQuery();

2)严格的参数校验

​ 参数校验就没得说了,在一些不该有特殊字符的参数中提前进行特殊字符校验即可。

3、DNS劫持&污染

本人面试百度一面期间的面试题

3.1、DNS劫持

  1. DNS劫持 就是通过劫持了 DNS 服务器,通过某些手段取得某域名的解析记录控制权,进而修改此域名的解析结果,导致对该域名的访问由原 IP 地址转入到修改后的指定 IP,结果就是对特定的网址不能访问或访问的是假网址,从而实现窃取资料或者破坏原有正常服务的目的。DNS劫持 通过篡改 DNS 服务器上的数据返回给用户一个错误的查询结果来实现的。

  2. DNS劫持 症状:**某些地区的用户在成功连接宽带后,首次打开任何页面都指向 ISP 提供的“电信互联星空”、“网通黄页广告”等内容页面。**还有就是曾经出现过用户访问 Google 域名的时候出现了百度的网站。这些都属于 DNS劫持。

3.2、DNS污染

  1. DNS污染,又称为域名服务器缓存污染(DNS cache pollution)或者域名服务器快照侵害(DNS cache poisoning)。 **DNS污染是指一些刻意制造或无意中制造出来的域名服务器分组,把域名指往不正确的IP地址。**它是一种让一般用户由于得到虚假目标主机IP而不能与其通信的方法,是一种DNS缓存投毒攻击(DNS cache poisoning)。其工作方式是:**由于通常的DNS查询没有任何认证机制,而且DNS查询通常基于的UDP是无连接不可靠的协议,因此DNS的查询非常容易被篡改,通过对UDP端口53上的DNS查询进行入侵检测,一经发现与关键词相匹配的请求则立即伪装成目标域名的解析服务器(NS,Name Server)给查询者返回虚假结果。**DNS污染是发生在用户请求的第一步上,直接从协议上对用户的DNS请求进行干扰。

  2. DNS污染症状:目前一些被禁止访问的网站很多就是通过DNS污染来实现的,例如YouTube、Facebook等网站。

3.3、实例

  • 你访问google.com 因为人家服务器在国外,你的DNS过去解析,肯定要走国际带宽的出口,然后就被GFW逮住了。因为DNS 走的是UDP协议,且UDP又没有什么校验机制,只管发送。所以这时候,GFW就假装成DNS服务器回应你了,而此时真正的请求可能正在被真正的DNS服务器处理,假的已经返回给你了,浏览器就选择了最快返回的那个地址去解析了。当然是一个不可用的地址啦。
  • 因为DNS 走的UDP协议,并且是53端口,所以这有多好发现也就不言而喻了。如果你强行让DNS走TCP协议,GFW 有办法让你连接重置,虽然污染不了你的DNS,但是你还是无法获得ip。
  • 也就是为什么有一种FQ方式就叫修改host 文件,修改后,域名不需要去DNS服务器请求了,直接在你的操作系统里就已经解析出了ip 地址。但是,GFW还是会定期封杀这些网站的ip地址,你的host就没用了。

解决方案

  1. 对于 DNS劫持,可以通过手动更换 DNS 服务器为 公共DNS 解决。

  2. 对于 DNS污染,可以说,个人用户很难单单靠设置解决,通常可以使用 VPN 或者域名远程解析的方法解决,但这大多需要购买付费的 VPN 或 SSH 等,也可以通过修改 Hosts 的方法,手动设置域名正确的 IP 地址。

4、XSS攻击

XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。 这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。

4.1、攻击原理

【面试系列】常考web安全问题总结_面试_03
  • 如果没有对参数进行过滤,用户可以输入任意字符,那么我们的程序逻辑可能被破坏,从而执行其他的代码,实习恶意的功能。
  • 代码逻辑一定要在用户输入不可信的基础上进行设计!!!

4.2、攻击手段

  1. 获取用户cookie
  2. 对页面进行篡改和钓鱼
  3. 进行蠕虫传播
  4. 执行恶意命令

4.3、解决方案

一般来讲,对参数进行过滤,如使用过滤函数、转义函数、正则表达式,避免将未经处理的用户输入数据直接运行或者输出到页面,就可以解决接近80%的漏洞。

5、CC 攻击 & DDOS 攻击

5.1、攻击原理

攻击,即是通过大量合法的请求占用大量网络资源,以达到瘫痪网络的目的。

  • CC 攻击,主要是用来攻击页面的,模拟多个用户不停的对你的页面进行访问,从而使你的系统资源消耗殆尽。
  • DDOS 攻击,中文名叫分布式拒绝服务攻击,指借助服务器技术将多个计算机联合起来作为攻击平台,来对一个或多个目标发动 DDOS 攻击。

5.2、解决方案

预防 CC、DDOS 攻击,这些只能是用硬件防火墙做流量清洗,将攻击流量引入黑洞

【面试系列】会持续更新,欢迎关注公众号“任冬学编程”,一起学习与进步!
【面试系列】常考web安全问题总结_web安全_04