mirror of https://github.com/jeecgboot/jeecg-boot
删除jsqlparse代码
parent
0e184eaa64
commit
37c593e1d4
|
@ -1,75 +0,0 @@
|
|||
package org.jeecg.test.sqlinjection;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import org.jeecg.common.util.SqlInjectionUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
* SQL注入攻击检查测试
|
||||
* @author: liusq
|
||||
* @date: 2023年09月08日
|
||||
*/
|
||||
@Slf4j
|
||||
public class TestInjectWithSqlParser {
|
||||
/**
|
||||
* 注入测试
|
||||
*
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
private boolean isExistSqlInject(String sql) {
|
||||
try {
|
||||
SqlInjectionUtil.specialFilterContentForOnlineReport(sql);
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.info("===================================================");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test() throws JSQLParserException {
|
||||
//不存在sql注入
|
||||
assertFalse(isExistSqlInject("select * from fm_time where dept_id=:sqlparamsmap.id and time=:sqlparamsmap.time"));
|
||||
assertFalse(isExistSqlInject("select * from test"));
|
||||
assertFalse(isExistSqlInject("select load_file(\"C:\\\\benben.txt\")"));
|
||||
assertFalse(isExistSqlInject("WITH SUB1 AS (SELECT user FROM t1) SELECT * FROM T2 WHERE id > 123 "));
|
||||
|
||||
//存在sql注入
|
||||
assertTrue(isExistSqlInject("or 1= 1 --"));
|
||||
assertTrue(isExistSqlInject("select * from test where sleep(%23)"));
|
||||
assertTrue(isExistSqlInject("select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));"));
|
||||
assertTrue(isExistSqlInject("select * from users;show databases;"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where id=1 and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13"));
|
||||
assertTrue(isExistSqlInject("update user set name = '123'"));
|
||||
assertTrue(isExistSqlInject("SELECT * FROM users WHERE username = 'admin' AND password = '123456' OR 1=1;--"));
|
||||
assertTrue(isExistSqlInject("select * from users where id=1 and (select count(*) from information_schema.tables where table_schema='数据库名')>4 %23"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where sleep(5) %23"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where id in (select id from other)"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where id in (select id from other)"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where 2=2.0 or 2 != 4"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where 1!=2.0"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where id=floor(2.0)"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where not true"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where 1 or id > 0"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where 'tom' or id > 0"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where '-2.3' "));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where 2 "));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where (3+2) "));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where -1 IS TRUE"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where 'hello' is null "));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where '2022-10-31' and id > 0"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where id > 0 or 1!=2.0 "));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where id > 0 or 1 in (1,3,4) "));
|
||||
assertTrue(isExistSqlInject("select * from dc_device UNION select name from other"));
|
||||
assertTrue(isExistSqlInject("(SELECT 6240 FROM (SELECT(SLEEP(5))and 1=2)vidl)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
package org.jeecg.test.sqlinjection;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import org.jeecg.common.util.SqlInjectionUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
* SQL注入攻击检查测试
|
||||
* @author: liusq
|
||||
* @date: 2023年09月08日
|
||||
*/
|
||||
@Slf4j
|
||||
public class TestSqlInjectForDict {
|
||||
/**
|
||||
* 注入测试
|
||||
*
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
private boolean isExistSqlInject(String sql) {
|
||||
try {
|
||||
SqlInjectionUtil.specialFilterContentForDictSql(sql);
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.info("===================================================");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test() throws JSQLParserException {
|
||||
//不存在sql注入
|
||||
assertFalse(isExistSqlInject("sys_user,realname,id"));
|
||||
assertFalse(isExistSqlInject("oa_officialdoc_organcode,organ_name,id"));
|
||||
assertFalse(isExistSqlInject("onl_cgform_head where table_type!=3 and copy_type=0,table_txt,table_name"));
|
||||
assertFalse(isExistSqlInject("onl_cgform_head where copy_type = 0,table_txt,table_name"));
|
||||
|
||||
//存在sql注入
|
||||
assertTrue(isExistSqlInject("or 1= 1 --"));
|
||||
assertTrue(isExistSqlInject("select * from test where sleep(%23)"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
package org.jeecg.test.sqlinjection;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import org.jeecg.common.util.SqlInjectionUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
* SQL注入攻击检查测试
|
||||
* @author: liusq
|
||||
* @date: 2023年09月08日
|
||||
*/
|
||||
@Slf4j
|
||||
public class TestSqlInjectForOnlineReport {
|
||||
/**
|
||||
* 注入测试
|
||||
*
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
private boolean isExistSqlInject(String sql) {
|
||||
try {
|
||||
SqlInjectionUtil.specialFilterContentForOnlineReport(sql);
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.info("===================================================");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test() throws JSQLParserException {
|
||||
//不存在sql注入
|
||||
assertFalse(isExistSqlInject("select * from fm_time where dept_id=:sqlparamsmap.id and time=:sqlparamsmap.time"));
|
||||
assertFalse(isExistSqlInject("select * from test"));
|
||||
assertFalse(isExistSqlInject("select load_file(\"C:\\\\benben.txt\")"));
|
||||
assertFalse(isExistSqlInject("select * from dc_device where id in (select id from other)"));
|
||||
assertFalse(isExistSqlInject("select * from dc_device UNION select name from other"));
|
||||
|
||||
//存在sql注入
|
||||
assertTrue(isExistSqlInject("(SELECT 6240 FROM (SELECT(SLEEP(5))and 1=2)vidl)"));
|
||||
assertTrue(isExistSqlInject("or 1= 1 --"));
|
||||
assertTrue(isExistSqlInject("select * from test where sleep(%23)"));
|
||||
assertTrue(isExistSqlInject("select * from test where SLEEP(3)"));
|
||||
assertTrue(isExistSqlInject("select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));"));
|
||||
assertTrue(isExistSqlInject("select * from users;show databases;"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where id=1 and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13"));
|
||||
assertTrue(isExistSqlInject("update user set name = '123'"));
|
||||
assertTrue(isExistSqlInject("SELECT * FROM users WHERE username = 'admin' AND password = '123456' OR 1=1;--"));
|
||||
assertTrue(isExistSqlInject("select * from users where id=1 and (select count(*) from information_schema.tables where table_schema='数据库名')>4 %23"));
|
||||
assertTrue(isExistSqlInject("select * from dc_device where sleep(5) %23"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
package org.jeecg.test.sqlinjection;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils;
|
||||
import org.jeecg.common.util.SqlInjectionUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Description: SQL注入测试类
|
||||
* @author: scott
|
||||
* @date: 2023年08月14日 9:55
|
||||
*/
|
||||
public class TestSqlInjection {
|
||||
|
||||
|
||||
/**
|
||||
* 表名带别名,同时有html编码字符
|
||||
*/
|
||||
@Test
|
||||
public void testSpecialSQL() {
|
||||
String tableName = "sys_user t";
|
||||
//解决使用参数tableName=sys_user t&复测,漏洞仍然存在
|
||||
if (tableName.contains(" ")) {
|
||||
tableName = tableName.substring(0, tableName.indexOf(" "));
|
||||
}
|
||||
//【issues/4393】 sys_user , (sys_user), sys_user%20, %60sys_user%60
|
||||
String reg = "\\s+|\\(|\\)|`";
|
||||
tableName = tableName.replaceAll(reg, "");
|
||||
System.out.println(tableName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 测试sql是否含sql注入风险
|
||||
* <p>
|
||||
* mybatis plus的方法
|
||||
*/
|
||||
@Test
|
||||
public void sqlInjectionCheck() {
|
||||
String sql = "select * from sys_user";
|
||||
System.out.println(SqlInjectionUtils.check(sql));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 测试sql是否有SLEEP风险
|
||||
* <p>
|
||||
* mybatisPlus的方法
|
||||
*/
|
||||
@Test
|
||||
public void sqlSleepCheck() {
|
||||
SqlInjectionUtil.checkSqlAnnotation("(SELECT 6240 FROM (SELECT(SLEEP(5))and 1=2)vidl)");
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试sql是否含sql注入风险
|
||||
* <p>
|
||||
* 自定义方法
|
||||
*/
|
||||
@Test
|
||||
public void sqlInjectionCheck2() {
|
||||
String sql = "select * from sys_user";
|
||||
SqlInjectionUtil.specialFilterContentForOnlineReport(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段定义只能是是字母 数字 下划线的组合(不允许有空格、转义字符串等)
|
||||
* <p>
|
||||
* 判断字段名是否符合规范
|
||||
*/
|
||||
@Test
|
||||
public void testFieldSpecification() {
|
||||
List<String> list = new ArrayList();
|
||||
list.add("Hello World!");
|
||||
list.add("Hello%20World!");
|
||||
list.add("HelloWorld!");
|
||||
list.add("Hello World");
|
||||
list.add("age");
|
||||
list.add("user_name");
|
||||
list.add("user_name%20");
|
||||
list.add("user_name%20 ");
|
||||
|
||||
for (String input : list) {
|
||||
boolean containsSpecialChars = isValidString(input);
|
||||
System.out.println("input:" + input + " ,包含空格和特殊字符: " + containsSpecialChars);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段定义只能是是字母 数字 下划线的组合(不允许有空格、转义字符串等)
|
||||
*
|
||||
* @param input
|
||||
* @return
|
||||
*/
|
||||
private static boolean isValidString(String input) {
|
||||
Pattern pattern = Pattern.compile("^[a-zA-Z0-9_]+$");
|
||||
return pattern.matcher(input).matches();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
package org.jeecg.test.sqlparse;
|
||||
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.common.util.sqlparse.JSqlParserUtils;
|
||||
import org.jeecg.common.util.sqlparse.vo.SelectSqlInfo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 针对 JSqlParserUtils 的单元测试
|
||||
*/
|
||||
public class JSqlParserUtilsTest {
|
||||
|
||||
private static final String[] sqlList = new String[]{
|
||||
"select * from sys_user",
|
||||
"select u.* from sys_user u",
|
||||
"select u.*, c.name from sys_user u, demo c",
|
||||
"select u.age, c.name from sys_user u, demo c",
|
||||
"select sex, age, c.name from sys_user, demo c",
|
||||
// 别名测试
|
||||
"select username as realname from sys_user",
|
||||
"select username as realname, u.realname as aaa, u.id bbb from sys_user u",
|
||||
// 不存在真实地查询字段
|
||||
"select count(1) from sys_user",
|
||||
// 函数式字段
|
||||
"select max(sex), id from sys_user",
|
||||
// 复杂嵌套函数式字段
|
||||
"select CONCAT(CONCAT(' _ ', sex), ' - ' , birthday) as info, id from sys_user",
|
||||
// 更复杂的嵌套函数式字段
|
||||
"select CONCAT(CONCAT(101,'_',NULL, DATE(create_time),'_',sex),' - ',birthday) as info, id from sys_user",
|
||||
// 子查询SQL
|
||||
"select u.name1 as name2 from (select username as name1 from sys_user) u",
|
||||
// 多层嵌套子查询SQL
|
||||
"select u2.name2 as name3 from (select u1.name1 as name2 from (select username as name1 from sys_user) u1) u2",
|
||||
// 字段子查询SQL
|
||||
"select id, (select username as name1 from sys_user u2 where u1.id = u2.id) as name2 from sys_user u1",
|
||||
// 带条件的SQL(不解析where条件里的字段,但不影响解析查询字段)
|
||||
"select username as name1 from sys_user where realname LIKE '%张%'",
|
||||
// 多重复杂关联表查询解析,包含的表为:sys_user, sys_depart, sys_dict_item, demo
|
||||
"" +
|
||||
"SELECT " +
|
||||
" u.*, d.age, sd.item_text AS sex, (SELECT count(sd.id) FROM sys_depart sd) AS count " +
|
||||
"FROM " +
|
||||
" (SELECT sd.username AS foo, sd.realname FROM sys_user sd) u, " +
|
||||
" demo d " +
|
||||
"LEFT JOIN sys_dict_item AS sd ON d.sex = sd.item_value " +
|
||||
"WHERE sd.dict_id = '3d9a351be3436fbefb1307d4cfb49bf2'",
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testParseSelectSql() {
|
||||
System.out.println("-----------------------------------------");
|
||||
for (String sql : sqlList) {
|
||||
System.out.println("待测试的sql:" + sql);
|
||||
try {
|
||||
// 解析所有的表名,key=表名,value=解析后的sql信息
|
||||
Map<String, SelectSqlInfo> parsedMap = JSqlParserUtils.parseAllSelectTable(sql);
|
||||
assert parsedMap != null;
|
||||
for (Map.Entry<String, SelectSqlInfo> entry : parsedMap.entrySet()) {
|
||||
System.out.println("表名:" + entry.getKey());
|
||||
this.printSqlInfo(entry.getValue(), 1);
|
||||
}
|
||||
} catch (JSQLParserException e) {
|
||||
System.out.println("SQL解析出现异常:" + e.getMessage());
|
||||
}
|
||||
System.out.println("-----------------------------------------");
|
||||
}
|
||||
}
|
||||
|
||||
private void printSqlInfo(SelectSqlInfo sqlInfo, int level) {
|
||||
String beforeStr = this.getBeforeStr(level);
|
||||
if (sqlInfo.getFromTableName() == null) {
|
||||
// 子查询
|
||||
System.out.println(beforeStr + "子查询:" + sqlInfo.getFromSubSelect().getParsedSql());
|
||||
this.printSqlInfo(sqlInfo.getFromSubSelect(), level + 1);
|
||||
} else {
|
||||
// 非子查询
|
||||
System.out.println(beforeStr + "查询的表名:" + sqlInfo.getFromTableName());
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(sqlInfo.getFromTableAliasName())) {
|
||||
System.out.println(beforeStr + "查询的表别名:" + sqlInfo.getFromTableAliasName());
|
||||
}
|
||||
if (sqlInfo.isSelectAll()) {
|
||||
System.out.println(beforeStr + "查询的字段:*");
|
||||
} else {
|
||||
System.out.println(beforeStr + "查询的字段:" + sqlInfo.getSelectFields());
|
||||
System.out.println(beforeStr + "真实的字段:" + sqlInfo.getRealSelectFields());
|
||||
if (sqlInfo.getFromTableName() == null) {
|
||||
System.out.println(beforeStr + "所有的字段(包括子查询):" + sqlInfo.getAllRealSelectFields());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 打印前缀,根据层级来打印
|
||||
private String getBeforeStr(int level) {
|
||||
if (level == 0) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder beforeStr = new StringBuilder();
|
||||
for (int i = 0; i < level; i++) {
|
||||
beforeStr.append(" ");
|
||||
}
|
||||
beforeStr.append("- ");
|
||||
return beforeStr.toString();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue