系统扫描安全漏洞攻防介绍

XSS 攻击

XSS 攻击的全称是跨站脚本攻击 (Cross Site Scripting), 是 WEB 应用程序中最常见到的攻击手段之一。跨站脚本攻击指的是攻击者在网页中嵌入恶意脚本程序, 当用户打开该网页时, 脚本程序便开始在客户端的浏览器上执行, 以盗取客户端 cookie、 盗取用户名密码、下载执行病毒木马程序等等。

为了不和层叠样式表 (Cascading Style Sheets,CSS) 的缩写混淆, 故将跨站脚本攻击缩写为 XSS

XSS 的防御

XSS 之所以会发生, 是因为用户输入的数据变成了代码。因此,我们需要对用户输入的数据进行 HTML 转义处理, 将其中的“尖括号”、“单引号”、“引号” 之类的特殊字符进行转义编码。

如今很多开源的开发框架本身默认就提供 HTML 代码转义的功能, 如流行的 jstl、Struts 等等, 不需要开发人员再进行过多的开发。
只需要将 escapeXml 设置为 true, jstl 就会将变量中的 HTML 代码进行转义输出。

CSRF 攻击

CSRF 攻击的全称是跨站请求伪造 (cross site request forgery), 是一种对网站的恶意利用, 你可以这么理解 CSRF 攻击:攻击者盗用了你的身份, 以你的名义向第三方网站发送恶意请求。CRSF 能做的事情包括利用你的身份发邮件、发短信、进行交易转账等等, 甚至盗取你的账号。

尽管听起来跟 XSS 跨站脚本攻击有点相似, 但事实上 CSRF 与 XSS 差别很大,XSS 利用的是站点内的信任用户, 而 CSRF 则是通过伪装来自受信任用户的请求来利用受信任的网站。

CSRF 的防御

cookie 设置为 HttpOnly

CSRF 攻击很大程度上是利用了浏览器的 cookie, 为了防止站内的 XSS 漏洞盗取 cookie, 需要在 cookie 中设置 "HttpOnly" 属性, 这样通过程序 (如 JavascriptS 脚本、Applet 等) 就无法读取到 cookie 信息, 避免了攻击者伪造 cookie 的情况出现。

增加 token

CSRF 攻击之所以能够成功, 是因为攻击者可以伪造用户的请求, 该请求中所有的用户验证信息都存在于 cookie 中, 因此攻击者可以在不知道用户验证信息的情况下直接利用用户的 cookie 来通过安全验证。由此可知, 抵御 CSRF 攻击的关键在于: 在请求中放入攻击者所不能伪造的信息, 并且该信息不存在于 cookie 之中。鉴于此, 系统开发人员可以在 HTTP 请求中以参数的形式加入一个随机产生的 token, 并在服务端进行 token 校验, 如果请求中没有 token 或者 token 内容不正确, 则认为是 CSRF 攻击而拒绝该请求。

通过 Referer 识别

根据 HTTP 协议, 在 HTTP 头中有一个字段叫 Referer, 它记录了该 HTTP 请求的来源地址。在通常情况下, 访问一个安全受限页面的请求都来自于同一个网站。如果 Referer 是其他网站的话, 就有可能是 CSRF 攻击, 则拒绝该请求。

SQL 注入攻击

所谓 SQL 注入, 就是通过把 SQL 命令伪装成正常的 HTTP 请求参数, 传递到服务端, 欺骗服务器最终执行恶意的 SQL 命令, 达到入侵目的。攻击者可以利用 SQL 注入漏洞, 查询非授权信息, 修改数据库服务器的数据, 改变表结构, 甚至是获取服务器 root 权限。总而言之,SQL 注入漏洞的危害极大, 攻击者采用的 SQL 指令, 决定攻击的威力。当前涉及到大批量数据泄露的攻击事件, 大部分都是通过利用 SQL 注入来实施的。

SQL 注入的防御

使用预编译语句

预编译语句PreparedStatement是 java.sql 中的一个接口, 继承自 Statement 接口。通过 Statement 对象执行 SQL 语句时, 需要将 SQL 语句发送给 DBMS, 由 DBMS 先进行编译后再执行。而预编译语句和 Statement 不同, 在创建 PreparedStatement 对象时就指定了 SQL 语句, 该语句立即发送给 DBMS 进行编译, 当该编译语句需要被执行时,DBMS 直接运行编译后的 SQL 语句, 而不需要像其他 SQL 语句那样首先将其编译。 

使用 ORM 框架

由上文可见, 防止 SQL 注入的关键在于对一些关键字符进行转义, 而常见的一些 ORM 框架, 如 ibatis、hibernate 等, 都支持对相应的关键字或者特殊符号进行转义, 可以通过简单的配置, 很好的预防 SQL 注入漏洞, 降低了普通的开发人员进行安全编程的门槛。
通过 #符号配置的变量,ibatis 能够对输入变量的一些关键字进行转义, 防止 SQL 注入攻击。

避免密码明文存放

对存储的密码进行单向 Hash, 如使用 MD5 对密码进行摘要, 而非直接存储明文密码, 这样的好处就是万一用户信息泄露, 即圈内所说的被“拖库”, 黑客无法直接获取用户密码, 而只能得到一串跟密码相差十万八千里的 Hash 码。

处理好相应的异常

后台的系统异常, 很可能包含了一些如服务器版本、数据库版本、编程语言等等的信息, 甚至是数据库连接的地址及用户名密码, 攻击者可以按图索骥, 找到对应版本的服务器漏洞或者数据库漏洞进行攻击, 因此, 必须要处理好后台的系统异常, 重定向到相应的错误处理页面, 而不是任由其直接输出到页面上。

上传文件漏洞

在上网的过程中, 我们经常会将一些如图片、压缩包之类的文件上传到远端服务器进行保存, 文件上传攻击指的是恶意攻击者利用一些站点没有对文件的类型做很好的校验这样的漏洞, 上传了可执行的文件或者脚本, 并且通过脚本获得服务器上相应的权利, 或者是通过诱导外 部用户访问或者下载上传的病毒或者木马文件, 达到攻击目的。

为了防范用户上传恶意的可执行文件和脚本, 以及将文件上传服务器当做免费的文件存储服务器使用,需要对上传的文件类型进行白名单 (非黑名单, 这点非常重要) 校验, 并且限制上传文件的大小, 上传的文件, 需要进行重新命名, 使攻击者无法猜测到上传文件的访问路径。

对于上传的文件来说, 不能简单的通过后缀名称来判断文件的类型, 因为恶意攻击可以将可执行文件的后缀名称改成图片或者其他的后缀类型, 诱导用户执行。因此, 判断文件类型需要使用更安全的方式。很多类型的文件, 起始的几个字节内容是固定的, 因此, 根据这几个字节的内容, 就可以确定文件类型, 这几个字节也被称为魔数 (magic number)。