dromara/Sa-Token · error · SaSsoException
CODE_30015
CODE_30015
Error message
无效的 allow-url 配置(*通配符只允许出现在最后一位):{url} What it means
Thrown by checkAllowUrlList at server startup or on first use: an entry in the client's allow-url config has a '*' wildcard somewhere other than the last character. The code comment explains why — a mid-string '*' (e.g. http://*.client1.com/sso/login) lets attacker URLs like http://sa-token.com/a.client1.com/sso/login pass suffix/contains matching, causing ticket hijacking.
Source
Thrown at sa-token-plugin/sa-token-sso/src/main/java/cn/dev33/satoken/sso/template/SaSsoServerTemplate.java:499
// sa-token.sso-server.allow-url=http://*.sa-sso-client1.com
//
// 开发者原意是为了允许 sa-sso-client1.com 下的所有子域名都可以下放ticket
// 例如:http://shop.sa-sso-client1.com
//
// 但是如果攻击者精心构建一个url:
// http://sa-sso-server.com:9000/sso/auth?redirect=http://sa-token.com/a.sa-sso-client1.com/sso/login
//
// 那么这个 url 就会绕过 allow-url 的校验,ticket 被下发到了第三方服务器地址:
// http://sa-token.com/a.sa-sso-client1.com/sso/login?ticket=v2KKMUFK7dDsMMzXLQ3aWGsyGUjrA0dBB2jeOWrpCnC8b5ScmXXQSv20mIwPK7Cx
//
// 造成了 ticket 参数劫持
// 所以此处需要禁止 allow-url 配置项的中间位置出现 * 字符(出现在末尾是没有问题的)
//
// 这么一刀切的做法,可能会导致正常场景下的子域名url也无法通过校验,例如:
// http://sa-sso-server.com:9000/sso/auth?redirect=http://shop.sa-sso-client1.com/sso/login
//
// 但是为了安全起见,这么做还是有必要的
throw new SaSsoException("无效的 allow-url 配置(*通配符只允许出现在最后一位):" + url).setCode(SaSsoErrorCode.CODE_30015);
}
}
}
// ------------------- 单点注销 -------------------
/**
* 为指定账号 id 注册应用接入信息(模式三)
*
* @param loginId 账号id
* @param client 指定客户端标识,可为null
* @param sloCallbackUrl 单点注销时的回调URL
*/
public void registerSloCallbackUrl(Object loginId, String client, String sloCallbackUrl) {
// 如果提供的参数是空值,则直接返回,不进行任何操作
if(SaFoxUtil.isEmpty(loginId)) {
return;View on GitHub (pinned to ac2c7f6e94)
Solutions
- Use the wildcard only as a trailing suffix, e.g. http://example.com/* — subdomain-level wildcards are intentionally not supported
- List each concrete subdomain explicitly: http://shop.example.com/sso/login,http://api.example.com/sso/login
- If many subdomains are needed, front them with one shared callback host and route internally
Example fix
# before allow-url: http://*.example.com/sso/login # CODE_30015 # after allow-url: http://shop.example.com/sso/login,http://api.example.com/sso/login
Defensive patterns
Strategy: validation
Validate before calling
for(String u : allowUrlList) {
int i = u.indexOf('*');
if(i != -1 && i != u.length() - 1) {
// fix config before server starts rejecting it
}
} Prevention
- Validate allow-url entries in CI with a config lint step
- Remember: wildcards are suffix-only by design; enumerate subdomains explicitly
When it happens
Trigger: Configuring allow-url: http://*.example.com/sso/login (leading or middle '*') on the sso-server; the check iterates every entry and rejects the offending one.
Common situations: Admin tries to whitelist all subdomains with a leading-star pattern and hits this deliberate restriction; migrating from an older sa-token that did not validate this.
Related errors
AI-assisted analysis of dromara/Sa-Token@ac2c7f6e94 (2026-08-14).
Data as JSON: /api/errors/8f46cd58ed16f3a9.
Report an issue: GitHub.