zhaoyu@home:~$

injection attacks

SQL Injection

当服务器以不安全的方式处理客户端传给数据库的参数时,会发生sql注入攻击。假如有如下一个程序执行sql。

Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
Statement statement = connection.createStatement();
String sql = "SELECT * FROM users WHERE email='" + email + "' AND encrypted_password='" + password + "'";
statement.executeQuery(sql);

上述sql语句的构造是不安全的,因为sql没有进行sql控制符的检查(如单引号),黑客可以将sql传入到参数中。如下,当传入email为billy@gmail.com'-- 时,会忽略后面的sql。任何账号都可以登录成功。

statement.executeQuery(
  "SELECT * FROM users WHERE email='billy@gmail.com'--' AND encrypted_password='Z$DSA92H0'");

甚至还可以传入其他各种sql,如billy@gmail.com'; DROP TABLE users;--,删除user表:

statement.executeQuery("SELECT * FROM users WHERE email='billy@gmail.com';
DROP TABLE users;--' AND encrypted_password='Z$DSA92H0'");

解决策略1:使用参数化语句

使用绑定参数构造sql,可以保护程序避免SQL注入。绑定参数是占位符,数据库会将这些占位符安全地替换掉。
当使用绑定参数时,传入的控制字符会以转移字符作为前缀,告诉数据库不作为控制字符处理。参数化语句如下:

Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
   Statement statement = connection.createStatement();
String sql = "SELECT * FROM users WHERE email = ? and encrypted_password = ?";
statement.executeQuery(sql, email, password);

解决策略2:使用ORM

ORM在框架中使用了参数化语句,所以也可以有效防止SQL注入。然而,多数ORM也允许开发者使用原生的SQL,此时,你也需要特别小心。

深层防御

  • 最小权限策略
    避免权限放大,只获取需要执行功能所需的权限。如数据库设置有限的权限,web程序只获取DML权限,不能获取DDL权限。
  • 盲眼和非盲眼SQL注入
    黑客攻击分盲眼和非盲眼。如果黑客得到了具体的信息,如email等关键信息,称为非盲眼。在错误信息中避免关键信息的暴露。

命令注入

命令注入,指攻击者利用网站调用到底层操作系统的不安全命令。如果你的web应用调用了命令行命令,请确保安全地构建命令行字符串。
如我们在后台接收domain参数,调用了nslookup命令。攻击者在传入domain参数时,传入google.com&&echo "IM A HACKER!",那么攻击者就通过 &&命令连接符,注入了一条命令。

解决方案:转义控制符

对传入的参数进行shell转义,和处理sql注入的思路类似,每个语言都有对应的shell转义功能。

远程代码执行

在一些情况下,攻击者可以在web服务器本身注入恶意代码,被称为远程代码执行。这种攻击虽然比前两种少见,但是同样危险。
如java的fastJson漏洞,在低版本时,可以在传入的参数中加入java代码,并让服务器执行这个java代码,这样攻击者就可以达到任何攻击目的了。

解决方案 在反序列化时,禁用代码执行

反序列化框架在主要的编程语言中广泛使用,框架一般会负责该功能。如果要自己定义一个反序列化框架,那么你需要格外注意,在反序列化时禁用所有执行代码可能。

文件上传漏洞

浏览器没有足够的能力检查上传文件的内容,而服务器又通常把上传文件视为大的二进制文件。所以攻击者很容易上传一个包含恶意代码的文件。
web shell工具是黑客常用的工具,攻击者一般会写一个web shell脚本,该脚本会上传一个可以在命令行执行的参数。然后将这个脚本保存为程序格式,如.PHP 等。将该文件作为图片等上传到服务器上,这是攻击成功的关键。一个.php文件不是一个合法的图片,但是在客户端,攻击者可以很容易地禁用js类型检查。
这样,攻击者就成功将恶意web shell代码存放到服务器上了。由于web shell可以通过URL访问,攻击者相当于创建了一个可以执行恶意代码的后门,他们只需要 通过调用URL传递命令执行web shell,就可以在服务器上执行任意的操作系统命令。

解决方案

确保任何上传都不能作为代码执行。在操作系统层面禁用上传文件的执行权限。上传文件后重新命名,这样就不会存在危险的后缀名。卸载没有使用的执行环境。