Java编程安全漏洞之:注入漏洞

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

SQL_Injection

SQL查询语句注入,来自用户的数据通过字符串拼接的方式构筑到SQL语句中。

修复建议

使用带占位符的预编译执行方式的SQL语句,并且,所有非程序自身的数据都不参与SQL语句的构成。

修复示例

如:

       public void SQL_Injection(HttpServletRequest request, Connection c){

              String text = request.getParameter("text");

              Statement s = c.createStatement();

              String sql = "select * from table where 1 = 1";

              s.executeQuery(sql + " and a = '" + text + "'");

       }

修复为:

       public void SQL_Injection_Fix(HttpServletRequest request, Connection c){

              String text = request.getParameter("text");

              String sql = "select * from table where 1 = 1 and a = ?";

              PreparedStatement s = c.preparedStatement(sql);

              s.setString(1, text);

              s.executeQuery();

       }

Second_Order_SQL_Injection

二次SQL注入,来自数据库的数据通过字符串拼接的方式构筑到SQL语句中。

修复建议

使用带占位符的预编译执行方式的SQL语句,并且,所有非程序自身的数据都不参与SQL语句的构成。

修复示例

如:

       public void SQL_Injection(HttpServletRequest request, Connection c){

              String text = request.getParameter("text");

              Statement s = c.createStatement();

              String sql = "select * from table where 1 = 1";

              s.executeQuery(sql + " and a = '" + text + "'");

       }

修复为:

       public void SQL_Injection_Fix(HttpServletRequest request, Connection c){

              String text = request.getParameter("text");

              String sql = "select * from table where 1 = 1 and a = ?";

              PreparedStatement s = c.preparedStatement(sql);

              s.setString(1, text);

              s.executeQuery();

       }

Code_Injection

代码注入,来自用户的数据被用作程序代码执行。

修复建议

所有程序外来数据都不要用作代码、反射使用。不要动态去构造对象。

修复示例

如:String methodName = request.getParameter(“CbData.SYNC_METO”);

……

Method syncMethod = dataSynClazz.getMethod(methodName,null);

修复为:

String methodName = request.getParameter(“CbData.SYNC_METO”);

 

private Map methodPool = new HashMap();

 

Method  syncMethod = methodPool.get(methodName);

如:public Object getInstance(String className) throws Exception{

Class clazz = Class.forName(className);

return clazz.newInstance();

}

修复为:

Private Map> classPool = new HashMap>();

{

classPool.put(“UserClass”,userClass.class);

}

Public Object getInstance(String className) throws Exception{

Class clazz = classPool.get(className);

return clazz.newInstance();

}

Connection_String_Injection

连接字符串注入,来自用户的数据被用作连接字符命令。

修复建议

所有程序外来数据都不要用作连接字符串、反射使用,若要使用可使用配置方式。

Command_Injection

命令行注入,用户可控的数据被直接作为系统命令在命令行执行。

修复建议

使用封装类,枚举限制可被执行的命令。

修复示例

如:

public class CommandLine_Injection{

       public static void main(String[] args){

              StringBuffer sb = new StringBuffer();

              if(args != null){

                     for(String arg : args){

                            sb.append(arg + " ");

                     }

              }

              try {

                     Runtime.getRuntime().exec(sb.toString());

              } catch (IOException e) {

                     e.printStackTrace();

              }

       }

}

修复为:

public class CommandLine_Injection{

       public static void main(String[] args){

              WindowsCmd wc = new NotepadCmd(args);

              if(wc.isValid()){

                     try {

                            Runtime.getRuntime().exec(wc.getCommandLineString());

                     } catch (IOException e) {

                            e.printStackTrace();

                     }

              }

       }

}

public interface WindowsCmd{

       String getCommandLineString();

       boolean isValid();

}

public class NotepadCmd implements WindowsCmd{

       private static final String head = "notepad";

       //Java中的正则执行引擎存在性能问题,可使用字符串处理方式校验。

       private static final String fileRegex = "[a-zA-Z]:/(([^/\\t\\*<>\\?\\|:\"])+/)*([^/\\t\\*<>\\?\\|:\"])+";

       public NotepadCmd(String[] args){

              valid = false;

              if(args != null && args.length >= 2){

                     String aName = args[0];

                     String fName = args[1];

                     aName = aName.toLowerCase();

                     if(head.equals(aName)){

                            if("".equals(fName.replaceAll(fileRegex, ""))){

                                   fileName = fName;

                                   valid = true;

                            }

                     }

              }

       }

       private String fileName;

       private boolean valid;

       public String getFileName(){

              return fileName;

       }

       public boolean isValid(){

              return valid;

       }

       public String getCommandLineString(){

              return new String(head) + " " + getFileName();

       }

}

 

Resource_Injection

资源注入,程序接收客户端输入数据,但在输入被用作一个可能超出预期控制范围的资源的标识符之前,不对该输入进行限制或过滤。

修复建议

使用正确的黑名单和白名单组合去确保系统只对有效的、预期的输入进行处理。

LDAP_Injection

LDAP注入,程序没有足够过滤在LDAP查询和响应中的有害字符,从而允许攻击者注入特定字符去修改LDAP查询的语法、内容和命令。

修复建议

假设所有输入都是恶意的。使用合适的黑名单和白名单组合来过滤或引用来自于用户控制输入数据的LDAP句法。

修复示例

context = new InitialDirContext(env);

String searchFilter = "StreetAddress=" + address;

NamingEnumeration answer = context.search(searchBase, searchFilter, searchCtls);

用户输入数据(地址)在被用于构建LDAP查询前没有被正确验证。应当对address进行黑名单和白名单过滤验证。

XPath_Injection

XPath注入,使用客户端输入数据,构造一个XPath表达式从xml中检索数据,但并未对用户可控的输入数据进行过滤。

修复建议

使用参数化的XPath查询。过滤用户输入的数据并对数据进行转义。

转载于:https://my.oschina.net/u/3100849/blog/863704

你可能感兴趣的:(Java编程安全漏洞之:注入漏洞)