Prevenção de Injeção de SQL no Struts2 Utilizando Interceptadores Personalizados

A proteção contra ataques de injeção de SQL em aplicações web desanvolvidas com o framework Struts2 pode ser implementada de forma centralizada através do uso de interceptadores (interceptors). Essa abordagem permite validar e sanitizar os parâmetros de requisição entes que eles alcancem as camadas de controle e persistência.

Para configurar essa validação, é necessário registrar o interceptador personalizado no arquivo de configuração do Struts (struts.xml) e associá-lo a uma pilha de itnerceptadores (interceptor stack).

<interceptors>
    <interceptor name="securityValidator" class="com.app.security.SqlInjectionInterceptor"/>
    <interceptor-stack name="secureStack">
        <interceptor-ref name="securityValidator"/>
        <interceptor-ref name="defaultStack"/>
    </interceptor-stack>
</interceptors>

A implementação do interceptador em Java deve estender AbstractInterceptor para simplificar o ciclo de vida do componente. A lógica principal consiste em verificar a sessão do usuário, extrair os parâmetros da requisição, aplicar decodificação de URL para evitar técnicas de evasão e validar o conteúdo contra uma expressão regular que identifica caracteres especiais potencialmente maliciosos.

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import org.apache.struts2.StrutsStatics;
import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SqlInjectionInterceptor extends AbstractInterceptor {

    private static final long serialVersionUID = 1L;
    
    // Expressão regular para detectar caracteres especiais potencialmente maliciosos
    private static final String SPECIAL_CHARS_REGEX = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:""’。,、?]";
    private static final Pattern THREAT_PATTERN = Pattern.compile(SPECIAL_CHARS_REGEX);

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        // Verifica se o usuário está autenticado
        UserSession currentUser = SecurityContext.getCurrentSession();
        if (currentUser == null) {
            return "login";
        }

        ActionContext context = invocation.getInvocationContext();
        HttpServletRequest httpRequest = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);
        httpRequest.setCharacterEncoding(StandardCharsets.UTF_8.name());

        Map<String, Object> requestParams = context.getParameters();
        boolean isThreatDetected = false;

        for (Map.Entry<String, Object> paramEntry : requestParams.entrySet()) {
            String[] paramValues = (String[]) paramEntry.getValue();
            
            if (paramValues != null && paramValues.length > 0 && paramValues[0] != null && !paramValues[0].trim().isEmpty()) {
                // Dupla decodificação de URL para prevenir técnicas de bypass
                String decodedValue = URLDecoder.decode(paramValues[0], StandardCharsets.UTF_8.name());
                decodedValue = URLDecoder.decode(decodedValue, StandardCharsets.UTF_8.name());
                
                Matcher matcher = THREAT_PATTERN.matcher(decodedValue);
                if (matcher.find()) {
                    isThreatDetected = true;
                    break;
                }
            }
        }

        if (isThreatDetected) {
            // Bloqueia a requisição se caracteres maliciosos forem encontrados
            return "security_error"; 
        }

        // Prossegue com a execução da ação
        return invocation.invoke();
    }
}

Neste exemplo, a expressão regular SPECIAL_CHARS_REGEX atua como uma lista de bloqueio para símbolos comumente utilizados em payloads de injeção. A dupla decodificação (URLDecoder.decode) é uma medida defensiva crucial, pois atacantes frequentemente codificam caracteres maliciosos múltiplas vezes para contornar filtros de segurança superficiais. Caso a validação falhe, a execução da ação é interrompida e o fluxo é redirecionado para um resultado de erro de segurança.

Tags: Struts2 java sql-injection interceptors Web-Security

Publicado em 6-10 05:42 por Thomas