> CentOS > CentOS安全 >

应用系统安全加固之防SQL注入解决方法

前一段时间笔者在领导的安排下开发了一套针对IT系统维护人员的绩效考核知识管理系统,系统上线后经过几次调优系统运行正常。可惜美好的时光总是太短暂,2月份集团派国内做安全的厂商对企业信息化系统安全扫描,发现该系统存在SQL注入式漏洞、数据库提权安全漏洞、密码明文及附件上传安全隐患。领导限期对该系统进行安全整改工作,于是笔者对该系统加班加点进行了一系列的安全加固。
应对措施如下:
1)对于SQL注入式漏洞解决方案是这样的在用户对系统进行操作时首先进行非法字符校验;
2)对数据库提权漏洞问题:一、采取数据库系统账号与应用账号分离即创建应用程序需要访问的账号;二、采取收缩权限并设置指定IP地址可以远程访问数据库;
3)对用户密码进行加密保存;
4)上传附件校验有黑名单转变成白名单方式。
附相关代码如下:
1、防SQL注入代码如下所示(需要的网友直接拷贝后放在自己的工程直接编译后调用即可轻松实现防SQL注入):
package action;
public class StringUtil {
    public StringUtil() {
    }
    public static String replace(String str, String substr, String restr) {
        String[] tmp = split(str, substr);
        String returnstr = null;
        if (tmp.length != 0) {
            returnstr = tmp[0];
            for (int i = 0; i < tmp.length - 1; i++)
                returnstr = dealNull(returnstr) + restr + tmp[i + 1];
        }
        return dealNull(returnstr);
    }
    public static String[] split(String source, String div) {
        int arynum = 0, intIdx = 0, intIdex = 0, div_length = div.length();
        if (source.compareTo("") != 0) {
            if (source.indexOf(div) != -1) {
                intIdx = source.indexOf(div);
                for (int intCount = 1;; intCount++) {
                    if (source.indexOf(div, intIdx + div_length) != -1) {
                        intIdx = source.indexOf(div, intIdx + div_length);
                        arynum = intCount;
                    } else {
                        arynum += 2;
                        break;
                    }
                }
            } else
                arynum = 1;
        } else
            arynum = 0;
        intIdx = 0;
        intIdex = 0;
        String[] returnStr = new String[arynum];
        if (source.compareTo("") != 0) {
            if (source.indexOf(div) != -1) {
                intIdx = (int) source.indexOf(div);
                returnStr[0] = (String) source.substring(0, intIdx);
                for (int intCount = 1;; intCount++) {
                    if (source.indexOf(div, intIdx + div_length) != -1) {
                        intIdex = (int) source
                                .indexOf(div, intIdx + div_length);
                        returnStr[intCount] = (String) source.substring(intIdx
                                + div_length, intIdex);
                        intIdx = (int) source.indexOf(div, intIdx + div_length);
                    } else {
                        returnStr[intCount] = (String) source.substring(intIdx
                                + div_length, source.length());
                        break;
                    }
                }
            } else {
                returnStr[0] = (String) source.substring(0, source.length());
                return returnStr;
            }
        } else {
            return returnStr;
        }
        return returnStr;
    }
    public static boolean sql_inj(String str) {
        String inj_str = "'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
        String inj_stra[] = split(inj_str, "|");
        for (int i = 0; i < inj_stra.length; i++) {
            if (str.indexOf(inj_stra[i]) >= 0) {
                return true;
                
            }
        }
        return false;
    }
    private static String dealNull(String str) {
        String returnstr = null;
        if (str == null)
            returnstr = "";
        else
            returnstr = str;
        return returnstr;
    }
//    public static void main(String[] args) {
//     if(sql_inj("test''")==true)
//        System.out.println("非法字符");
//     else
//     System.out.println("输入内容合法"); 
//        
//    }
}
2、MD5加密代码如下所示:
package action;
import java.security.MessageDigest;
/**
 * <p>
 * Title:MD5加密和验证
 * </p>
 * 
 * <p>
 * Description:
 * </p>
 * 
 * <p>
 * Copyright: Copyright (c) 2006
 * </p>
 * 
 * <p>
 * Company:
 * </p>
 * 
 * @author not attributable
 * @version 1.0
 */
public class MD5 {
 public MD5() {
 }
 /**
  * MD5加密 Computes the MD5 fingerprint of a string.
  * 
  * @return the MD5 digest of the input <code>String</code>
  */
 public static String compute(String inStr) {
  MessageDigest md5 = null;
  try {
   md5 = MessageDigest.getInstance("MD5");
  } catch (Exception e) {
   System.out.println(e.toString());
   e.printStackTrace();
   return "";
  }
  char[] charArray = inStr.toCharArray();
  byte[] byteArray = new byte[charArray.length];
  for (int i = 0; i < charArray.length; i++) {
   byteArray[i] = (byte) charArray[i];
  }
  byte[] md5Bytes = md5.digest(byteArray);
  StringBuffer hexValue = new StringBuffer();
  for (int i = 0; i < md5Bytes.length; i++) {
   int val = ((int) md5Bytes[i]) & 0xff;
   if (val < 16) {
    hexValue.append("0");
   }
   hexValue.append(Integer.toHexString(val));
  }
  return hexValue.toString();
 }
 /**
  * 验证MD5
  * 
  * @param compareStr
  *            String 要比较的字符串
  * @param md5Str
  *            String 加密后的字符串
  * @return boolean 验证通过返回true,否则返回false
  */
 public static boolean compare(String compareStr, String md5Str) {
  String computeStr = compute(compareStr);
  if (computeStr.equals(md5Str)) {
   return true;
  } else {
   return false;
  }
 }
 public static void main(String[] args) {
  System.out.println("aa:==" + compute("aa"));
  System.out.println(compare("aa", "4124bc0a9335c27f086f24ba207a4912"));
 }
}
(责任编辑:IT)