dromara/Sa-Token · error · RequestPathInvalidException

请求 path 包含禁止字符 %:{requestPath}

Error message

请求 path 包含禁止字符 %:{requestPath}

What it means

The second check in SaFirewallCheckHookForPathBannedCharacter: when config bannedPercentage is true (the default), any '%' character in the request path throws RequestPathInvalidException. Percent-encoding attacks (%2e%2e for '..') bypass naive path checks, so sa-token blocks raw percent signs in paths by default. Legitimately encoded path segments therefore fail this check.

Source

Thrown at sa-token-core/src/main/java/cn/dev33/satoken/strategy/hooks/SaFirewallCheckHookForPathBannedCharacter.java:64

        this.bannedPercentage = bannedPercentage;
    }

    /**
     * 执行的方法
     *
     * @param req 请求对象
     * @param res 响应对象
     * @param extArg 预留扩展参数
     */
    @Override
    public void execute(SaRequest req, SaResponse res, Object extArg) {
        // 非可打印 ASCII 字符检查
        String requestPath = req.getRequestPath();
        if(SaFoxUtil.hasNonPrintableASCII(requestPath)) {
            throw new RequestPathInvalidException("请求 path 包含禁止字符:" + requestPath, requestPath);
        }
        if(bannedPercentage && requestPath.contains("%")) {
            throw new RequestPathInvalidException("请求 path 包含禁止字符 %:" + requestPath, requestPath);
        }
    }

}

View on GitHub (pinned to ac2c7f6e94)

Solutions

  1. If your API legitimately uses encoded path segments, disable it: sa-token.firewall.banned-percentage=false
  2. Prefer query parameters (?name=a%20b) over encoded path segments for user-supplied data
  3. Normalize/decode URLs at the gateway so the app sees decoded paths without '%'

Example fix

# before
sa-token:
  firewall:
    banned-percentage: true  # default; /files/a%20b.pdf blocked

# after
sa-token:
  firewall:
    banned-percentage: false
Defensive patterns

Strategy: validation

Validate before calling

String path = SaHolder.getRequest().getRequestPath();
boolean banned = SaManager.getConfig().getFirewall().getBannedPercentage();
if (banned && path.contains("%")) {
    // either decode at the gateway, move data to query params, or disable banned-percentage in config
}

Try / catch

try {
    chain.doFilter(req, res);
} catch (RequestPathInvalidException e) {
    res.setStatus(400);
}

Prevention

When it happens

Trigger: A request whose path contains '%', e.g. /files/report%20final.pdf or /search/%E4%B8%AD — i.e. any percent-encoded space, CJK character, or reserved char in the path — while firewall.banned-percentage is not set to false.

Common situations: Serving user-uploaded files with unicode or spaces in names; browsers auto-encoding non-ASCII path segments; enabling the default firewall on an API that already relies on encoded path variables.

Related errors


AI-assisted analysis of dromara/Sa-Token@ac2c7f6e94 (2026-08-14). Data as JSON: /api/errors/db6524965a5dc9e8. Report an issue: GitHub.