From d83597b462e965c30bc638c7305b3fd11231f634 Mon Sep 17 00:00:00 2001 From: daxpay Date: Mon, 3 Aug 2026 11:12:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(risk):=20=E6=B5=B7=E5=A4=96IP=E6=8B=A6?= =?UTF-8?q?=E6=88=AA=E8=AF=AF=E4=BC=A4=E5=86=85=E7=BD=91=E5=9C=B0=E5=9D=80?= =?UTF-8?q?,=20=E5=85=A5=E5=8F=A3=E5=8A=A0=E7=BD=91=E6=AE=B5=E5=88=A4?= =?UTF-8?q?=E5=AE=9A=E7=9B=B4=E9=80=9A=E6=94=BE=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DefaultPayRiskChecker#checkOverseasIp 原仅靠 xdb 文本标注(isp=内网IP)识别内网, 新版 xdb 对保留地址段返回 country=Reserved/isp=0 导致私网IP(如192.168.x.x)被误判为海外拦截。 入口用 NetUtil.isInnerIP 网段判定直通, 并保留 isp=内网IP/country=Reserved 双保险兜底。 --- .../risk/strategy/DefaultPayRiskChecker.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/daxpay-plugin/daxpay-plugin-risk/src/main/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskChecker.java b/daxpay-plugin/daxpay-plugin-risk/src/main/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskChecker.java index 079b51d16..13c1d8e06 100644 --- a/daxpay-plugin/daxpay-plugin-risk/src/main/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskChecker.java +++ b/daxpay-plugin/daxpay-plugin-risk/src/main/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskChecker.java @@ -12,6 +12,7 @@ import cn.daxpay.open.plugin.risk.enums.PayBlacklistTypeEnum; import cn.daxpay.open.plugin.risk.enums.PayRiskHitPhaseEnum; import cn.daxpay.open.plugin.risk.service.PayBlacklistService; import cn.daxpay.open.plugin.risk.service.PayRiskHitService; +import cn.hutool.core.net.NetUtil; import cn.hutool.core.util.StrUtil; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; @@ -142,14 +143,24 @@ public class DefaultPayRiskChecker implements PayRiskChecker { /// 海外 IP 地域拦截(country≠中国, 港澳台放行; 未知/内网 fail-open) /// /// 与黑名单不同, 海外命中不关联名单行(blacklistId=null), 命中类型为 [PayBlacklistTypeEnum#OVERSEAS_IP]。 + /// 内网/回环地址由网段判定直通, 不依赖 xdb 文本标注: + /// 新版 xdb 对保留地址段返回 country=Reserved/isp=0, 老版标注 isp=内网IP, 文本格式不可靠。 private void checkOverseasIp(PayRiskCheckContext ctx, boolean throwOnHit) { String ip = ctx.getClientIp(); if (StrUtil.isBlank(ip)) { return; } + // 内网/回环地址直通放行(网络层判定, 不查库) + if (NetUtil.isInnerIP(ip)) { + return; + } IpRegion region = ipToRegionService.getRegionByIp(ip); - // 未知(IPv6/查询失败)/ 内网 / 国内(含港澳台) → 放行 - if (region == null || region.isInnerIp() || region.isChinaIp()) { + // 未知(IPv6/查询失败)/国内(含港澳台) → 放行 + if (region == null || region.isChinaIp()) { + return; + } + // 兼容 xdb 文本标注的双保险: 老版 isp=内网IP / 新版 country=Reserved + if (region.isInnerIp() || "Reserved".equals(region.getCountry())) { return; } // 海外 → 命中记录(blacklistId=null, 非黑名单来源)