走进JavaWeb技术世界17:web安全攻防详解


安全要素与 STRIDE 威胁

今天,来分享下安全要素与 STRIDE 威胁。

STRIDE 威胁

STRIDE 威胁,代表六种安全威胁:身份假冒(Spoofing)、篡改(Tampering)、抵赖(Repudiation)、信息泄露(Information Disclosure)、拒绝服务(Denial of Service)、特权提升(Elevation of Privilege)。

身份假冒(Spoofing)

身份假冒,即伪装成某对象或某人。例如,我们通过伪造别人的 ID 进行操作。

篡改(Tampering)

篡改,即未经授权修改数据或者代码。例如,我通过网络抓包或者某种途径修改某个请求包,而服务端没有进行进一步的防范措施,使得我篡改的请求包提交成功。

抵赖(Repudiation)

抵赖,即拒绝执行他人无法证实也无法反对的行为而产生抵赖。例如,我攻击了某个产品,他们并不知道是我做的,没有证据证明是我做的,我就可以进行抵赖,换句话说,我可以死不承认。

信息泄露(Information Disclosure)

信息泄露,即将信息暴露给未授权用户。例如,我通过某种途径获取未经加密的敏感信息,例如用户密码。

拒绝服务(Denial of Service)

拒绝服务,即拒绝或降低有效用户的服务级别。例如,我通过拒绝服务攻击,使得其他正常用户无法使用产品的相关服务功能。

特权提升(Elevation of Privilege)

特权提升,即通过非授权方式获得更高权限。例如,我试图用管理员的权限进行业务操作。

安全要素

为了防范上面的 STRIDE 威胁,我们需要采用一些防范措施。

威胁 安全要素 消减技术
身份假冒 认证 Kerberos、SSL/TLS、证书、认证码等
篡改 完整性 访问控制列表、SSL/TLS、认证码等
抵赖 非抵赖/审计/记录 安全审计和日志记录、数字签名、可信第三方
信息泄露 保密 加密、访问控制列表
拒绝服务 可用性 访问控制列表、过滤、配额、授权
特权提升 授权 访问控制列表、角色控制、授权

如何防范常见的Web攻击

今天,从开发人员的角度,并结合我在开发过程中遇到的问题,说说《如何防范常见的Web攻击》话题。

SQL注入攻击

SQL注入攻击,这个是最常聊到的话题,使用过Java的开发人员,第一个反应就是一定要使用预编译的PrepareStatement,是吧?

什么是SQL注入攻击

攻击者在HTTP请求中注入恶意的SQL代码,服务器使用参数构建数据库SQL命令时,恶意SQL被一起构造,并在数据库中执行。

用户登录,输入用户名 lianggzone,密码 ‘ or ‘1’=’1 ,如果此时使用参数构造的方式,就会出现

 
   
  1. select * from user where name = 'lianggzone' and password = '' or '1'='1'

不管用户名和密码是什么内容,使查询出来的用户列表不为空。

现在还会存在SQL注入攻击么

这个问题在使用了预编译的PrepareStatement后,安全性得到了很大的提高,但是真实情况下,很多同学并不重视,还是会留下漏洞的。举个例子,看看,大家的代码中对 sql 中 in 操作,使用了预编译,还是仍然还是通过字符串拼接呢?

如何防范SQL注入攻击

使用预编译的PrepareStatement是必须的,但是一般我们会从两个方面同时入手。

  • Web端
  1. 有效性检验。
  2. 限制字符串输入的长度。
  • 服务端
  1. 不用拼接SQL字符串。
  2. 使用预编译的PrepareStatement。
  3. 有效性检验。(为什么服务端还要做有效性检验?第一准则,外部都是不可信的,防止攻击者绕过Web端请求)
  4. 过滤SQL需要的参数中的特殊字符。比如单引号、双引号。

XSS攻击

什么是XSS攻击

跨站点脚本攻击,指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。

假设页面上有一个表单

 
   
  1. type="text" name="name" value="梁桂钊"/>

如果,用户输入的不是一个正常的字符串,而是

 
   
  1. "/>

此时,页面变成下面的内容,在输入框input的后面带上了一段脚本代码。

 
   
  1. type="text" name="name" value="梁桂钊"/>

这端脚本程序只是弹出一个消息框,并不会造成什么危害,攻击的威力取决于用户输入了什么样的脚本,只要稍微修改,便可使攻击极具攻击性。

XSS攻击有多可怕

蛮早之前,我曾经找了几个网站做个测试,其实大家对XSS攻击的防范还是不够,都成功的注入了测试脚本。

甚至,还有攻击者提交恶意的javascript代码的评论信息或者反馈信息(这些信息,正常客户端没有做xss校验,会存在客户端注入问题),所有访问者访问该内容时,都会执行这段恶意的javascript代码。

如何防范XSS攻击

  1. 前端,服务端,同时需要字符串输入的长度限制。
  2. 前端,服务端,同时需要对HTML转义处理。将其中的”<”,”>”等特殊字符进行转义编码。

CSRF攻击

什么是CSRF攻击

跨站点请求伪造,指攻击者通过跨站请求,以合法的用户的身份进行非法操作。可以这么理解CSRF攻击:攻击者盗用你的身份,以你的名义向第三方网站发送恶意请求。CRSF能做的事情包括利用你的身份发邮件,发短信,进行交易转账,甚至盗取账号信息。

如何防范CSRF攻击

  1. 安全框架,例如Spring Security。
  2. token机制。在HTTP请求中进行token验证,如果请求中没有token或者token内容不正确,则认为CSRF攻击而拒绝该请求。
  3. 验证码。通常情况下,验证码能够很好的遏制CSRF攻击,但是很多情况下,出于用户体验考虑,验证码只能作为一种辅助手段,而不是最主要的解决方案。
  4. referer识别。在HTTP Header中有一个字段Referer,它记录了HTTP请求的来源地址。如果Referer是其他网站,就有可能是CSRF攻击,则拒绝该请求。但是,服务器并非都能取到Referer。很多用户出于隐私保护的考虑,限制了Referer的发送。在某些情况下,浏览器也不会发送Referer,例如HTTPS跳转到HTTP。

文件上传漏洞

什么是文件上传漏洞

文件上传漏洞,指的是用户上传一个可执行的脚本文件,并通过此脚本文件获得了执行服务端命令的能力。

许多第三方框架、服务,都曾经被爆出文件上传漏洞,比如很早之前的Struts2,以及富文本编辑器等等,可能被一旦被攻击者上传恶意代码,有可能服务端就被人黑了。

如何防范文件上传漏洞

  1. 文件上传的目录设置为不可执行。
  2. 判断文件类型。在判断文件类型的时候,可以结合使用MIME Type,后缀检查等方式。因为对于上传文件,不能简单地通过后缀名称来判断文件的类型,因为攻击者可以将可执行文件的后缀名称改为图片或其他后缀类型,诱导用户执行。
  3. 对上传的文件类型进行白名单校验,只允许上传可靠类型。
  4. 上传的文件需要进行重新命名,使攻击者无法猜想上传文件的访问路径,将极大地增加攻击成本,同时向shell.php.rar.ara这种文件,因为重命名而无法成功实施攻击。
  5. 限制上传文件的大小。
  6. 单独设置文件服务器的域名。

访问控制

一般来说,“基于URL的访问控制”是最常见的。

垂直权限管理

访问控制实际上是建立用户与权限之间的对应关系,即“基于角色的访问控制”,RBAC。不同角色的权限有高低之分。高权限角色访问低权限角色的资源往往是被允许的,而低权限角色访问高权限的资源往往被禁止的。在配置权限时,应当使用“最小权限原则”,并使用“默认拒绝”的策略,只对有需要的主体单独配置”允许”的策略,这在很多时候能够避免发生“越权访问”。

例如,Spring Security, Apache Shiro都可以建立垂直权限管理。

水平权限管理

水平权限问题在同一个角色上,系统只验证了访问数据的角色,没有对角色内的用户做细分,由于水平权限管理是系统缺乏一个数据级的访问控制所造成的,因此水平权限管理又可以称之为“基于数据的访问控制”。

举个理解,比如我们之前的一个助手产品,客户端用户删除评论功能,如果没有做水平权限管理,即设置只有本人才可以删除自己的评论,那么用户通过修改评论id就可以删除别人的评论这个就存在危险的越权操作。

这个层面,基本需要我们业务层面去处理,但是这个也是最为经常遗落的安全点。

总结

上面列举的几个话题,都是我在开发过程中,遇到的比较常见的Web安全话题,以及一些防范方案,需要我们在开发过程中及时规避,而不是依靠安全人员或者真正用户,甚至恶意的攻击者帮我们去发现问题。当然,还有很多Web安全话题,例如远程执行漏洞、拒绝服务攻击、Session保持攻击等等,如果读者对于安全方面有兴趣,可以阅读 吴翰清《白帽子讲Web安全》, 值得推荐。



服务端通信安全攻防详解



接着,昨天《HTTPS原理剖析与项目场景》的话题,我觉得安全方面有蛮多话题可以聊聊的,那么今天再分享一篇《服务端通信安全攻防详解》。

服务端接口通信过程中,一般是明文传输的,没有经过任何安全处理。那么这个时候就很容易在传输过程中被中间者窃听、篡改、冒充等风险。因此,对于敏感信息,以及重要文件就需要进行加密策略,保证通信的安全性。

Base64加密传输

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,但是它其实并不是一种用于安全领域的加密解密算法。

但是,Base64编码的数据并不会被人用肉眼所直观的理解,所以也有人使用Base64来进行加密解密,这里所说的加密与解密实际是指编码和解码的过程。

这种,加密传输的安全性是非常低的,Base64加密非常容易被人识别并解码。

DES对称加密

DES也是一种非常常用的加密方案,我们会将敏感的信息在通信过程中通过DES进行加密传输,然后在客户端和服务端直接进行解码。

此时,作为读者的你,可能会有个疑问,那如何保管密钥呢?其实,想想,答案就复出水面了,因为客户端和服务端都需要进行解码,所以两者都要存一份密钥。其实,还有一种方案是通过服务端下发,但是下发的时候通信的安全性也是没有很好的保障。

所以,DES对称加密也是存在一定的安全隐患:密钥可能会泄漏。这边,举个真实的案例,某个APP的资源不错,同事想抓包分析下其服务端通信的信息结构,但是发现它既然全部采用了DES加密方案,本来想放弃了,但是我们又回头想想客户端肯定需要密钥对接口的加密的内容做解码才能正常展现,那么密钥肯定在app包中,因此我们又对app进行了反编译,结果成功的获取到了密钥,对服务端通信的加密信息进行了解码。

AES对称加密

AES和DES类似,相较于DES算法而言,AES算法有着更高的速度和资源使用效率,安全级别也较之更高。一般情况下,用于文件的加密。我们之前做个不准确测试,AES和DES分别对一个大文件加密,AES的速度大概是DES的5倍。(因为基于工具和环境问题,这个数据不是很准确哟)。

仍然存在一个相同的问题:密钥可能会泄漏。因此,保管好密钥很关键。

升级到HTTPS

这个可以参考上篇博客《HTTPS原理剖析与项目场景》的内容。

HTTPS的价值在于:

  • 内容加密,第三方无法窃听。
  • 身份认证,一旦被篡改,通信双方会立刻发现。
  • 数据完整性。防止内容冒充或者篡改。

这个方案,没法保护敏感数据,如果需要对敏感数据进行加密,还是需要考虑加密方案。

URL签名

基于OAuth2协议,进行URL签名。这个方案,有很多话题可以分享,后面另开一篇来详细讲解。

值得注意的是,URL签名只能垂直权限管理,但没法保护敏感数据,如果需要对敏感数据进行保护,还是需要考虑加密方案。

双向RSA加密

RSA双向认证,就是用对方的公钥加密是为了保密,这个只有对方用私钥能解密。用自己的私钥加密是为了防抵赖,能用我的公钥解开,说明这是我发来的。

例如,支付宝的支付接口就是非常典型的RSA双向认证的安全方案。此外,我们之前的教育资源、敏感验证码出于安全性考虑都借鉴了这个方案。

HTTPS原理剖析与项目场景

发表于 2016-10-19 | 安全相关 | 安全 HTTPS

文章目录

  1. 1. 为什么使用HTTPS
  2. 2. 什么是HTTPS
  3. 3. HTTPS原理剖析
  4. 4. HTTPS的相关场景
    1. 4.1. 场景一,对HTTPS进行CDN加速
    2. 4.2. 场景二,对HTTPS的域名通过CNAME绑定到另外一个HTTPS域名上
    3. 4.3. 场景三,两台服务器的证书问题
  5. 5. HTTPS设计上的借鉴



最近手头有两个项目,XX导航和XX产业平台,都需要使用HTTPS协议,因此,这次对HTTPS协议做一次整理与分享。

为什么使用HTTPS

HTTP 协议,本身是明文传输的,没有经过任何安全处理。那么这个时候就很容易在传输过程中被中间者窃听、篡改、冒充等风险。这里提到的中间者主要指一些网络节点,是用户数据在浏览器和服务器中间传输必须要经过的节点,比如 WIFI 热点,路由器,防火墙,反向代理,缓存服务器等。

HTTP 协议,中间者可以窃听隐私,使用户的敏感数据暴露无遗;篡改网页,例如往页面插的广告内容,甚至进行流量劫持,比如有的时候你会发现域名没输错,结果却跑到了一个钓鱼网站上,因为被它劫持了。

为了解决这三大风险,HTTPS的价值就体现出来了。

  • 内容加密,第三方无法窃听。
  • 身份认证,一旦被篡改,通信双方会立刻发现。
  • 数据完整性。防止内容冒充或者篡改。

什么是HTTPS

HTTPS,简单的理解HTTP的安全版,即HTTP下加入SSL层,由两部分组成:HTTP + SSL / TLS。

HTTPS原理剖析

第一步,用户在浏览器里输入一个https网址,此时客户端发起HTTPS请求,通过TCP和服务器建立连接(443端口)。

第二步,服务器存放CA证书进行处理,注意的是采用HTTPS协议的服务器必须要有一套数字证书,这套证书其实就是一对公钥和私钥。

第三步,服务器向客户端返回证书。证书里面包含了很多信息:比如域名,申请证书的公司,公钥等。以下是一个淘宝网的CA证书。


第四步,客户端对证书进行解析。这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随机数,然后用证书对该随机数进行加密。

第五步,向服务器发送证书加密后的随机数。

第六步,服务器用它的私钥进行解密,得到了客户端传过来的随机数。

第七步,服务器用客户端的随机数加密后的信息发送给客户端。

第八步,客户端用之前生成的密钥解密服务端传过来的信息。

以上就是整个HTTPS的交互过程,大家是不是对整个流程有了比较大致的了解了呢。

HTTPS的相关场景

真实业务场景是复杂的,这里,整理3个项目中遇到的比较复杂的应用场景。

场景一,对HTTPS进行CDN加速

这种情况下,CA证书需要存放在哪里呢?

主要两个方案。

方案一:服务器(源站)提供证书给CDN厂商,包括公钥证书和私钥,CDN负责交互和内容缓存,CDN有缓存则直接响应,以HTTP或HTTPS的形式回源。这个方案,适用仅对防劫持、防篡改有需求,而愿意提供证书给CDN的源站加速。

方案二:服务器(源站)不提供证书,CDN存放公钥,服务器(源站)存放私钥。在CDN与前端浏览器进行TLS的认证和秘钥协商过程中,通过安全的信道把协商过程中的信息以HTTP或HTTPS的形式转发给源网站。此方案中,CDN不做缓存,仅以自有的加速网络,将用户的请求快速送到服务器(源站),降低公网延迟。这个方案,适用于对安全要求更高,不愿将私钥共享给CDN的源站加速。

场景二,对HTTPS的域名通过CNAME绑定到另外一个HTTPS域名上

这个情况下,我们需要一个证书还是两个证书呢?

我们的方案是,两个证书。因为每个证书跟自己的域名进行绑定,即使它们都在同一个服务器上,也不能使用同一个证书。

场景三,两台服务器的证书问题

因为安全问题,CA证书在一台服务器上,而服务部署在另外一台服务器上。这种情况就比较难办。

此时,需要借助Nginx进行反向代理,回源到具体的服务器。

HTTPS设计上的借鉴

对于HTTPS设计上的方案,对于我们而言,有什么可以借鉴的地方么?

答案是肯定的:有。一个非常典型的方案就是RSA双向认证。

RSA双向认证,顾名思义,就是用对方的公钥加密是为了保密,这个只有对方用私钥能解密。用自己的私钥加密是为了防抵赖,能用我的公钥解开,说明这是我发来的。例如,支付宝的支付接口就是非常典型的RSA双向认证的安全方案。此外,我们之前的教育资源、敏感验证码出于安全性考虑都借鉴了这个方案。


HTTPS 降级攻击的场景剖析与解决之道

这篇文章,一个月前就想整理成文,可惜最近事情比较多,一直拖着。那么,今天的话题就来讲讲《HTTPS 降级攻击的场景剖析与解决之道》。一个对安全性的要求很高的产品,不仅需要使用HTTPS协议,并且需要防止HTTPS降级攻击。

HTTPS 一定安全么

HTTP 协议,本身是明文传输的,没有经过任何安全处理。那么这个时候就很容易在传输过程中被中间者窃听、篡改、冒充等风险。这里提到的中间者主要指一些网络节点,是用户数据在浏览器和服务器中间传输必须要经过的节点,比如 WIFI 热点,路由器,防火墙,反向代理,缓存服务器等。HTTP 协议,中间者可以窃听隐私,使用户的敏感数据暴露无遗;篡改网页,例如往页面插的广告内容,甚至进行流量劫持,比如有的时候你会发现域名没输错,结果却跑到了一个钓鱼网站上,因为被它劫持了。

此时,HTTPS 的价值就体现出来了。HTTPS 协议在应用层的 HTTP 协议和以及传输层 TCP 协议之间的会话层加入了 SSL/TLS 协议,用作加密数据包。在真正数据传输之前,进行握手通信,握手的信息交换主要包括:双方确认加密协议的版本,确认身份(其中浏览器客户端的身份有时是不需要确认的),确认传输真正数据的加密密码(对称加密)。在用作信息传输的加密密码确认之后,接下来的通信数据都会加密后再传输,从而达到防窃取的作用。原理剖析,可以参考我之前的文章《HTTPS原理剖析与项目场景》。

那么,使用了 HTTPS 就能确保安全传输了吗?理论上,是的,但是,现实却不是如此。

设计和实现 SSL/TLS 协议出现了漏洞,导致攻击者同样可以攻击一些旧版本的 SSL/TLS 协议。这其中就包括 SSL 3.0。

什么是 HTTPS 降级攻击

攻击者可利用 SSL 3.0 漏洞获取安全连接当中某些是SSL3.0加密后的明文内容。因为兼容性问题,当浏览器进行 HTTPS 连接失败的时候,将会尝试使用旧的协议版本,于是,加密协议由更加安全的协议,比如 TLS 1.2降级成 SSL 3.0。

如果服务器提供有漏洞的 SSL 3.0 协议的支持,同时,攻击者又能作为中间人控制被攻击者的浏览器发起漏洞版本的 HTTPS 请求,那虽然攻击者监听到的也是加密过的数据,但因为加密协议有漏洞,可以解密这些数据。攻击者可以利用此漏洞,截获用户的隐私数据,比如 Cookie,这样攻击者就可以拿到这些隐私数据,进行更深层次的攻击,进而造成了用户隐私的泄漏。

解决之道

目前,唯一解决问题的方法是禁用 SSL 3.0 加密协议,防止TLS 1.2 或者 TLS 1.1 或者 TLS 1.0降级到 SSL 3.0 加密协议。

禁用的策略有很多,这里主要讲解下 Nginx 如何防止 TLS 降级到 SSL 3.0 以下版本,从而防止 HTTPS 降级攻击。

原先的配置如下。值得注意的是,隐性默认是SSLv3 TLSv1 TLSv1.1 TLSv1.2。

 
   
  1. ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;

禁用的操作很简单,现在改成这样即可。

 
   
  1. ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

总结

HTTPS 能确保安全传输了吗?答案是,不一定,因为旧的版本存在安全漏洞,可能会被攻击者进行 HTTPS 的降级攻击。所以,SSL 3.0 协议以下版本并不安全,因此,为了防止 HTTPS 的降级攻击,我们需要禁用它。


你可能感兴趣的:(走进JavaWeb技术世界17:web安全攻防详解)