A high-performance JDBC connection pool and database monitoring library with SQL parsing and security features
—
Advanced SQL injection protection and security filtering system with configurable policies, database-specific rules, and comprehensive validation capabilities through the WallFilter framework.
// Main security filter class
class WallFilter extends FilterAdapter implements WallFilterMBean {
// Constructors
public WallFilter();
public WallFilter(Properties properties);
// Configuration
public void configFromProperties(Properties properties);
public synchronized void init(DataSourceProxy dataSource);
// Security behavior
public boolean isLogViolation();
public void setLogViolation(boolean logViolation);
public boolean isThrowException();
public void setThrowException(boolean throwException);
public String getDbType();
public void setDbType(String dbType);
public void setDbType(DbType dbType);
// Provider and configuration access
public WallProvider getProvider();
public WallConfig getConfig();
public void setConfig(WallConfig config);
// SQL validation
public String check(String sql) throws SQLException;
public boolean checkValid(String sql);
// Statistics and management
public long getViolationCount();
public void resetViolationCount();
public void clearProviderCache();
public Set<String> getProviderWhiteList();
public void clearWhiteList();
}// Security configuration class
class WallConfig implements WallConfigMBean {
// Statement type controls
public boolean isSelectAllow();
public void setSelectAllow(boolean selectAllow);
public boolean isInsertAllow();
public void setInsertAllow(boolean insertAllow);
public boolean isUpdateAllow();
public void setUpdateAllow(boolean updateAllow);
public boolean isDeleteAllow();
public void setDeleteAllow(boolean deleteAllow);
// DDL controls
public boolean isCreateTableAllow();
public void setCreateTableAllow(boolean createTableAllow);
public boolean isDropTableAllow();
public void setDropTableAllow(boolean dropTableAllow);
public boolean isAlterTableAllow();
public void setAlterTableAllow(boolean alterTableAllow);
public boolean isTruncateAllow();
public void setTruncateAllow(boolean truncateAllow);
// Security checks
public boolean isSelectWhereAlwayTrueCheck();
public void setSelectWhereAlwayTrueCheck(boolean selectWhereAlwayTrueCheck);
public boolean isUpdateWhereAlwayTrueCheck();
public void setUpdateWhereAlwayTrueCheck(boolean updateWhereAlwayTrueCheck);
public boolean isDeleteWhereAlwayTrueCheck();
public void setDeleteWhereAlwayTrueCheck(boolean deleteWhereAlwayTrueCheck);
// Syntax and features
public boolean isCommentAllow();
public void setCommentAllow(boolean commentAllow);
public boolean isMultiStatementAllow();
public void setMultiStatementAllow(boolean multiStatementAllow);
public boolean isStrictSyntaxCheck();
public void setStrictSyntaxCheck(boolean strictSyntaxCheck);
// Access controls
public Set<String> getDenyFunctions();
public Set<String> getDenyTables();
public Set<String> getDenySchemas();
public Set<String> getPermitFunctions();
public Set<String> getPermitTables();
public Set<String> getReadOnlyTables();
// Advanced features
public boolean isMustParameterized();
public void setMustParameterized(boolean mustParameterized);
public int getSelectLimit();
public void setSelectLimit(int selectLimit);
public void configFromProperties(Properties properties);
}import com.alibaba.druid.wall.WallFilter;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.pool.DruidDataSource;
// Create and configure WallFilter
WallFilter wallFilter = new WallFilter();
wallFilter.setDbType("mysql");
wallFilter.setLogViolation(true);
wallFilter.setThrowException(true);
// Configure security policies
WallConfig config = new WallConfig();
config.setMultiStatementAllow(false);
config.setSelectWhereAlwayTrueCheck(true);
config.setUpdateWhereAlwayTrueCheck(true);
config.setDeleteWhereAlwayTrueCheck(true);
config.setCommentAllow(false);
wallFilter.setConfig(config);
// Integrate with DataSource
DruidDataSource dataSource = new DruidDataSource();
dataSource.getProxyFilters().add(wallFilter);
// or via filters string
dataSource.setFilters("wall");// Configure via Properties
Properties config = new Properties();
config.setProperty("druid.wall.logViolation", "true");
config.setProperty("druid.wall.throwException", "true");
config.setProperty("druid.wall.selectAllow", "true");
config.setProperty("druid.wall.updateAllow", "true");
config.setProperty("druid.wall.deleteAllow", "true");
config.setProperty("druid.wall.insertAllow", "true");
config.setProperty("druid.wall.multiStatementAllow", "false");
config.setProperty("druid.wall.selectLimit", "1000");
WallFilter wallFilter = new WallFilter(config);WallConfig config = new WallConfig();
// Basic DML controls
config.setSelectAllow(true); // Allow SELECT statements
config.setInsertAllow(true); // Allow INSERT statements
config.setUpdateAllow(true); // Allow UPDATE statements
config.setDeleteAllow(false); // Deny DELETE statements
// DDL controls
config.setCreateTableAllow(false); // Deny CREATE TABLE
config.setDropTableAllow(false); // Deny DROP TABLE
config.setAlterTableAllow(false); // Deny ALTER TABLE
config.setTruncateAllow(false); // Deny TRUNCATE
// Apply configuration
wallFilter.setConfig(config);// Configure injection protection checks
config.setSelectWhereAlwayTrueCheck(true); // Detect "WHERE 1=1" patterns
config.setUpdateWhereAlwayTrueCheck(true); // Detect unsafe UPDATE conditions
config.setDeleteWhereAlwayTrueCheck(true); // Detect unsafe DELETE conditions
// Union and set operation controls
config.setSelectUnionCheck(true); // Check UNION operations
config.setMinusAllow(false); // Deny MINUS operations
config.setIntersectAllow(true); // Allow INTERSECT operations
// Syntax and structure controls
config.setStrictSyntaxCheck(true); // Enable strict syntax validation
config.setMultiStatementAllow(false); // Deny multiple statements
config.setCommentAllow(false); // Deny SQL comments// Function blacklist/whitelist
Set<String> denyFunctions = config.getDenyFunctions();
denyFunctions.add("version");
denyFunctions.add("database");
denyFunctions.add("user");
denyFunctions.add("benchmark");
denyFunctions.add("sleep");
// Table access controls
Set<String> denyTables = config.getDenyTables();
denyTables.add("sys");
denyTables.add("information_schema");
Set<String> readOnlyTables = config.getReadOnlyTables();
readOnlyTables.add("users");
readOnlyTables.add("audit_log");
// Schema restrictions
Set<String> denySchemas = config.getDenySchemas();
denySchemas.add("mysql");
denySchemas.add("performance_schema");// Base provider interface
abstract class WallProvider {
public WallCheckResult check(String sql);
public boolean checkValid(String sql);
public WallConfig getConfig();
// Statistics and management
public long getCheckCount();
public long getViolationCount();
public long getWhiteListHitCount();
public long getBlackListHitCount();
public void clearCache();
public void clearWhiteList();
public Set<String> getWhiteList();
public Set<String> getBlackList();
// Security checks
public boolean checkDenyFunction(String functionName);
public boolean checkDenySchema(String schemaName);
public boolean checkDenyTable(String tableName);
public boolean checkReadOnlyTable(String tableName);
}// MySQL-specific security
WallFilter mysqlWall = new WallFilter();
mysqlWall.setDbType(DbType.mysql);
// Uses MySqlWallProvider with MySQL-specific rules
// Oracle-specific security
WallFilter oracleWall = new WallFilter();
oracleWall.setDbType(DbType.oracle);
// Uses OracleWallProvider with Oracle-specific rules
// PostgreSQL-specific security
WallFilter pgWall = new WallFilter();
pgWall.setDbType(DbType.postgresql);
// Uses PGWallProvider with PostgreSQL-specific rules// Validation utility methods
class WallUtils {
// MySQL validation
static boolean isValidateMySql(String sql);
static boolean isValidateMySql(String sql, WallConfig config);
// Oracle validation
static boolean isValidateOracle(String sql);
static boolean isValidateOracle(String sql, WallConfig config);
// PostgreSQL validation
static boolean isValidatePostgres(String sql);
static boolean isValidatePostgres(String sql, WallConfig config);
// SQL Server validation
static boolean isValidateSqlServer(String sql);
static boolean isValidateSqlServer(String sql, WallConfig config);
// DB2 validation
static boolean isValidateDB2(String sql);
static boolean isValidateDB2(String sql, WallConfig config);
}import com.alibaba.druid.wall.WallUtils;
import com.alibaba.druid.wall.WallConfig;
// Basic validation
boolean valid = WallUtils.isValidateMySql("SELECT * FROM users WHERE id = ?");
// Returns: true (parameterized query is safe)
boolean invalid = WallUtils.isValidateMySql("SELECT * FROM users WHERE 1=1");
// Returns: false (always true condition detected)
// Custom configuration validation
WallConfig config = new WallConfig();
config.setSelectAllow(true);
config.setMultiStatementAllow(false);
config.setSelectWhereAlwayTrueCheck(true);
boolean result = WallUtils.isValidateMySql(
"SELECT * FROM users; DROP TABLE users;", config);
// Returns: false (multiple statements not allowed)// Security validation result
class WallCheckResult {
public String getSql();
public List<Violation> getViolations();
public List<SQLStatement> getStatementList();
public boolean isSyntaxError();
// Statistics
public Map<String, WallSqlTableStat> getTableStats();
public Map<String, WallSqlFunctionStat> getFunctionStats();
public WallSqlStat getSqlStat();
}// Multi-tenant configuration
void setTenantColumn(String tenantColumn);
String getTenantColumn();
void setTenantTablePattern(String tenantTablePattern);
String getTenantTablePattern();
void setTenantCallBack(TenantCallBack tenantCallBack);
TenantCallBack getTenantCallBack();// Configure multi-tenant security
WallConfig config = new WallConfig();
config.setTenantColumn("tenant_id");
config.setTenantTablePattern(".*"); // Apply to all tables
// Custom tenant callback
config.setTenantCallBack(new TenantCallBack() {
@Override
public String getTenantValue() {
// Return current tenant ID from context
return getCurrentTenantId();
}
});
wallFilter.setConfig(config);// Configure update validation
WallConfig config = new WallConfig();
config.addUpdateCheckColumns("users.email,users.phone");
config.addUpdateCheckColumns("orders.status");
// Custom update check handler
config.setUpdateCheckHandler(new WallUpdateCheckHandler() {
@Override
public void checkUpdate(WallUpdateCheckItem item) throws SQLException {
// Custom validation logic
if (item.getColumn().equals("email")) {
validateEmailUpdate(item);
}
}
});// Main security exception
class WallSQLException extends SQLException {
public WallSQLException(String reason);
public WallSQLException(String reason, Throwable cause);
}
// Violation types
interface Violation {
String getMessage();
int getErrorCode();
}
class IllegalSQLObjectViolation implements Violation {
public String getMessage();
public int getErrorCode();
}// Common error codes
public interface ErrorCode {
int SYNTAX_ERROR = 1001; // SQL syntax errors
int SELECT_NOT_ALLOW = 1002; // SELECT not allowed
int INSERT_NOT_ALLOW = 1004; // INSERT not allowed
int DELETE_NOT_ALLOW = 1005; // DELETE not allowed
int UPDATE_NOT_ALLOW = 1006; // UPDATE not allowed
int FUNCTION_DENY = 2001; // Denied function
int SCHEMA_DENY = 2002; // Denied schema
int TABLE_DENY = 2004; // Denied table
int ALWAYS_TRUE = 2100; // Always true condition
int MULTI_STATEMENT = 2201; // Multiple statements
}
// Exception handling example
try {
Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
// ... execute statement
} catch (WallSQLException e) {
int errorCode = e.getErrorCode();
switch (errorCode) {
case ErrorCode.ALWAYS_TRUE:
log.warn("SQL injection attempt detected: " + e.getMessage());
break;
case ErrorCode.FUNCTION_DENY:
log.warn("Unauthorized function usage: " + e.getMessage());
break;
default:
log.error("Security violation: " + e.getMessage());
}
}// Access security statistics
WallFilter wallFilter = getWallFilter();
long violationCount = wallFilter.getViolationCount();
long checkCount = wallFilter.getProvider().getCheckCount();
long whiteListHits = wallFilter.getProvider().getWhiteListHitCount();
long blackListHits = wallFilter.getProvider().getBlackListHitCount();
// Table and function statistics
Map<String, WallTableStat> tableStats = wallFilter.getProvider().getTableStats();
Map<String, WallFunctionStat> functionStats = wallFilter.getProvider().getFunctionStats();
// Reset statistics
wallFilter.resetViolationCount();
wallFilter.getProvider().reset();// Cache operations
Set<String> whiteList = wallFilter.getProvider().getWhiteList();
Set<String> blackList = wallFilter.getProvider().getBlackList();
// Clear caches
wallFilter.clearProviderCache();
wallFilter.getProvider().clearWhiteList();
wallFilter.getProvider().clearBlackList();
wallFilter.getProvider().clearCache();import com.alibaba.druid.wall.WallFilter;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.DbType;
public class DruidSecurityConfiguration {
public static DruidDataSource createSecureDataSource() {
// Create DataSource
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("dbuser");
dataSource.setPassword("dbpass");
// Create WallFilter
WallFilter wallFilter = new WallFilter();
wallFilter.setDbType(DbType.mysql);
wallFilter.setLogViolation(true);
wallFilter.setThrowException(true);
// Configure security policies
WallConfig config = new WallConfig();
// Statement controls
config.setSelectAllow(true);
config.setInsertAllow(true);
config.setUpdateAllow(true);
config.setDeleteAllow(true);
config.setCreateTableAllow(false); // Deny DDL
config.setDropTableAllow(false);
config.setAlterTableAllow(false);
// Injection protection
config.setSelectWhereAlwayTrueCheck(true);
config.setUpdateWhereAlwayTrueCheck(true);
config.setDeleteWhereAlwayTrueCheck(true);
config.setMultiStatementAllow(false);
config.setCommentAllow(false);
config.setStrictSyntaxCheck(true);
// Function restrictions
config.getDenyFunctions().addAll(Arrays.asList(
"version", "database", "user", "benchmark", "sleep", "load_file"
));
// Table restrictions
config.getDenyTables().addAll(Arrays.asList(
"information_schema", "mysql", "performance_schema", "sys"
));
// Read-only tables
config.getReadOnlyTables().addAll(Arrays.asList(
"audit_log", "system_config"
));
// Advanced features
config.setSelectLimit(10000); // Limit result set size
config.setMustParameterized(true); // Require parameterized queries
wallFilter.setConfig(config);
// Add filter to DataSource
dataSource.getProxyFilters().add(wallFilter);
return dataSource;
}
}This comprehensive security framework provides enterprise-grade SQL injection protection through configurable policies, database-specific rules, access controls, and detailed monitoring capabilities.
Install with Tessl CLI
npx tessl i tessl/maven-com-alibaba--druid