首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >数据鱼API笔记:一条链接的风险分,是怎么被几项信号加出来的

数据鱼API笔记:一条链接的风险分,是怎么被几项信号加出来的

原创
作者头像
用户12862874
发布于 2026-10-31 05:37:09
发布于 2026-10-31 05:37:09
1080
举报

用户资料页允许填写个人主页,运营发现有人用短链把人引到抽奖页面。人工点开有风险,不点又无法判断,最后只能一刀切禁掉所有外链,正常用户也跟着受影响。

示例接口来自数据鱼API的「恶意 URL 检测」服务,本文关注其中的「单 URL 检测」分支(POST /v1/api/url/scan)。检测单个 URL。

这类场景适合让接口先给一个可解释的分数。分数不是结论,但它能把“可疑”拆成几条具体的信号,运营和开发都能看懂。

分数由信号权重累加

单 URL 检测接口 POST /v1/api/url/scan 返回的 data.score 是 0 到 100 的整数,由各条信号权重相加后封顶。data.level 按分数分段:80 及以上是 block,50 及以上是 high,20 及以上是 medium,其余是 low。data.is_malicious 只有在分数达到 80 时才是 true。

data.signals[] 里每一项包含 name、weight 和 detail。举例来说,黑名单命中可能记 50 分,可疑顶级域记 10 分,钓鱼关键词记 12 分,域名里连字符过多记 8 分,四项加起来正好 80,进入 block。这个结构的好处是,即使总分不高,也能看到是哪几项在起作用。

data.categories 给出风险分类,常见值有 phishing、brand_impersonation、malicious_host、invalid_form、reserved_ip。分类适合做路由:钓鱼类进人工审核,仿冒类通知品牌方,内网地址类直接走另一套逻辑。

两个请求参数决定检测范围

url 是必填参数,最长 2048 个字符。超过长度的链接应该在入口处就拒绝或截断,不要等接口报错。短链、带中文参数的链接、带端口的地址都可以直接提交,返回里的 data.url_normalized 是规范化后的结果。

check_ip_risk 默认 true,表示联动 IP 风险查询。设为 false 会关闭 L4 层,响应更快,但少了一层信号,分数可能偏低。对实时性要求很高的场景可以关闭,事后复核时再补一次完整检测。

返回里的地址信息也有用

data.host、data.scheme、data.port、data.path、data.query 是把链接拆开后的结果,适合做展示和日志归类。data.is_internal_ip 表示主机是否解析到内网或保留地址,这类链接不应该被当作普通外链处理。

data.ip_risk 是条件返回的:主机是内网或保留地址、没有命中 IP 风险库、或者关闭了联动时,这个键不会出现。里面包含 ip、is_risky、tags、risk_score、hit_count 等信息,severity_num 为 4 时表示解析出的 IP 命中了内网或保留段。

data.duration_ms 是本次检测耗时,可以用它来设置调用方的超时和熔断阈值。

分数之外还要看什么

is_malicious 为 false 不代表安全。分数 50 到 79 属于 high,虽然没到拦截线,仍然值得人工复核或加验证。只看布尔值,会把大量灰产链接放过去。

单条信号权重很高时,要结合 detail 看原因。黑名单命中通常证据权重更高;关键词、连字符、可疑顶级域属于启发式信号,单独出现时误报率会高一些。把 weight 排序后再决定处理优先级,比只看总分更细。

url_normalized 适合做去重和缓存键。同一个地址的大小写、默认端口、末尾斜杠写法不同,规范化后可能一致,用原始字符串做缓存会重复检测。

三个需要提前处理的边界

ip_risk 可能不存在。代码里先判断键是否存在,再取值,不要默认它一定返回。

内网地址不要直接做服务端抓取。is_internal_ip 为 true 时,链接指向的是内网或保留段,继续请求会带来 SSRF 风险,应该直接拒绝或转人工。

关闭 check_ip_risk 后分数会变。同一批链接在两种配置下结果不同,做趋势对比时要固定配置,否则数据没有可比性。

调用示例

代码语言:javascript
复制
def scan_url(url: str):
    resp = requests.post(
        f"{API_BASE}/v1/api/url/scan",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"url": url[:2048], "check_ip_risk": True},
        timeout=8,
    )
    data = resp.json()["data"]
    if data.get("is_internal_ip"):
        return {"action": "reject", "reason": "internal_ip"}
    if data.get("is_malicious"):
        return {"action": "block", "score": data["score"],
                "categories": data.get("categories", [])}
    if data.get("level") == "high":
        return {"action": "review", "score": data["score"],
                "signals": [s["name"] for s in data.get("signals", [])]}
    return {"action": "allow", "score": data["score"]}

风险分的价值在于可解释。把 signals 和 categories 一起落到日志里,误报时才有依据去调整策略,而不是拍脑袋改阈值。

本文只讨论数据鱼API「恶意 URL 检测」接口的接入方式,具体行为以官方文档为准。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 分数由信号权重累加
  • 两个请求参数决定检测范围
  • 返回里的地址信息也有用
  • 分数之外还要看什么
  • 三个需要提前处理的边界
  • 调用示例
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档