mirror of
https://gitee.com/kekingcn/file-online-preview.git
synced 2026-03-13 20:53:47 +08:00
fix(security): enforce whitelist with blacklist and harden wildcard rules
This commit is contained in:
@@ -146,11 +146,15 @@ trust.host = *
|
||||
|
||||
### Q4: 如何允许子域名?
|
||||
|
||||
目前不支持通配符域名匹配,需要明确列出每个子域名:
|
||||
已支持通配符域名匹配,可使用 `*.example.com`:
|
||||
```properties
|
||||
trust.host = cdn.example.com,api.example.com,storage.example.com
|
||||
trust.host = *.example.com
|
||||
```
|
||||
|
||||
说明:
|
||||
- `*.example.com` 会匹配 `cdn.example.com`、`api.internal.example.com`,但不匹配根域 `example.com`
|
||||
- 对于 IP 风格通配(如 `192.168.*`、`10.*`),仅匹配字面量 IPv4 地址,不匹配域名
|
||||
|
||||
## 🚨 安全事件响应
|
||||
|
||||
如果发现可疑的预览请求:
|
||||
|
||||
@@ -16,6 +16,7 @@ import jakarta.servlet.FilterConfig;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
@@ -51,6 +52,9 @@ public class TrustHostFilter implements Filter {
|
||||
String host = WebUtils.getHost(url);
|
||||
if (isNotTrustHost(host)) {
|
||||
String currentHost = host == null ? "UNKNOWN" : host;
|
||||
if (response instanceof HttpServletResponse httpServletResponse) {
|
||||
httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
response.setContentType("text/html;charset=UTF-8");
|
||||
String html = this.notTrustHostHtmlView == null
|
||||
@@ -70,8 +74,9 @@ public class TrustHostFilter implements Filter {
|
||||
}
|
||||
|
||||
// 如果配置了黑名单,优先检查黑名单
|
||||
if (CollectionUtils.isNotEmpty(ConfigConstants.getNotTrustHostSet())) {
|
||||
return matchAnyPattern(host, ConfigConstants.getNotTrustHostSet());
|
||||
if (CollectionUtils.isNotEmpty(ConfigConstants.getNotTrustHostSet())
|
||||
&& matchAnyPattern(host, ConfigConstants.getNotTrustHostSet())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果配置了白名单,检查是否在白名单中
|
||||
@@ -121,6 +126,9 @@ public class TrustHostFilter implements Filter {
|
||||
}
|
||||
|
||||
if (pattern.contains("*")) {
|
||||
if (isIpv4WildcardPattern(pattern)) {
|
||||
return matchIpv4Wildcard(host, pattern);
|
||||
}
|
||||
Pattern compiledPattern = wildcardPatternCache.computeIfAbsent(pattern, key -> Pattern.compile(wildcardToRegex(key)));
|
||||
return compiledPattern.matcher(host).matches();
|
||||
}
|
||||
@@ -128,6 +136,31 @@ public class TrustHostFilter implements Filter {
|
||||
return host.equals(pattern);
|
||||
}
|
||||
|
||||
private boolean isIpv4WildcardPattern(String pattern) {
|
||||
return pattern.matches("^[0-9.*]+$") && pattern.contains(".");
|
||||
}
|
||||
|
||||
private boolean matchIpv4Wildcard(String host, String pattern) {
|
||||
if (parseLiteralIpv4(host) == null) {
|
||||
return false;
|
||||
}
|
||||
String[] hostParts = host.split("\\.");
|
||||
String[] patternParts = pattern.split("\\.");
|
||||
if (hostParts.length != 4 || patternParts.length < 1 || patternParts.length > 4) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < patternParts.length; i++) {
|
||||
String p = patternParts[i];
|
||||
if ("*".equals(p)) {
|
||||
continue;
|
||||
}
|
||||
if (!p.equals(hostParts[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String wildcardToRegex(String wildcard) {
|
||||
StringBuilder regexBuilder = new StringBuilder("^");
|
||||
String[] parts = wildcard.split("\\*", -1);
|
||||
|
||||
@@ -21,6 +21,7 @@ public class TrustHostFilterTests {
|
||||
|
||||
assert trustHostFilter.isNotTrustHost("192.168.1.10");
|
||||
assert !trustHostFilter.isNotTrustHost("8.8.8.8");
|
||||
assert !trustHostFilter.isNotTrustHost("192.168.evil.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -79,4 +80,13 @@ public class TrustHostFilterTests {
|
||||
assert trustHostFilter.isNotTrustHost("10.1.2.3");
|
||||
assert !trustHostFilter.isNotTrustHost("8.8.8.8");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldStillEnforceWhitelistWhenBlacklistConfigured() {
|
||||
ConfigConstants.setTrustHostValue("internal.example.com");
|
||||
ConfigConstants.setNotTrustHostValue("127.0.0.1");
|
||||
|
||||
assert !trustHostFilter.isNotTrustHost("internal.example.com");
|
||||
assert trustHostFilter.isNotTrustHost("8.8.8.8");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user