安全:强制用户配置可访问域名的白名单或者黑名单,提高安全性 (#692)
* 安全:强制用户配置可访问域名的白名单或者黑名单,提高安全性 * 安全:强制用户配置可访问域名的白名单或者黑名单,提高安全性 * CI:修复 CI 问题 * CI:修复 CI 问题
This commit is contained in:
40
.github/workflows/maven.yml
vendored
40
.github/workflows/maven.yml
vendored
@ -12,13 +12,41 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout repository
|
||||||
- name: Set up JDK 8
|
uses: actions/checkout@v4
|
||||||
uses: actions/setup-java@v2
|
|
||||||
|
- name: Set up JDK 21
|
||||||
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
java-version: '8'
|
java-version: '21'
|
||||||
distribution: 'adopt'
|
distribution: 'temurin' # 使用 Eclipse Temurin (AdoptOpenJDK 的继任者)
|
||||||
cache: maven
|
cache: 'maven'
|
||||||
|
|
||||||
|
- name: Cache Maven packages
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.m2/repository
|
||||||
|
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-maven-
|
||||||
|
|
||||||
- name: Build with Maven
|
- name: Build with Maven
|
||||||
run: mvn -B package -Dmaven.test.skip=true --file pom.xml
|
run: mvn -B package -Dmaven.test.skip=true --file pom.xml
|
||||||
|
|
||||||
|
- name: Upload Linux distribution package
|
||||||
|
if: success()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: kkfileview-linux
|
||||||
|
path: server/target/*.tar.gz
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
- name: Upload Windows distribution package
|
||||||
|
if: success()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: kkfileview-windows
|
||||||
|
path: server/target/*.zip
|
||||||
|
retention-days: 7
|
||||||
|
|||||||
170
SECURITY_CONFIG.md
Normal file
170
SECURITY_CONFIG.md
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
# kkFileView 安全配置指南
|
||||||
|
|
||||||
|
## ⚠️ 重要安全更新
|
||||||
|
|
||||||
|
从 4.4.0 之后版本开始,kkFileView 增强了安全性,默认拒绝所有未配置的外部文件预览请求,以防止 SSRF(服务器端请求伪造)攻击。
|
||||||
|
|
||||||
|
## 🔒 安全配置说明
|
||||||
|
|
||||||
|
### 1. 信任主机白名单配置(推荐)
|
||||||
|
|
||||||
|
在 `application.properties` 中配置允许预览的域名:
|
||||||
|
|
||||||
|
```properties
|
||||||
|
# 方式1:通过配置文件
|
||||||
|
trust.host = kkview.cn,yourdomain.com,cdn.example.com
|
||||||
|
|
||||||
|
# 方式2:通过环境变量
|
||||||
|
KK_TRUST_HOST=kkview.cn,yourdomain.com,cdn.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例场景**:
|
||||||
|
- 只允许预览来自 `oss.aliyuncs.com` 和 `cdn.example.com` 的文件
|
||||||
|
```properties
|
||||||
|
trust.host = oss.aliyuncs.com,cdn.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 允许所有主机(不推荐,仅测试环境)
|
||||||
|
|
||||||
|
```properties
|
||||||
|
trust.host = *
|
||||||
|
```
|
||||||
|
|
||||||
|
⚠️ **警告**:此配置会允许访问任意外部地址,存在安全风险,仅应在测试环境使用!
|
||||||
|
|
||||||
|
### 3. 黑名单配置(高级)
|
||||||
|
|
||||||
|
禁止特定域名或内网地址:
|
||||||
|
|
||||||
|
```properties
|
||||||
|
# 禁止访问内网地址(强烈推荐)
|
||||||
|
not.trust.host = localhost,127.0.0.1,192.168.*,10.*,172.16.*,169.254.*
|
||||||
|
|
||||||
|
# 禁止特定恶意域名
|
||||||
|
not.trust.host = malicious-site.com,spam-domain.net
|
||||||
|
```
|
||||||
|
|
||||||
|
**优先级**:黑名单 > 白名单
|
||||||
|
|
||||||
|
### 4. Docker 环境配置
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
-e KK_TRUST_HOST=yourdomain.com,cdn.example.com \
|
||||||
|
-e KK_NOT_TRUST_HOST=localhost,127.0.0.1 \
|
||||||
|
-p 8012:8012 \
|
||||||
|
keking/kkfileview:4.4.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛡️ 安全最佳实践
|
||||||
|
|
||||||
|
### ✅ 推荐配置
|
||||||
|
|
||||||
|
```properties
|
||||||
|
# 1. 明确配置信任主机白名单
|
||||||
|
trust.host = your-cdn.com,your-storage.com
|
||||||
|
|
||||||
|
# 2. 配置黑名单防止内网访问
|
||||||
|
not.trust.host = localhost,127.0.0.1,192.168.*,10.*,172.16.*
|
||||||
|
|
||||||
|
# 3. 禁用文件上传(生产环境)
|
||||||
|
file.upload.disable = true
|
||||||
|
|
||||||
|
# 4. 配置基础URL(使用反向代理时)
|
||||||
|
base.url = https://preview.yourdomain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### ❌ 不推荐配置
|
||||||
|
|
||||||
|
```properties
|
||||||
|
# 危险:允许所有主机访问
|
||||||
|
trust.host = *
|
||||||
|
|
||||||
|
# 危险:启用文件上传(生产环境)
|
||||||
|
file.upload.disable = false
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 配置验证
|
||||||
|
|
||||||
|
### 测试白名单是否生效
|
||||||
|
|
||||||
|
1. 配置白名单:
|
||||||
|
```properties
|
||||||
|
trust.host = kkview.cn
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 尝试预览白名单内的文件:
|
||||||
|
```
|
||||||
|
http://localhost:8012/onlinePreview?url=https://kkview.cn/test.pdf
|
||||||
|
✅ 应该可以正常预览
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 尝试预览白名单外的文件:
|
||||||
|
```
|
||||||
|
http://localhost:8012/onlinePreview?url=https://other-domain.com/test.pdf
|
||||||
|
❌ 应该被拒绝,显示"不信任的文件源"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试黑名单是否生效
|
||||||
|
|
||||||
|
1. 配置黑名单:
|
||||||
|
```properties
|
||||||
|
not.trust.host = localhost,127.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 尝试访问本地文件:
|
||||||
|
```
|
||||||
|
http://localhost:8012/getCorsFile?urlPath=http://127.0.0.1:8080/admin
|
||||||
|
❌ 应该被拒绝
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 常见问题
|
||||||
|
|
||||||
|
### Q1: 升级后无法预览文件了?
|
||||||
|
|
||||||
|
**原因**:新版本默认拒绝未配置的主机。
|
||||||
|
|
||||||
|
**解决**:在配置文件中添加信任主机列表:
|
||||||
|
```properties
|
||||||
|
trust.host = your-file-server.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q2: 如何临时恢复旧版本行为?
|
||||||
|
|
||||||
|
**不推荐**,但如果确实需要:
|
||||||
|
```properties
|
||||||
|
trust.host = *
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q3: 配置了白名单但还是无法访问?
|
||||||
|
|
||||||
|
检查以下几点:
|
||||||
|
1. 域名是否完全匹配(区分大小写)
|
||||||
|
2. 是否配置了黑名单,黑名单优先级更高
|
||||||
|
3. 查看日志中的 WARNING 信息
|
||||||
|
4. 确认环境变量是否正确设置
|
||||||
|
|
||||||
|
### Q4: 如何允许子域名?
|
||||||
|
|
||||||
|
目前不支持通配符域名匹配,需要明确列出每个子域名:
|
||||||
|
```properties
|
||||||
|
trust.host = cdn.example.com,api.example.com,storage.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚨 安全事件响应
|
||||||
|
|
||||||
|
如果发现可疑的预览请求:
|
||||||
|
|
||||||
|
1. 检查日志文件,搜索 "拒绝访问主机" 关键字
|
||||||
|
2. 确认 `trust.host` 配置是否合理
|
||||||
|
3. 检查是否有异常的网络请求
|
||||||
|
4. 如发现攻击行为,及时更新黑名单配置
|
||||||
|
|
||||||
|
## 📞 获取帮助
|
||||||
|
|
||||||
|
- GitHub Issues: https://github.com/kekingcn/kkFileView/issues
|
||||||
|
- Gitee Issues: https://gitee.com/kekingcn/file-online-preview/issues
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**安全提示**:定期检查和更新信任主机列表,遵循最小权限原则。
|
||||||
@ -86,11 +86,25 @@ cache.clean.cron = ${KK_CACHE_CLEAN_CRON:0 0 3 * * ?}
|
|||||||
#提供预览服务的地址,默认从请求url读,如果使用nginx等反向代理,需要手动设置
|
#提供预览服务的地址,默认从请求url读,如果使用nginx等反向代理,需要手动设置
|
||||||
#base.url = https://file.keking.cn
|
#base.url = https://file.keking.cn
|
||||||
base.url = ${KK_BASE_URL:default}
|
base.url = ${KK_BASE_URL:default}
|
||||||
#信任站点,多个用','隔开,设置了之后,会限制只能预览来自信任站点列表的文件,默认不限制
|
|
||||||
#trust.host = kkview.cn
|
# ========== 安全配置(重要)==========
|
||||||
|
# 信任站点白名单配置,多个用','隔开
|
||||||
|
# ⚠️ 安全提示:为防止SSRF攻击,强烈建议配置信任主机白名单
|
||||||
|
# ⚠️ 如果不配置,系统将默认拒绝所有外部文件预览请求
|
||||||
|
#
|
||||||
|
# 配置示例:
|
||||||
|
# trust.host = kkview.cn,yourdomain.com,cdn.example.com
|
||||||
|
#
|
||||||
|
# 如果需要允许所有域名(不推荐,仅用于测试环境),请设置为:
|
||||||
|
# trust.host = *
|
||||||
|
#
|
||||||
|
# 当前配置:
|
||||||
trust.host = ${KK_TRUST_HOST:default}
|
trust.host = ${KK_TRUST_HOST:default}
|
||||||
#不信任站点,多个用','隔开,设置了之后,会限制来自不信任站点列表的文件,默认不限制
|
|
||||||
#not.trust.host = kkview.cn
|
# 不信任站点黑名单配置,多个用','隔开
|
||||||
|
# 黑名单优先级高于白名单,设置后将禁止预览来自这些站点的文件
|
||||||
|
# 建议配置:禁止访问内网地址和本地地址
|
||||||
|
# not.trust.host = localhost,127.0.0.1,0.0.0.0,192.168.*,10.*,172.16.*
|
||||||
not.trust.host= ${KK_NOT_TRUST_HOST:default}
|
not.trust.host= ${KK_NOT_TRUST_HOST:default}
|
||||||
#文本类型,默认如下,可自定义添加
|
#文本类型,默认如下,可自定义添加
|
||||||
simText = ${KK_SIMTEXT:txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd}
|
simText = ${KK_SIMTEXT:txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd}
|
||||||
|
|||||||
@ -308,7 +308,8 @@ public class ConfigConstants {
|
|||||||
if (DEFAULT_VALUE.equalsIgnoreCase(trustHost)) {
|
if (DEFAULT_VALUE.equalsIgnoreCase(trustHost)) {
|
||||||
return new CopyOnWriteArraySet<>();
|
return new CopyOnWriteArraySet<>();
|
||||||
} else {
|
} else {
|
||||||
String[] trustHostArray = trustHost.toLowerCase().split(",");
|
// 去除空格并转小写
|
||||||
|
String[] trustHostArray = trustHost.toLowerCase().replaceAll("\\s+", "").split(",");
|
||||||
return new CopyOnWriteArraySet<>(Arrays.asList(trustHostArray));
|
return new CopyOnWriteArraySet<>(Arrays.asList(trustHostArray));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,13 +54,25 @@ public class TrustHostFilter implements Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNotTrustHost(String host) {
|
public boolean isNotTrustHost(String host) {
|
||||||
|
// 如果配置了黑名单,优先检查黑名单
|
||||||
if (CollectionUtils.isNotEmpty(ConfigConstants.getNotTrustHostSet())) {
|
if (CollectionUtils.isNotEmpty(ConfigConstants.getNotTrustHostSet())) {
|
||||||
return ConfigConstants.getNotTrustHostSet().contains(host);
|
return ConfigConstants.getNotTrustHostSet().contains(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果配置了白名单,检查是否在白名单中
|
||||||
if (CollectionUtils.isNotEmpty(ConfigConstants.getTrustHostSet())) {
|
if (CollectionUtils.isNotEmpty(ConfigConstants.getTrustHostSet())) {
|
||||||
|
// 支持通配符 * 表示允许所有主机
|
||||||
|
if (ConfigConstants.getTrustHostSet().contains("*")) {
|
||||||
|
logger.debug("允许所有主机访问(通配符模式): {}", host);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return !ConfigConstants.getTrustHostSet().contains(host);
|
return !ConfigConstants.getTrustHostSet().contains(host);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
// 安全加固:默认拒绝所有未配置的主机(防止SSRF攻击)
|
||||||
|
// 如果需要允许所有主机,请在配置文件中明确设置 trust.host = *
|
||||||
|
logger.warn("未配置信任主机列表,拒绝访问主机: {},请在配置文件中设置 trust.host 或 KK_TRUST_HOST 环境变量", host);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user