You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web应用SQL异常时如何隐藏数据库详情?Struts框架适配方案问询

Solution to Mask Sensitive DB Details in Struts SQL Error Messages

Got it, let's work through this problem where your Struts app is exposing sensitive database details (like schema names, constraint names) in SQL error messages during white hat security scans. Since you're already using ActionErrors and ActionError, we can build on that setup to mask those sensitive bits while keeping useful, user-friendly feedback.

Here's a step-by-step refined solution:

1. Create a Custom Exception Handler

First, build a centralized exception handler to intercept SQL-related exceptions, strip sensitive details, and map errors to generic, safe messages. This replaces the default Struts exception handling that dumps raw error info.

import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ExceptionHandler;
import org.apache.struts.config.ExceptionConfig;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SensitiveSqlExceptionHandler extends ExceptionHandler {

    @Override
    public ActionForward execute(Exception ex, ExceptionConfig config,
                                 ActionMapping mapping, org.apache.struts.action.ActionForm form,
                                 HttpServletRequest request, HttpServletResponse response) throws Exception {

        String userFriendlyMessage = "操作失败,请稍后重试";
        if (ex instanceof SQLException) {
            String rawError = ex.getMessage();
            // Extract the core Oracle error code (e.g., ORA-00001)
            Pattern oraPattern = Pattern.compile("ORA-(\\d+):");
            Matcher matcher = oraPattern.matcher(rawError);
            
            if (matcher.find()) {
                String errorCode = matcher.group(1);
                // Map specific error codes to user-friendly messages
                switch (errorCode) {
                    case "00001":
                        userFriendlyMessage = "数据重复,无法完成此操作";
                        break;
                    case "01400":
                        userFriendlyMessage = "必填字段不能为空,请检查输入";
                        break;
                    case "02291":
                        userFriendlyMessage = "关联数据不存在,请确认输入信息";
                        break;
                    // Add more common error codes as needed
                    default:
                        userFriendlyMessage = "数据库操作异常,请联系管理员";
                }
            }
        }

        // Add the sanitized message to ActionErrors
        ActionErrors errors = new ActionErrors();
        errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.global", userFriendlyMessage));
        saveErrors(request, errors);

        // Redirect to the input page or error page (configure in struts-config)
        return mapping.getInputForward();
    }
}

2. Configure Struts to Use the Custom Handler

Update your struts-config.xml to register the custom handler for SQL exceptions, so all such errors go through our sanitization logic:

<struts-config>
    <!-- ... other configs ... -->
    <global-exceptions>
        <exception
            type="java.sql.SQLException"
            handler="com.yourpackage.SensitiveSqlExceptionHandler"
            path="/your-input-page.jsp"/>
        <!-- Add other DB-specific exceptions if needed (e.g., OracleSQLException) -->
    </global-exceptions>
</struts-config>

3. Refine Action-Level Error Handling

If you're manually catching exceptions in your Actions (instead of relying on global handling), replace direct raw error message usage with a centralized message mapper:

First, create a utility class for consistent mapping:

import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ErrorMessageMapper {
    public static String getFriendlySqlMessage(SQLException ex) {
        String rawError = ex.getMessage();
        Pattern oraPattern = Pattern.compile("ORA-(\\d+):");
        Matcher matcher = oraPattern.matcher(rawError);
        
        if (matcher.find()) {
            switch (matcher.group(1)) {
                case "00001":
                    return "数据重复,无法完成操作";
                case "01400":
                    return "必填字段不能为空";
                // Add more mappings
                default:
                    return "数据库操作异常,请联系管理员";
            }
        }
        return "操作失败,请稍后重试";
    }
}

Then use it in your Action:

public ActionForward update(ActionMapping mapping, ActionForm form,
                            HttpServletRequest request, HttpServletResponse response) throws Exception {
    try {
        // Your database update logic here
    } catch (SQLException ex) {
        String safeMessage = ErrorMessageMapper.getFriendlySqlMessage(ex);
        ActionErrors errors = new ActionErrors();
        errors.add("updateError", new ActionError("error.update.failed", safeMessage));
        saveErrors(request, errors);
        return mapping.getInputForward();
    }
}

4. Secure Logging (Critical for Security)

Even if users don't see raw errors, ensure your logs don't expose sensitive DB details. Log only the error code and stack trace (without raw message content):

import org.apache.log4j.Logger;

public class YourAction {
    private static final Logger logger = Logger.getLogger(YourAction.class);

    public ActionForward update(...) throws Exception {
        try {
            // DB logic
        } catch (SQLException ex) {
            // Extract error code for logging
            String errorCode = extractOraErrorCode(ex);
            logger.error("Database operation failed with code: " + errorCode, ex);
            // Proceed to add sanitized message to ActionErrors
        }
    }

    private String extractOraErrorCode(SQLException ex) {
        Matcher matcher = Pattern.compile("ORA-(\\d+):").matcher(ex.getMessage());
        return matcher.find() ? matcher.group(1) : "unknown";
    }
}

5. Test Thoroughly

Trigger various SQL exceptions (unique constraint violation, foreign key failure, null value violation) to verify:

  • Frontend shows only sanitized, user-friendly messages
  • No sensitive DB details (schema names, constraint names) are exposed anywhere
  • All edge cases are covered by your error code mappings

内容的提问来源于stack exchange,提问作者user7491136

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:54:03