十大漏洞:SQL注入、跨站脚本、失效的访问控制、失效的身份认真和会话、安全配置错误、敏感信息泄露、攻击检测与防范不足、跨站请求伪造、使用含有已知漏洞的组件、未受保护的APIs。在系统架构设计、技术选型和编码阶段就需要充分考虑安全性要求,避免各类Web应用安全漏洞。

SQL注入

1、原理

      SQL注入即是指web应用程序对用户输入数据的合法性没有判断,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。它不是利用操作系统的BUG来实现攻击,而是利用程序员编程时的疏忽。

例如,一般用户登录用的SQL语句为:SELECT * FROM user WHERE username='admin' AND password='passwd',此处admin和passwd分别为用户输入的用户名和密码,如果程序员没有对用户输入的用户名和密码做处理,就可以构造万能密码成功绕过登录验证,如用户输入' or 1#,SQL语句将变为:SELECT * FROM user WHERE username='' or 1#' AND password='','' or 1为TRUE,#注释掉后面的内容,所以查询语句可以正确执行。

另外,通过or或者and 与1=1、1=2等组合即可判断是否存在SQL注入的漏洞,例如:

http://xxxxxxxx?id=xxx AND 1=1 --

http://xxxxxxxx?id=xxx AND 1=2 --

如果前一个能返回正常信息而后一个不能,则可以判定会有id注入的可能。因为后者即使id正常,1=2永远无法成立。一反一正说明注入的语句可能会正常运行。

2、危害

  1. 绕过登录或者获取到系统管理员权限
  2. 注入时如果数据库权限设置不当,可能会查看到数据库系统表、数据,甚至可以非法增删改查数据等
  3. 如果权限设置不当,注入木马或者利用存储过程扩展功能操作操作系统的shell,比如master.dbo.xp_cmdshell,从而控制整个服务器
  4. 注入过程如果错误没有正确处理,则可能暴露整个系统文件夹结构

3、防范方法

  1. 所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。当前几乎所有的数据库系统都提供了参数化SQL语句执行接口,使用此接口可以非常有效的防止SQL注入攻击。
  2. 对进入数据库的特殊字符(’”<>&*;等)进行转义处理,或编码转换。
  3. 确认每种数据的类型,比如数字型的数据就必须是数字,数据库中的存储字段必须对应为int型。
  4. 数据长度应该严格规定,能在一定程度上防止比较长的SQL注入语句无法正确执行。
  5. 网站每个数据层的编码统一,建议全部使用UTF-8编码,上下层编码不一致有可能导致一些过滤模型被绕过。
  6. 严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害。
  7. 避免网站显示SQL错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
  8. 在网站发布之前建议使用一些专业的SQL注入检测工具进行检测,及时修补这些SQL注入漏洞。

具体在软件开发层面,表现在以下:

  1. 前端表单进行参数格式控制;
  2. 后台进行参数格式化,过滤所有涉及sql的非法字符;可通过拦截器统一拦截
//过滤 sql注解、关键字、符号等

static String reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|"+ "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)";

static Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);//表示忽略大小写

/***************************************************************************

 * 参数校验@param str ep: "or 1=1"

 */

public static boolean isSqlValid(String str) {

Matcher matcher = sqlPattern.matcher(str);

if (matcher.find()) {

System.out.println("参数存在非法字符,请确认:"+matcher.group());//获取非法字符:or

return false;

}

return true;

}
  1.  持久层使用参数化的持久化sql,使用预编译语句集,切忌使用拼接字符串;例如spring的jdbcTemplate防止sql注入,mybatis防止sql注入,jpa防止sql注入。
String sql= "select * from user where name=?";

PreparedStatement ps = conn.prepareStatement(sql);

ps.setString(1, name);

ResultSet rs = ps.executeQuery();

Logo

开源、云原生的融合云平台

更多推荐