From 2ed1199d48f7207f4a012c04f61e13ac1a8d5154 Mon Sep 17 00:00:00 2001
From: chenjiahe <763432473@qq.com>
Date: 星期四, 16 六月 2022 10:27:44 +0800
Subject: [PATCH] 新增请求安全工具

---
 src/main/java/com/hx/mybatis/aes/springbean/SqlUtils.java |  297 +++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 197 insertions(+), 100 deletions(-)

diff --git a/src/main/java/com/hx/mybatis/aes/springbean/SqlUtils.java b/src/main/java/com/hx/mybatis/aes/springbean/SqlUtils.java
index a2ad79e..8d978db 100644
--- a/src/main/java/com/hx/mybatis/aes/springbean/SqlUtils.java
+++ b/src/main/java/com/hx/mybatis/aes/springbean/SqlUtils.java
@@ -3,10 +3,7 @@
 import com.alibaba.druid.sql.SQLUtils;
 import com.alibaba.druid.sql.ast.SQLExpr;
 import com.alibaba.druid.sql.ast.SQLStatement;
-import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
-import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
 import com.alibaba.druid.sql.ast.statement.*;
-import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement;
 import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
 import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
 import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
@@ -17,6 +14,8 @@
 import com.alibaba.druid.util.JdbcConstants;
 import com.alibaba.druid.util.JdbcUtils;
 import com.hx.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.Collection;
 import java.util.List;
@@ -27,8 +26,11 @@
  * @author CJH 2022-01-12
  */
 public class SqlUtils {
+    //log4j鏃ュ織
+    private static Logger logger = LoggerFactory.getLogger(SqlUtils.class.getName());
 
-    /**鏌ヨ鍔犲瘑鏁版嵁澶勭悊锛屽彧瀵规煡璇㈠仛澶勭悊锛宻elect杩斿洖涓嶅仛澶勭悊
+
+    /**鏌ヨ鍔犲瘑鏁版嵁澶勭悊锛屽彧瀵规煡璇㈠仛澶勭悊
      * @param sql sql璇彞
      * @param aesKeysTable aes绉橀挜
      * @return
@@ -37,13 +39,88 @@
 
         MySqlStatementParser parser = new MySqlStatementParser(sql);
         SQLSelectStatement sqlStatement = (SQLSelectStatement) parser.parseSelect();
-        //鑾峰彇鏍煎紡鍖栫殑slq璇彞
-        sql = sqlStatement.toString();
+
+        SQLSelect sqlSelect = sqlStatement.getSelect();
+        if (sqlSelect.getQuery() instanceof SQLSelectQueryBlock) {
+            // 闈瀠nion鐨勬煡璇㈣鍙�
+            return selectSqlRoutine( sqlStatement,aesKeysTable);
+        } else if (sqlSelect.getQuery() instanceof SQLUnionQuery) {
+            // union鐨勬煡璇㈣鍙�
+            return selectSqlUnion( sql, sqlStatement, aesKeysTable);
+        }else {
+            return selectSqlRoutine( sqlStatement,aesKeysTable);
+        }
+    }
+
+    /**鏌ヨ鍔犲瘑鏁版嵁澶勭悊锛屽彧瀵规煡璇㈠仛澶勭悊锛宻elect杩斿洖涓嶅仛澶勭悊锛圲nion鐗规畩璇彞锛�
+     * @param sql sql璇彞
+     * @param aesKeysTable aes绉橀挜
+     * @return
+     */
+    public static String selectSqlUnion(String sql,SQLSelectStatement sqlStatement,Map<String,Map<String,String>> aesKeysTable){
+
+        //鑾峰彇琛ㄥ拰鍒悕
+        ExportTableAliasVisitor visitorTable = new ExportTableAliasVisitor();
+        sqlStatement.accept(visitorTable);
+        Map<String,String> tableMaps = visitorTable.getTableMap();
+
+        //鑾峰彇鎵�鏈夌殑瀛楁
+        MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
+        sqlStatement.accept(visitor);
+        //閬嶅巻鎵�鏈夊瓧娈�
+        Collection<TableStat.Column> columns= visitor.getColumns();
+
+        //澶勭悊闇�瑕佸姞瀵嗗緱瀛楁
+
+        if(!StringUtils.isEmpty(sql)){
+            Map<String,String> aesKeys = null;
+            String aeskey = null;
+            //鎶婂墿涓嬬殑鎷兼帴涓婃潵
+            String tableAl = null;
+            for(TableStat.Column column:columns){
+                aesKeys= aesKeysTable.get(column.getTable());
+                if(aesKeys == null){
+                    continue;
+                }
+                aeskey = aesKeys.getOrDefault(column.getName(),null);
+                if(StringUtils.isEmpty(aeskey)){
+                    continue;
+                }
+                tableAl = tableMaps.get(column.getTable());
+                if(!StringUtils.isEmpty(tableAl)){
+                    tableAl = tableAl+"."+column.getName();
+                }else{
+                    tableAl = column.getName();
+                }
+                sql = sql.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')");
+            }
+        }
+        return sql;
+    }
+
+
+    /**鏌ヨ鍔犲瘑鏁版嵁澶勭悊锛屽彧瀵规煡璇㈠仛澶勭悊锛宻elect杩斿洖涓嶅仛澶勭悊锛堝父瑙勮鍙ワ級
+     * @param sqlStatement sql璇彞
+     * @param aesKeysTable aes绉橀挜
+     * @return
+     */
+    public static String selectSqlRoutine(SQLSelectStatement sqlStatement,Map<String,Map<String,String>> aesKeysTable){
 
         //瑙f瀽select鏌ヨ
         //SQLSelect sqlSelect = sqlStatement.getSelect()
         //鑾峰彇sql鏌ヨ鍧�
-        SQLSelectQueryBlock sqlSelectQuery = (SQLSelectQueryBlock)sqlStatement.getSelect().getQuery() ;
+        SQLSelectQueryBlock sqlSelectQuery = null;
+        boolean b = true;
+        try{
+            sqlSelectQuery = (SQLSelectQueryBlock)sqlStatement.getSelect().getQuery() ;
+        }catch (Exception e){
+            b = false;
+            logger.error("瑙f瀽sql鎶ラ敊锛�"+e.getMessage());
+        }
+        if(!b){
+            return "err";
+        }
+
         StringBuffer out = new StringBuffer() ;
         //鍒涘缓sql瑙f瀽鐨勬爣鍑嗗寲杈撳嚭
         SQLASTOutputVisitor sqlastOutputVisitor = SQLUtils.createFormatOutputVisitor(out , null , JdbcUtils.MYSQL) ;
@@ -69,31 +146,37 @@
             if(sqlSelect.length() > 7){
                 sqlSelect.append(",");
             }
-            expr = sqlSelectItem.getExpr().toString();
-            if(expr.indexOf("SELECT") == -1){
+
+            out.delete(0, out.length()) ;
+            sqlSelectItem.accept(sqlastOutputVisitor) ;
+            expr = out.toString();
+            sqlSelect.append(expr);
+
+           /* if(expr.indexOf("SELECT") == -1){
                 sqlSelect.append(expr);
-                if(!StringUtils.isEmpty(sqlSelectItem.getAlias())){
-                    sqlSelect.append(" AS "+sqlSelectItem.getAlias());
-                }
             }else{
-                sqlSelect.append("(");
-                sqlSelect.append(selectSqlHandle(expr,aesKeysTable,tableMaps,columns));
-                sqlSelect.append(")");
-                if(!StringUtils.isEmpty(sqlSelectItem.getAlias())){
+                //sqlSelect.append("(");
+                sqlSelect.append(expr);
+                //sqlSelect.append(")");
+               *//* if(!StringUtils.isEmpty(sqlSelectItem.getAlias())){
                     sqlSelect.append(" AS "+sqlSelectItem.getAlias());
-                }
-            }
+                }*//*
+            }*/
         }
 
         //瑙f瀽from
-        out.delete(0, out.length()) ;
-        sqlSelectQuery.getFrom().accept(sqlastOutputVisitor) ;
-        sqlWhere.append(" FROM "+out);
+        if(sqlSelectQuery.getFrom() != null){
+            out.delete(0, out.length()) ;
+            sqlSelectQuery.getFrom().accept(sqlastOutputVisitor) ;
+            sqlWhere.append(" FROM "+out);
+        }
 
         //瑙f瀽where
-        out.delete(0, out.length()) ;
-        sqlSelectQuery.getWhere().accept(sqlastOutputVisitor) ;
-        sqlWhere.append(" WHERE "+out+" ");
+        if(sqlSelectQuery.getWhere() != null){
+            out.delete(0, out.length()) ;
+            sqlSelectQuery.getWhere().accept(sqlastOutputVisitor) ;
+            sqlWhere.append(" WHERE "+out+" ");
+        }
 
         if(sqlSelectQuery.getGroupBy() != null){
             out.delete(0, out.length()) ;
@@ -112,7 +195,7 @@
         }
 
         //澶勭悊where闇�瑕佸姞瀵嗗緱瀛楁
-        sql = sqlWhere.toString();
+        String sql = sqlWhere.toString();
         if(!StringUtils.isEmpty(sql)){
             Map<String,String> aesKeys = null;
             String aeskey = null;
@@ -133,12 +216,20 @@
                 }else{
                     tableAl = column.getName();
                 }
-                sql = sql.replaceAll("( |\\n|\\()"+tableAl+"( |\\n|\\))"," AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"') ");
+                sql = sql.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')");
             }
         }
         return sqlSelect.toString()+sql;
     }
 
+    /**
+     * 澶勭悊select杩斿洖瀛楁鐨勫弬鏁�
+     * @param sql
+     * @param aesKeysTable
+     * @param tableMaps
+     * @param columns
+     * @return
+     */
     public static String selectSqlHandle(String sql,Map<String,Map<String,String>> aesKeysTable
             ,Map<String,String> tableMaps,Collection<TableStat.Column> columns){
 
@@ -183,14 +274,18 @@
         }
 
         //瑙f瀽from
-        out.delete(0, out.length()) ;
-        sqlSelectQuery.getFrom().accept(sqlastOutputVisitor) ;
-        sqlWhere.append(" FROM "+out);
+        if(sqlSelectQuery.getFrom() != null){
+            out.delete(0, out.length()) ;
+            sqlSelectQuery.getFrom().accept(sqlastOutputVisitor) ;
+            sqlWhere.append(" FROM "+out);
+        }
 
         //瑙f瀽where
-        out.delete(0, out.length()) ;
-        sqlSelectQuery.getWhere().accept(sqlastOutputVisitor) ;
-        sqlWhere.append(" WHERE "+out+" ");
+        if(sqlSelectQuery.getWhere() != null){
+            out.delete(0, out.length()) ;
+            sqlSelectQuery.getWhere().accept(sqlastOutputVisitor) ;
+            sqlWhere.append(" WHERE "+out+" ");
+        }
 
         if(sqlSelectQuery.getGroupBy() != null){
             out.delete(0, out.length()) ;
@@ -230,7 +325,7 @@
                 }else{
                     tableAl = column.getName();
                 }
-                sql = sql.replaceAll("( |\\n|\\()"+tableAl+"( |\\n|\\))"," AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"') ");
+                sql = sql.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')");
             }
         }
         return sqlSelect.toString()+sql;
@@ -241,72 +336,72 @@
      * @param aesKeysTable aes绉橀挜
      * @return
      */
-   public static String insertSql(String sql,Map<String,Map<String,String>> aesKeysTable){
-       //瑁呰浇閲嶅啓鐨剆ql璇彞
-       StringBuilder splicingSql = new StringBuilder();
+    public static String insertSql(String sql,Map<String,Map<String,String>> aesKeysTable){
+        //瑁呰浇閲嶅啓鐨剆ql璇彞
+        StringBuilder splicingSql = new StringBuilder();
 
-       sql = SQLUtils.format(sql, JdbcConstants.MYSQL);
-       String[] datas = sql.split("VALUES",2);
+        sql = SQLUtils.format(sql, JdbcConstants.MYSQL);
+        String[] datas = sql.split("VALUES",2);
 
-       splicingSql.append(datas[0]+"VALUES ");
+        splicingSql.append(datas[0]+"VALUES ");
 
-       //閲嶆柊鎷兼帴SQL璇彞
+        //閲嶆柊鎷兼帴SQL璇彞
 
-       //瑙f瀽sql璇彞
-       MySqlStatementParser parser = new MySqlStatementParser(sql);
-       SQLStatement statement = parser.parseStatement();
-       MySqlInsertStatement insert = (MySqlInsertStatement)statement;
+        //瑙f瀽sql璇彞
+        MySqlStatementParser parser = new MySqlStatementParser(sql);
+        SQLStatement statement = parser.parseStatement();
+        MySqlInsertStatement insert = (MySqlInsertStatement)statement;
 
-       String insertName = insert.getTableName().getSimpleName();
+        String insertName = insert.getTableName().getSimpleName();
 
-       //鏍规嵁琛ㄥ悕绉拌幏鍙栧埌AES绉橀挜
-       Map<String,String> aesKeys= aesKeysTable.get(insertName);
-       if(aesKeys == null){
-           return sql;
-       }
+        //鏍规嵁琛ㄥ悕绉拌幏鍙栧埌AES绉橀挜
+        Map<String,String> aesKeys= aesKeysTable.get(insertName);
+        if(aesKeys == null){
+            return sql;
+        }
 
-       //鑾峰彇鎵�鏈夌殑瀛楁
-       List<SQLExpr> columns = insert.getColumns();
+        //鑾峰彇鎵�鏈夌殑瀛楁
+        List<SQLExpr> columns = insert.getColumns();
 
-       String fildValue = null;
-       String aeskey = null;
-       //閬嶅巻鍊�
-       List<SQLInsertStatement.ValuesClause> vcl = insert.getValuesList();
-       for(int j = 0; j<vcl.size(); j++){
-           if( j != 0){
-               splicingSql.append(",");
-           }
-           for(int i = 0;i < columns.size();i++){
-               //鏌ヨ鏀瑰瓧娈垫槸鍚﹂渶瑕佸姞瀵�
-               aeskey = aesKeys.getOrDefault(columns.get(i).toString(),null);
-               fildValue = vcl.get(j).getValues().get(i).toString();
-               if(i == 0){
-                   splicingSql.append("(");
-                   if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){
-                       splicingSql.append("HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))");
-                   }else{
-                       splicingSql.append(fildValue);
-                   }
-               }else if(i == columns.size()-1){
-                   splicingSql.append(",");
-                   if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){
-                       splicingSql.append("HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))");
-                   }else{
-                       splicingSql.append(fildValue);
-                   }
-                   splicingSql.append(")");
-               }else{
-                   splicingSql.append(",");
-                   if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){
-                       splicingSql.append("HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))");
-                   }else{
-                       splicingSql.append(fildValue);
-                   }
-               }
-           }
-       }
-       return splicingSql.toString();
-   }
+        String fildValue = null;
+        String aeskey = null;
+        //閬嶅巻鍊�
+        List<SQLInsertStatement.ValuesClause> vcl = insert.getValuesList();
+        for(int j = 0; j<vcl.size(); j++){
+            if( j != 0){
+                splicingSql.append(",");
+            }
+            for(int i = 0;i < columns.size();i++){
+                //鏌ヨ鏀瑰瓧娈垫槸鍚﹂渶瑕佸姞瀵�
+                aeskey = aesKeys.getOrDefault(columns.get(i).toString(),null);
+                fildValue = vcl.get(j).getValues().get(i).toString();
+                if(i == 0){
+                    splicingSql.append("(");
+                    if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){
+                        splicingSql.append("HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))");
+                    }else{
+                        splicingSql.append(fildValue);
+                    }
+                }else if(i == columns.size()-1){
+                    splicingSql.append(",");
+                    if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){
+                        splicingSql.append("HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))");
+                    }else{
+                        splicingSql.append(fildValue);
+                    }
+                    splicingSql.append(")");
+                }else{
+                    splicingSql.append(",");
+                    if(aeskey != null && fildValue.indexOf("AES_ENCRYPT") == -1){
+                        splicingSql.append("HEX(AES_ENCRYPT("+fildValue+",'"+aeskey+"'))");
+                    }else{
+                        splicingSql.append(fildValue);
+                    }
+                }
+            }
+        }
+        return splicingSql.toString();
+    }
 
     /**鏇存柊鍔犲瘑鏁版嵁澶勭悊
      * @param sql sql璇彞
@@ -314,6 +409,7 @@
      * @return
      */
     public static String updateSql(String sql,Map<String,Map<String,String>> aesKeysTable){
+
         //瑁呰浇閲嶅啓鐨剆ql璇彞
         StringBuilder splicingSql = new StringBuilder();
 
@@ -323,7 +419,6 @@
         //鑾峰彇鏍煎紡鍖栫殑slq璇彞
         sql = sqlStatement.toString();
 
-
         MySqlUpdateStatement updateStatement = (MySqlUpdateStatement)sqlStatement;
 
         String insertName = updateStatement.getTableName().getSimpleName();
@@ -331,9 +426,11 @@
         String[] datas = sql.split("WHERE",2);
 
         Map<String,String> aesKeys = aesKeysTable.get(insertName);
+        if(aesKeys == null){
+            return sql;
+        }
 
         splicingSql.append("UPDATE "+insertName+" SET ");
-
         String aeskey = null;
         String fildValue = null;
         List<SQLUpdateSetItem> items = updateStatement.getItems();
@@ -341,9 +438,7 @@
             if(i != 0){
                 splicingSql.append(",");
             }
-
             SQLUpdateSetItem item = items.get(i);
-
             //鏌ヨ鏀瑰瓧娈垫槸鍚﹂渶瑕佸姞瀵�
             aeskey = aesKeys.getOrDefault(item.getColumn().toString(),null);
 
@@ -354,7 +449,6 @@
                 splicingSql.append(item.getColumn()+" = "+fildValue);
             }
         }
-
         String sqlWhere = " WHERE";
         //鎶婂墿涓嬬殑鎷兼帴涓婃潵
         if(datas.length > 1){
@@ -395,11 +489,11 @@
                 }else{
                     tableAl = column.getName();
                 }
-                sqlWhere = sqlWhere.replaceAll("( |\\n|\\()"+tableAl+"( |\\n|\\))"," AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"') ");
+                sqlWhere = sqlWhere.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')");
             }
 
         }
-        splicingSql.append(sqlWhere.toString());
+        splicingSql.append(sqlWhere);
         return splicingSql.toString();
     }
 
@@ -425,6 +519,9 @@
         String[] datas = sql.split("WHERE",2);
 
         Map<String,String> aesKeys = aesKeysTable.get(insertName);
+        if(aesKeys == null){
+            return sql;
+        }
 
         splicingSql.append("DELETE FROM "+insertName);
 
@@ -470,11 +567,11 @@
                 }else{
                     tableAl = column.getName();
                 }
-                sqlWhere = sqlWhere.replaceAll("( |\\n|\\()"+tableAl+"( |\\n|\\))"," AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"') ");
+                sqlWhere = sqlWhere.replaceAll("((?<!\\.)\\b"+tableAl+"\\b(?!\\.))","AES_DECRYPT(UNHEX("+tableAl+"),'"+aeskey+"')");
             }
 
         }
-        splicingSql.append(sqlWhere.toString());
+        splicingSql.append(sqlWhere);
         return splicingSql.toString();
     }
 

--
Gitblit v1.8.0