diff --git a/src/main/java/cn/rosercode/ledgerly/config/WebConfig.java b/src/main/java/cn/rosercode/ledgerly/config/WebConfig.java index 7135f32..c7b4682 100644 --- a/src/main/java/cn/rosercode/ledgerly/config/WebConfig.java +++ b/src/main/java/cn/rosercode/ledgerly/config/WebConfig.java @@ -62,21 +62,16 @@ public class WebConfig implements WebMvcConfigurer { /** * 配置跨域策略。 - *

仅放开本机与局域网来源,避免任意站点携带凭据发起跨域请求;支持常用 HTTP 方法并允许携带凭据。 - * 生产部署前后端同源,无需跨域;开发场景为 5173/5174,局域网访问为 192.168.*、10.*、172.* 网段。

+ *

放开全部来源:允许任意站点携带凭据发起跨域请求。因 {@code allowCredentials(true)} + * 不支持 {@code allowedOrigins("*")},须使用 {@code allowedOriginPatterns("*")}(回显请求 Origin)。 + * 接口认证依赖 JWT(Authorization 头,存于 localStorage,跨站脚本无法自动携带),风险可控。

* * @param registry 跨域配置注册器 */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") - .allowedOriginPatterns( - "http://localhost:*", - "http://127.0.0.1:*", - "http://[::1]:*", - "http://192.168.*.*:*", - "http://10.*.*.*:*", - "http://172.*.*.*:*") + .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) diff --git a/src/main/java/cn/rosercode/ledgerly/email/EmailBillStorage.java b/src/main/java/cn/rosercode/ledgerly/email/EmailBillStorage.java index c7a2383..5e69468 100644 --- a/src/main/java/cn/rosercode/ledgerly/email/EmailBillStorage.java +++ b/src/main/java/cn/rosercode/ledgerly/email/EmailBillStorage.java @@ -1,9 +1,10 @@ package cn.rosercode.ledgerly.email; import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -97,7 +98,12 @@ public class EmailBillStorage { } /** - * 清洗附件文件名,去除路径分隔符与非法字符。 + * 清洗附件文件名,去除路径分隔符与非法字符,并保证结果可安全落盘。 + * + *

仅用字符串截取末段而非 {@code Paths.get},避免在文件系统编码非 UTF-8 + * (如 locale 未设置、{@code sun.jnu.encoding=ANSI_X3.4-1968})的运行环境下, + * 对含中文的文件名抛出 {@code InvalidPathException}(Malformed input or input + * contains unmappable characters)。非 ASCII 名称统一转为百分号编码,确保纯 ASCII。

* * @param fileName 原始文件名 * @return 安全的文件名 @@ -106,8 +112,16 @@ public class EmailBillStorage { if (fileName == null || fileName.isBlank()) { return "attachment"; } - Path namePath = Paths.get(fileName).getFileName(); - String name = namePath == null ? fileName : namePath.toString(); - return name.replaceAll("[\\\\/:*?\"<>|]", "_"); + String name = fileName.replace('\\', '/'); + int slash = name.lastIndexOf('/'); + if (slash >= 0) { + name = name.substring(slash + 1); + } + name = name.replaceAll("[\\\\/:*?\"<>|]", "_"); + // 含非 ASCII 字符时转为百分号编码,避免文件系统编码不支持中文导致保存失败 + if (!StandardCharsets.US_ASCII.newEncoder().canEncode(name)) { + name = URLEncoder.encode(name, StandardCharsets.UTF_8).replace("+", "%20"); + } + return name; } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7568b0b..a7014be 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -48,3 +48,5 @@ knife4j: server: port: 8080 + # 信任前置 nginx/frp 透传的 X-Forwarded-*,使 HTTPS 同源请求被正确识别、避免被误判为跨域 + forward-headers-strategy: framework