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,就可以在服务器上执行任意的操作系统命令。
解决方案
确保任何上传都不能作为代码执行。在操作系统层面禁用上传文件的执行权限。上传文件后重新命名,这样就不会存在危险的后缀名。卸载没有使用的执行环境。