-
Notifications
You must be signed in to change notification settings - Fork 8.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
selectLimit 只在第一条sql 生效 #2649
Comments
你调用的什么API? |
配置druid的wallfilter设置selectLimit,没有调用什么api |
我也看到了 目前看起来似乎是使用了druid的statement缓存 而大部分wallfilter的check是执行check方法或者说checkInternal private WallCheckResult checkInternal(String sql) throws SQLException {
WallCheckResult checkResult = provider.check(sql);
List<Violation> violations = checkResult.getViolations();
if (violations.size() > 0) {
Violation firstViolation = violations.get(0);
if (isLogViolation()) {
LOG.error("sql injection violation, " + firstViolation.getMessage() + " : " + sql);
}
if (throwException) {
if (violations.get(0) instanceof SyntaxErrorViolation) {
SyntaxErrorViolation violation = (SyntaxErrorViolation) violations.get(0);
throw new SQLException("sql injection violation, " + firstViolation.getMessage() + " : " + sql,
violation.getException());
} else {
throw new SQLException("sql injection violation, " + firstViolation.getMessage() + " : " + sql);
}
}
}
return checkResult;
} 而关于check方法封装 public String check(String sql) throws SQLException {
return checkInternal(sql)
.getSql();
} 但是大部分使用的都是预编译 即preparedStatement @Override
public boolean preparedStatement_execute(FilterChain chain, PreparedStatementProxy statement) throws SQLException {
try {
wallUpdateCheck(statement);
boolean firstResult = chain.preparedStatement_execute(statement);
if (!firstResult) {
WallSqlStat sqlStat = (WallSqlStat) statement.getAttribute(ATTR_SQL_STAT);
int updateCount = statement.getUpdateCount();
if (sqlStat != null) {
provider.addUpdateCount(sqlStat, updateCount);
}
}
return firstResult;
} catch (SQLException ex) {
incrementExecuteErrorCount(statement);
throw ex;
}
} 并未调用check方法 |
目前可以看到有更多信息 如果开启了poolPreparedStatements的时候 由于PreparedStatements会被池化缓存 这样将不会触发check 在没有对于PreparedStatement进行check之前 我只能先关闭pool了
|
1.1.10试试看? |
试过了~从1.1.4 测试到了1.1.10 ~ 确实是有问题的
|
遇到了相同的问题,研究了一下,发现在wallprovider里面使用了LRUCache来缓存黑白名单,存入cache的是rewrite之前的SQL,后续从cache里面读取时使用了未被rewrite的SQL。 // first step, check whiteList
boolean mulltiTenant = config.getTenantTablePattern() != null && config.getTenantTablePattern().length() > 0;
if (!mulltiTenant) {
WallCheckResult checkResult = checkWhiteAndBlackList(sql);
if (checkResult != null) {
checkResult.setSql(sql);
return checkResult;
}
} 此处如果能读到缓存,就直接返回缓存内的SQL解析结果,使用了原始SQL。 if ((!updateCheckHandlerEnable) && sql.length() < MAX_SQL_LENGTH) {
sqlStat = addWhiteSql(sql, tableStat, context.getFunctionStats(), syntaxError);
} 而写入时使用的是Rewrite之前的SQL语句,直接无视了Rewrite后的SQL |
druid版本 druid-spring-boot-starter 1.1.4 设置select-limit:5 只有在第一条语句的时候
SELECT id, serviceTypeId, name, description, price
, isDeleted, isRadioOption, serviceSubTypeId, imageUrl, serviceCategoryId
, isPublicVisit, finance_category, star_level, work_type_id, fast_repair
, charge_model_same, maintenance_period, maintenance_miles
FROM ServiceSubItem
WHERE isDeleted = 0
AND serviceTypeId = ?
AND serviceCategoryId = ?
LIMIT 5
第二次就不再limit了
SELECT id, serviceTypeId, name, description, price
, isDeleted, isRadioOption, serviceSubTypeId, imageUrl, serviceCategoryId
, isPublicVisit, finance_category, star_level, work_type_id, fast_repair
, charge_model_same, maintenance_period, maintenance_miles
FROM ServiceSubItem
WHERE isDeleted = 0
AND serviceTypeId = ?
AND serviceCategoryId = ?
The text was updated successfully, but these errors were encountered: