天天看點

利用spring AOP 實作 sql注入檢測

什麼是sql注入?

所謂SQL注入,就是通過把SQL指令插入到Web表單送出或輸入域名或頁面請求的查詢字元串,最終達到欺騙伺服器執行惡意的SQL指令。具體來說,它是利用現有應用程式,将(惡意的)SQL指令注入到背景資料庫引擎執行的能力,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網站上的資料庫,而不是按照設計者意圖去執行SQL語句。 [1] 比如先前的很多影視網站洩露VIP會員密碼大多就是通過WEB表單遞交查詢字元暴出的,這類表單特别容易受到SQL注入式攻擊

sql注入導緻原因?

SQL注入的産生原因通常表現在以下幾方面:

①不當的類型處理;

②不安全的資料庫配置;

③不合理的查詢集處理;

④不當的錯誤處理;

⑤轉義字元處理不合适;

⑥多個送出處理不當。

簡單例子

利用spring AOP 實作 sql注入檢測
@Aspect
    @Component
    public class LogAspect {
        /**
         * 切面類
         */
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        // 存在SQL注入風險
        private static final String IS_SQL_INJECTION = "輸入參數存在SQL注入風險";
    
        private static final String UNVALIDATED_INPUT = "輸入參數含有非法字元";
    
        private static final String ERORR_INPUT = "輸入的參數非法";
    
        //切入點
        @Pointcut("execution(public * com.kevin.library.controller.*.*(..))")
        public void webLog() {
        }
    
        //前置通知
        @Before("webLog()")
        public void before(JoinPoint joinPoint)throws Throwable {
            // 接收到請求,記錄請求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            // 記錄下請求内容
            logger.info("URL : " + request.getRequestURL().toString());
            logger.info("HTTP_METHOD : " + request.getMethod());
            logger.info("IP : " + request.getRemoteAddr());
            logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
            logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
        }
    
        //後置通知
        @AfterReturning(returning = "ret", pointcut = "webLog()")
        public void afterReturning(Object ret) throws Throwable {
            // 處理完請求,傳回内容
            logger.info("方法的傳回值 : " + ret);
        }
    
        //後置異常通知
        @AfterThrowing("webLog()")
        public void returnThrowing(JoinPoint joinPoint) {
            logger.info("方法異常時執行");
        }
    
        //最終通知
        @After("webLog()")
        public void after(JoinPoint joinPoint) {
            logger.info("方法最終執行");
        }
    
        //環繞通知
        @Around("webLog()")
        public Object arround(ProceedingJoinPoint pjp) {
            logger.info("方法環繞start.....");
            try {
                Object[] args =pjp.getArgs();// 參數
                //String str = String.valueOf(args);
                String st = Arrays.toString(args );
                if (!IllegalStrFilterUtil.sqlStrFilter(str)) {
                    logger.info(IS_SQL_INJECTION);
                    new RuntimeException(ERORR_INPUT);
                }
                if (!IllegalStrFilterUtil.isIllegalStr(str)) {
                    logger.info(UNVALIDATED_INPUT);
                    new RuntimeException(ERORR_INPUT);
                }
                Object o =  pjp.proceed();
                logger.info("方法環繞proceed,結果是 :" + o);
                return o;
            } catch (Throwable e) {
                e.printStackTrace();
                return null;
            }
        }
    
    }      
public class IllegalStrFilterUtil {
    
        private static Logger logger = LoggerFactory.getLogger(IllegalStrFilterUtil.class);
    
        private static final String REGX = "!|!|@|◎|#|#|(\\$)|¥|%|%|(\\^)|……|(\\&)|※|(\\*)|×|(\\()|(|(\\))|)|_|——|(\\+)|+|(\\|)|§ ";
    
        /**
         * 對常見的sql注入攻擊進行攔截
         *
         * @param input
         * @return
         *  true 表示參數不存在SQL注入風險
         *  false 表示參數存在SQL注入風險
         */
        public static Boolean sqlStrFilter(String input) {
            if (input == null || input.trim().length() == 0) {
                return false;
            }
            input = input.toUpperCase();
    
            if (input.indexOf("DELETE") >= 0 || input.indexOf("ASCII") >= 0 || input.indexOf("UPDATE") >= 0 || input.indexOf("SELECT") >= 0
                    || input.indexOf("'") >= 0 || input.indexOf("SUBSTR(") >= 0 || input.indexOf("COUNT(") >= 0 || input.indexOf(" OR ") >= 0
                    || input.indexOf(" AND ") >= 0 || input.indexOf("DROP") >= 0 || input.indexOf("EXECUTE") >= 0 || input.indexOf("EXEC") >= 0
                    || input.indexOf("TRUNCATE") >= 0 || input.indexOf("INTO") >= 0 || input.indexOf("DECLARE") >= 0 || input.indexOf("MASTER") >= 0) {
                logger.error("該參數怎麼SQL注入風險:sInput=" + input);
                return false;
            }
            logger.info("通過sql檢測");
            return true;
        }
    
        /**
         * 對非法字元進行檢測
         *
         * @param input
         * @return
         *  true 表示參數不包含非法字元
         *  false 表示參數包含非法字元
         */
        public static Boolean isIllegalStr(String input) {
    
            if (input == null || input.trim().length() == 0) {
                return false;
            }
            input = input.trim();
            Pattern compile = Pattern.compile(REGX, Pattern.CASE_INSENSITIVE);
            Matcher matcher = compile.matcher(input);
            logger.info("通過字元串檢測");
            return matcher.find();
        }
    }      
上一篇: k8s架構