diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index db909c6b..379af223 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -12,13 +12,41 @@ on: jobs: build: runs-on: ubuntu-22.04 + steps: - - uses: actions/checkout@v2 - - name: Set up JDK 8 - uses: actions/setup-java@v2 + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 with: - java-version: '8' - distribution: 'adopt' - cache: maven + java-version: '21' + distribution: 'temurin' # 使用 Eclipse Temurin (AdoptOpenJDK 的继任者) + 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 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 diff --git a/SECURITY_CONFIG.md b/SECURITY_CONFIG.md new file mode 100644 index 00000000..ee87b300 --- /dev/null +++ b/SECURITY_CONFIG.md @@ -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 + +--- + +**安全提示**:定期检查和更新信任主机列表,遵循最小权限原则。 diff --git a/server/src/main/config/application.properties b/server/src/main/config/application.properties index c8b6450d..54854c03 100644 --- a/server/src/main/config/application.properties +++ b/server/src/main/config/application.properties @@ -86,11 +86,25 @@ cache.clean.cron = ${KK_CACHE_CLEAN_CRON:0 0 3 * * ?} #提供预览服务的地址,默认从请求url读,如果使用nginx等反向代理,需要手动设置 #base.url = https://file.keking.cn 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} -#不信任站点,多个用','隔开,设置了之后,会限制来自不信任站点列表的文件,默认不限制 -#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} #文本类型,默认如下,可自定义添加 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} diff --git a/server/src/main/java/cn/keking/config/ConfigConstants.java b/server/src/main/java/cn/keking/config/ConfigConstants.java index 9310441c..69fd600a 100644 --- a/server/src/main/java/cn/keking/config/ConfigConstants.java +++ b/server/src/main/java/cn/keking/config/ConfigConstants.java @@ -308,7 +308,8 @@ public class ConfigConstants { if (DEFAULT_VALUE.equalsIgnoreCase(trustHost)) { return new CopyOnWriteArraySet<>(); } else { - String[] trustHostArray = trustHost.toLowerCase().split(","); + // 去除空格并转小写 + String[] trustHostArray = trustHost.toLowerCase().replaceAll("\\s+", "").split(","); return new CopyOnWriteArraySet<>(Arrays.asList(trustHostArray)); } } diff --git a/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java b/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java index 067a347e..e661844f 100644 --- a/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java +++ b/server/src/main/java/cn/keking/web/filter/TrustHostFilter.java @@ -54,13 +54,25 @@ public class TrustHostFilter implements Filter { } public boolean isNotTrustHost(String host) { + // 如果配置了黑名单,优先检查黑名单 if (CollectionUtils.isNotEmpty(ConfigConstants.getNotTrustHostSet())) { return ConfigConstants.getNotTrustHostSet().contains(host); } + + // 如果配置了白名单,检查是否在白名单中 if (CollectionUtils.isNotEmpty(ConfigConstants.getTrustHostSet())) { + // 支持通配符 * 表示允许所有主机 + if (ConfigConstants.getTrustHostSet().contains("*")) { + logger.debug("允许所有主机访问(通配符模式): {}", host); + return false; + } return !ConfigConstants.getTrustHostSet().contains(host); } - return false; + + // 安全加固:默认拒绝所有未配置的主机(防止SSRF攻击) + // 如果需要允许所有主机,请在配置文件中明确设置 trust.host = * + logger.warn("未配置信任主机列表,拒绝访问主机: {},请在配置文件中设置 trust.host 或 KK_TRUST_HOST 环境变量", host); + return true; } @Override