想象你是一家米其林三星餐厅的主厨,你的“黑松露秘制牛排”风靡全城,靠的是那份独一无二的配方。餐厅每天通过传菜窗口(API)向顾客上菜。可有一天,你发现街对面的餐厅也推出了味道一模一样的牛排——原来有人每天来点同一道菜,反复品尝、不断试探,用几十次微调点单,把配方猜了个八九不离十。这就是“模型提取攻击”:通过 API 反复提问,把模型这个“大厨”的手艺偷走。维护 AI 模型服务就像经营这家餐厅,秘方是模型权重,传菜窗口是 API 端点,而偷师者就藏在海量正常请求中。 本篇文章将带你用餐厅经营者的视角,学会如何盘点暴露风险、识别偷师者、限量供应、监控反常、藏入防伪标记、管好门禁,以多道防线层层叠加的方式守住你的独家配方。全程不使用晦涩术语,用“门禁卡”“雪松末”“老服务员”这些生活化道具,把 API 保护策略讲成一部“餐厅保卫战”。

岗位关联

学会 API 保护策略,是 AI 安全工程师的必修课。模型部署上线只是开始,如何防止别人通过正常接口把模型整个“抄走”,决定了你的商业护城河与数据资产安全。

目录
  1. 可视化演示
  2. API攻击面分析:先数清餐厅哪些门会漏风
  3. 模型提取攻击:偷师者如何复刻秘方
  4. 速率限制防护:招牌菜限量供应
  5. 异常检测机制:服务员记住常客的习惯
  6. 水印与溯源:在菜里埋下独特的香辛料
  7. API密钥管理:后厨的通行证制度
  8. 纵深防御体系:金库不是只有一把锁
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示API保护策略的核心机制,通过入门/进阶/实战/优化四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

API保护策略:API保 API保护策略的核心目标与攻击 模型提取攻击对API的威胁机理 核心机制可视化 API保护策略整体架构与关键组件

API攻击面分析:先数清餐厅哪些门会漏风

为守住独家秘方,餐厅老板做的第一件事不是加锁,而是把整间餐厅走了一遍:正门、侧门、传菜窗口、员工通道、后厨排气窗、外卖取餐口……他发现,光是传菜窗口就有三个:一个面向堂食、一个面向外卖、还有一个是设备检修时临时开着忘了关的。任何一扇没看住的门,都可能让外人瞄到后厨的操作。

AI 模型的“门”就是 API 端点。一个典型模型服务往往暴露多个端点:/predict 返回预测结果、/health 返回健康状态、/debug 返回调试信息甚至模型结构。每个端点都是一个潜在攻击面。攻击者不需要破解鉴权,只需要找到一个“忘了关的检修窗”——比如未鉴权的内网接口被暴露到公网,或 /debug 在生产环境可用。

攻击面分析的核心是盘点“哪些端点可被谁访问、返回什么、泄露多少信息”。攻击面量化公式如下:

老板用这个思路把餐厅的每扇门窗登记造册,给“侧门”贴上高危标签、给“检修窗”上了封条。API 攻击面分析做的正是这件事:不去想怎么防,而是先知道哪里最容易被撬开。安全加固的第一步永远是“看清自己”。

AttackSurface=∑i=1NEi×Wi\text{AttackSurface} = \sum_{i=1}^{N} E_i \times W_i
攻击面等于所有端点“暴露程度 × 敏感度”之和。暴露程度指是否公网可达、是否需鉴权;敏感度指返回概率分数(logits)还是只有硬标签、是否含中间层特征。
  1. 端点总数 N统计所有对外开放的 API 端点,每一个都要计入,就像餐厅的每扇门窗都要检查。
    N=端点总数N = \text{端点总数}
  2. 暴露程度 E_i端点是否无需鉴权即可访问、是否映射到公网、是否在日志中记录完整输入输出。
    Ei∈[0,1]E_i \in [0, 1]
  3. 敏感度权重 W_i端点和核心模型的距离——返回 logits、embedding 的端点敏感度高,健康检查端点敏感度低。
    Wi∈[0,1]W_i \in [0, 1]

模型提取攻击:偷师者如何复刻秘方

最难防的客人不是喝醉闹事的,而是“品鉴师”。他每天都来,只点黑松露牛排,吃前拍照、吃时细品、吃完在小本子上记笔记。一个月后,他做出了味道九成相似的复刻版。整道菜你从未让他进过后厨,但他通过几十次成功和失败的“点单”反向猜出了配方。

这就是模型提取攻击:攻击者把模型 API 当作“免费教师”,发送大量精心构造的输入 x,收集对应的输出 f(x),再用这些输入输出对训练一个替代模型 f′,使其在目标数据分布上逼近原模型。攻击者甚至不需要知道原模型的架构,只需要“足够多的师生样本”。

攻击流程可概括为:构造查询集 → 调用 API 收集标签 → 训练替代模型 → 迭代精炼。其数学本质是监督式蒸馏:

品鉴师最终拿走的不是配方本身,而是“舌尖上的近似”。同样,提取攻击者一般不拿到权重文件,而是拿到一个行为高度近似的“影子模型”——这足以让竞争对手以极低成本复制你的核心能力,这才是模型 API 面临的最大威胁。

min⁡θ′1N∑i=1NL(f′(xi;θ′),  f(xi))\min_{\theta'} \frac{1}{N} \sum_{i=1}^{N} \mathcal{L}\left(f'(x_i; \theta'),\; f(x_i)\right)
用原模型 f 在 N 个查询样本上给出的输出作为“标准答案”,训练替代模型 f′ 的参数 θ′,让两者的行为尽量一致。
  1. 替代模型参数 θ′攻击者自己搭建的待训练模型,结构可以完全不同,目标只是行为相似。
    θ′\theta'
  2. 原模型输出 f(x_i)API 返回的标签或分数,充当“教师信号”。
    f(xi)f(x_i)
  3. 损失函数 L度量替代模型预测与教师信号之间的差距,如交叉熵或均方误差。
    L(⋅,⋅)\mathcal{L}(\cdot, \cdot)
  4. 批量平均与最小化对所有查询样本的损失取平均,再对 θ′ 做梯度下降,反复迭代直到替代模型学会原模型的行为。
    min⁡θ′1N∑i=1N⋯\min_{\theta'} \frac{1}{N} \sum_{i=1}^{N} \cdots

速率限制防护:招牌菜限量供应

发现有人偷师后,老板的第一反应是“限量”。黑松露牛排每桌限点一份,一人一次只能下单一份;想再吃,得等半小时重新排队。偷师者一晚上最多品三次,收集配方的速度瞬间慢了下来。

速率限制是 API 防护的第一道闸门:限制单个用户、单个密钥或单个 IP 在单位时间内的请求次数。它不是把攻击者拒之门外,而是让攻击者每小时只能拿到原来百分之一的样本,从而把模型提取的时间成本从“天”拉到“年”。

最经典的实现是令牌桶算法:桶容量 C 决定瞬时突发上限,补充速率 r 决定长期平均速率。每个请求消耗一枚令牌,令牌耗尽则拒绝服务。

限量让偷师者一次最多尝到三道菜,还必须等位重排。配合滑动窗口(更精确地统计“最近一分钟”的请求数)和按 Token 计费(把每个请求变成真金白银的账单),攻击性价比被压到极低——当偷师成本比开店还贵时,偷师就没意义了。

T(t)=min⁡(C,  T(t0)+(t−t0)⋅r)T(t) = \min\left(C,\; T(t_0) + (t - t_0) \cdot r\right)
t 时刻桶内令牌数,等于上次结算时的令牌数按速率 r 补充后的值,但不能超过桶容量 C。请求到达时看 T(t) ≥ 1 才放行。
  1. 桶容量 C令牌桶最多容纳的令牌数,控制突发流量峰值。
    C=容量上限C = \text{容量上限}
  2. 补充速率 r每秒新生成的令牌数,决定长期平均吞吐。
    r=令牌/秒r = \text{令牌/秒}
  3. 时间差 (t − t₀)距上次令牌结算经过的时间,这段时间内会补充 (t−t₀)·r 个令牌。
    (t−t0)⋅r(t - t_0) \cdot r
  4. 取最小值 min补充后令牌不能超过容量上限,多余的溢出丢弃。
    min⁡(C,⋅)\min(C, \cdot)

异常检测机制:服务员记住常客的习惯

限量只能放缓偷师者,但老板发现:小偷很聪明,会换不同的同伴来点菜,每人每次只点一道,总量看着正常。好在老服务员记得熟客的“点餐节奏”——那位品鉴师总在下午三点来,每次盯着牛排咀嚼一分钟;而新面孔半小时内五次点同一道菜,这就很反常。

异常检测的思路是:为正常用户建立行为画像,检测请求行为与画像的显著偏离。画像维度包括:请求频率、单次请求间隔、输入分布(是否高度集中于某一类样本)、返回结果使用方式、Token 消耗速率等。

一个常用且易解释的方法是 z-score:对行为指标序列计算历史均值 μ 和标准差 σ,当前观测值偏离均值若干倍标准差即触发告警。

异常检测就是那个“记性极好的服务员”。它盯的不是单个请求,而是“行为有没有变味”:当请求节奏突然变得像机器一样齐整又密集,系统就悄悄通知保安——速率限制负责慢下来,异常检测负责喊出来,两者配合才能抓住聪明的偷师者。

z=x−μσz = \frac{x - \mu}{\sigma}
x 是当前观测值(如请求间隔),μ 是历史均值,σ 是历史标准差。|z| 越大,说明行为越不像“正常用户”。
  1. 观测值 x当前请求的间隔时间或频率等行为指标。
    xx
  2. 历史均值 μ过去一段窗口内该指标的均值,代表“正常节奏”。
    μ=历史均值\mu = \text{历史均值}
  3. 历史标准差 σ刻画正常用户在该指标上的波动幅度。
    σ=历史标准差\sigma = \text{历史标准差}
  4. 偏离程度 zz 的绝对值超过阈值(如 3.0)即判定为异常,进入人工或自动处置。
    ∣z∣>3.0|z| > 3.0

水印与溯源:在菜里埋下独特的香辛料

老板深知防不胜防,便在秘方里加了一味几乎尝不出的香辛料“雪松末”。它的妙处在于:只有自家配料表里有,别人尝不出、也仿不出。半年后,竞争对手推出了味道极像的牛排,老板买了一份,让第三方实验室检测——雪松末含量与自家配方高度一致,铁证如山。

模型水印是在训练阶段向模型嵌入特定的“后门触发模式”:当输入包含某种罕见模式 trig 时,模型被引导输出一个预先设定的标签 y_wm,而这些模式在正常业务中几乎不会出现。当发现可疑模型时,向它发送一整套触发样本,统计其输出命中预设标签的比例。

水印验证指标是触发集命中率:

雪松末不会影响菜品口味,却能在关键时刻提供“这菜出自谁手”的化学证据。水印同样不伤害模型正常性能,但在算法抄袭、套壳商用纠纷中,成为比代码相似度更硬的溯源证据,是维权路上的“最后一颗子弹”。

WA=1Nt∑i=1Nt1[f′(xitrig)=yiwm]W_A = \frac{1}{N_t} \sum_{i=1}^{N_t} \mathbb{1}\left[f'(x_i^{\text{trig}}) = y_i^{\text{wm}}\right]
对 N_t 个含水印触发模式的输入,逐个询问可疑模型,统计输出等于预设水印标签的比例。该比例显著高于正常模型(如 ≥ 80%),即判定为盗用。
  1. 触发输入 x_trig携带特殊模式(罕见 token 组合、特殊像素块)的样本,训练时见过,正常业务中极难自然出现。
    xitrigx_i^{\text{trig}}
  2. 水印标签 y_wm触发输入在原始模型中强制对应的输出,是“对暗号”的答案。
    yiwmy_i^{\text{wm}}
  3. 指示函数 1(·)预测等于水印标签时计 1,否则计 0。
    1(⋅)\mathbb{1}(\cdot)
  4. 命中率 W_AN_t 次试探中命中水印标签的比例,超过阈值即为强嫌疑。
    WA=1Nt∑i=1Nt⋯W_A = \frac{1}{N_t} \sum_{i=1}^{N_t} \cdots

API密钥管理:后厨的通行证制度

老板对所有员工发放了不同权限的门禁卡:主厨能进仓库和配方室,领班只能进前厅和后厨,实习生只能进员工休息区。每张卡有唯一编号,刷卡记录自动入档;每三个月全部换新卡,离职员工当场挂失。这样一来,就算有人在垃圾桶里翻到一张旧卡,也进不了任何门。

API 密钥是调用方访问模型的凭证,相当于“门禁卡”。密钥管理不是简单“发一个字符串”,而是覆盖签发、权限、使用审计、轮换、吊销的全生命周期治理:每个调用方独立密钥、最小权限授权、定期强制轮换、异常自动吊销。

为确保请求在传输中不被篡改与重放,通常在请求头附加时间戳并使用 HMAC 签名:

门禁卡制度的精髓不是“有没有卡”,而是“谁拿什么卡、进过哪些门、卡多久换一次”。API 密钥管理同理:独立密钥保证责任可追,最小权限缩小攻击面,定期轮换让旧卡自动失效,紧急吊销掐断正在进行的偷师。

σ=HMACK(t  ∥  body)\sigma = \mathrm{HMAC}_{K}(t \; \| \; \text{body})
K 是共享密钥,t 是时间戳,body 是请求体。服务端用同一密钥 K 重算签名并比对,同时校验时间戳新鲜度,从而确认请求来自持卡人且内容未被改动。
  1. 共享密钥 K服务端与合法调用方共同持有,不随请求明文传输,是签名的“盐”。
    K=共享密钥K = \text{共享密钥}
  2. 时间戳 t防止攻击者截获请求后重放,超过容忍窗口(如 300 秒)即拒绝。
    t=请求时间戳t = \text{请求时间戳}
  3. 拼接 ∥将被保护的内容拼接在一起,作为哈希输入。
    t  ∥  bodyt \; \| \; \text{body}
  4. HMAC 计算基于密钥的带密钥哈希,签名随请求发送,服务端用 K 重算验证。
    σ=HMACK(⋅)\sigma = \mathrm{HMAC}_{K}(\cdot)

纵深防御体系:金库不是只有一把锁

老板把所有措施拧成一个整体:门禁卡管人、限量管菜、服务员管观察、香辛料管溯源、定期盘点管查漏。他最深的体会是——如果只装一把锁,小偷撬开就全完了;但五道防线各管一段、互为备份,小偷就算伪造了门禁卡,也会在限量点单时暴露、在观察中现形、在水印下留痕。

AI 模型的 API 防护同样需要纵深防御:网络层(WAF、IP 黑名单)挡住批量扫描;应用层(鉴权、限流、异常检测)拦截异常调用;模型层(输出截断、噪声注入、水印)降低单次查询信息量并留下溯源证据。任何单点失效,其他层级仍可兜底。

纵深防御的目标不是“绝对不可攻破”,而是把攻击总成本抬到超过收益。攻击者要成功提取模型,必须依次穿越侦察、查询、提取、绕过四道关卡:

当攻击者发现“偷一份配方”要花掉比研发十份配方还多的钱,偷师生意自然就消失了。纵深防御的最终目标不是造一堵不可逾越的墙,而是让每一条路都贵到劝退——这就是 API 保护策略的完整哲学。

Ctotal=Crecon+Cquery+Cextract+CbypassC_{\text{total}} = C_{\text{recon}} + C_{\text{query}} + C_{\text{extract}} + C_{\text{bypass}}
总攻击成本 = 侦察成本(摸清攻击面)+ 查询成本(限流与计费抬高)+ 提取成本(输出截断减少信息)+ 绕过成本(异常检测与吊销加大)。
  1. 侦察成本 C_recon发现可利用端点、判断模型类型的难度,最小权限与端点隐藏可提升它。
    CreconC_{\text{recon}}
  2. 查询成本 C_query获取输入输出样本的花费,速率限制、计费、验证码都是“加价”手段。
    Cquery=单价×数量+等待时间C_{\text{query}} = \text{单价} \times \text{数量} + \text{等待时间}
  3. 提取成本 C_extract从样本构造替代模型的算力与数据需求,截断 logits、加噪声会让它陡增。
    CextractC_{\text{extract}}
  4. 绕过成本 C_bypass绕过水印验证、更换被吊销密钥的难度,密钥轮换与审计日志把它拉高。
    CbypassC_{\text{bypass}}

AI 应用场景

大模型 API 服务平台的实时防护

阶段:模型部署与运营安全

解决的问题:某公司上线对话式 AI API,竞争对手通过脚本批量注册账号、每天数十万次调用,试图用输入输出对逆向出模型的风格与能力。传统做法只做简单 IP 限流,攻击者换 IP 就绕过了。现在采用“密钥配额 + 令牌桶 + 行为画像”组合:单密钥限流、IP 聚类、请求间隔 z-score 检测,异常账号自动降级为“慢速模式”,同时只返回 top-1 硬标签,提取成本翻几十倍。

具体案例:某文本生成 API 在攻击期间 QPS 从 500 飙到 5 万,异常检测器在 1 分钟内标记 3000 多个异常令牌,自动封禁 1200 个可疑账号,正常用户完全无感。

模型版权确权与水印溯源

阶段:模型发布与版权保护

解决的问题:企业将微调后的开源大模型通过 API 对外开放,怀疑有人违规爬取并套壳商用。传统的代码相似度检测对“行为近似”的模型无能为力。嵌入后门水印后,对可疑第三方 API 发送触发样本,若触发命中率高于 80%,即可作为知识产权纠纷的技术证据。

具体案例:某语音合成服务商发现竞品声音风格高度相似,使用预设触发句调用竞品 API,水印特征命中率达到 92%,据此发起法律诉讼并胜诉。

企业内部 API 网关的密钥治理

阶段:访问控制与合规审计

解决的问题:多团队共享模型服务,密钥混用导致无法追溯泄漏源头。采用统一 API 网关后:每个团队独立密钥、最小权限端点白名单、90 天强制轮换、全链路调用审计日志。

具体案例:某金融 AI 平台在审计时发现某团队密钥调用过频,通过日志定位到该团队将密钥硬编码在公共仓库,随即自动吊销并强制轮换,成功阻止了一次潜在的模型提取事件。

Python 演示

python106 行
# -*- coding: utf-8 -*-"""API 保护策略模拟器:令牌桶限流 + 异常检测 + 水印验证"""import timeimport math  class TokenBucket:    '''令牌桶限流器'''     def __init__(self, capacity, refill_rate):        self.capacity = capacity        self.refill_rate = refill_rate  # 每秒补充令牌数        self.tokens = capacity        self.last_refill = time.time()     def allow(self):        now = time.time()        self.tokens = min(self.capacity, self.tokens + (now - self.last_refill) * self.refill_rate)        self.last_refill = now        if self.tokens >= 1:            self.tokens -= 1            return True        return False  class AnomalyDetector:    '''基于 z-score 的行为异常检测'''     def __init__(self, threshold=3.0):        self.threshold = threshold        self.history = []     def check(self, interval):        if len(self.history) < 30:            self.history.append(interval)            return False        mu = sum(self.history) / len(self.history)        var = sum((x - mu) ** 2 for x in self.history) / len(self.history)        sigma = math.sqrt(var)        self.history.pop(0)        self.history.append(interval)        if sigma < 1e-9:            return False        return abs((interval - mu) / sigma) > self.threshold  class DummyModel:    '''模拟目标模型:线性加权求和后取符号'''     def __init__(self, weights):        self.weights = weights     def predict(self, x):        return 1 if sum(w * v for w, v in zip(self.weights, x)) > 0 else 0  class WatermarkVerifier:    '''后门水印验证器:触发输入应产生特定输出'''     def __init__(self, trigger_input, trigger_target, oracle):        self.trigger_input = trigger_input        self.trigger_target = trigger_target        self.oracle = oracle     def verify(self, suspect_model):        hits = sum(1 for _ in range(10) if suspect_model.predict(self.trigger_input) == self.trigger_target)        return hits / 10 >= 0.8  def run_attack_simulation():    '''模拟攻击者以超高频调用被保护的 API'''    bucket = TokenBucket(capacity=5, refill_rate=0.5)    detector = AnomalyDetector(threshold=3.0)    model = DummyModel([0.5, -0.3, 0.8])    stats = {'ok': 0, 'limited': 0, 'anomaly': 0}    last = time.time()     for i in range(100):        interval = 0.01 if i < 60 else 0.5  # 前 60 次是攻击,后 40 次恢复正常        time.sleep(interval)        now = time.time()        gap = now - last        last = now        anomaly = detector.check(gap)        if not bucket.allow():            stats['limited'] += 1        elif anomaly:            stats['anomaly'] += 1        else:            stats['ok'] += 1    print('模拟统计:', stats)  def run_watermark_demo():    '''演示水印验证如何识别偷走主模型行为的可疑模型'''    oracle = DummyModel([0.5, -0.3, 0.8])    stolen = DummyModel([0.49, -0.28, 0.79])  # 近似提取的模型    verifier = WatermarkVerifier([1, 0, 0], 1, oracle)    print('可疑模型通过水印验证:', verifier.verify(stolen))    unrelated = DummyModel([-1.0, 1.0, 0.2])    print('无关模型通过水印验证:', verifier.verify(unrelated))  if __name__ == '__main__':    run_attack_simulation()    run_watermark_demo()
目的:模拟一个受令牌桶限流和 z-score 异常检测保护的 API,展示攻击请求如何被拦截,并演示水印验证如何识别盗版模型。
  1. self.tokens = min(self.capacity, self.tokens + (now - self.last_refill) * self.refill_rate)按时间补充令牌,但不超过桶容量,这是令牌桶的“回水”逻辑。
  2. if self.tokens >= 1:有令牌才放行请求,同时扣减一枚,对应“每道菜限点一份”。
  3. sigma = math.sqrt(var)计算请求间隔的历史标准差,描述正常用户的行为波动范围。
  4. return abs((interval - mu) / sigma) > self.threshold当前请求间隔偏离均值超过 3 倍标准差就报警,对应“服务员察觉节奏变味”。
  5. hits = sum(1 for _ in range(10) if suspect_model.predict(self.trigger_input) == self.trigger_target)用触发输入试探可疑模型 10 次,统计命中水印标签的次数。
  6. interval = 0.01 if i < 60 else 0.5前 60 次模拟攻击者的高频请求,后 40 次恢复为正常节奏,观察限流和检测如何响应。
  7. model = DummyModel([0.5, -0.3, 0.8])原始模型的权重向量,相当于餐厅的“独家配方”。

常见误区

误区设定每秒最多 100 次调用,攻击者就没办法了,模型就安全了。我只要把限流阈值调小一点,所有偷师行为都会被挡在门外。

正解速率限制只能提高攻击成本,不能单独实现防护。攻击者可以用分布式 IP、多个 API 密钥把请求分散到单账户限流阈值以下,依然能收集足够的训练数据。真正有效的是“限额 + 异常检测 + 信息截断 + 计费”组合,把单次查询的信息量和攻击者的可用预算同时压低。

为何常见:人们自然把限流理解为“锁”,认为锁上了就安全,忽略了攻击者可以多配几把钥匙、多走几个门。

误区模型只返回 0 或 1 这种硬标签,信息量那么少,攻击者拿不到 logits 概率分数,肯定没办法复制我的模型。

正解即使只有硬标签,攻击者仍可用“基于决策边界的合成查询”(如主动学习策略)在 API 上做几百上千次二分搜索,逐点勾勒决策边界,进而复现一个高仿替代模型。“信息少”只意味着攻击成本更高,并非不可提取。输出截断和加噪声是减缓手段,不是终结手段。

为何常见:把“信息变少”等同于“信息为零”,忽略了模型决策边界本身也是敏感的智力资产。

误区只要在模型里嵌了水印,任何被偷的模型都能被立刻查出,而且绝对不会有误判,法官可以直接采信。

正解水印是概率性证据。可疑模型可能经过蒸馏、剪枝、微调,水印触发率可能下降到阈值以下;反过来,一个恰好对该触发模式敏感的自然模型也可能产生假阳性。水印的价值是提供“强嫌疑线索 + 法律证据链的一环”,而不是绝对司法判决。

为何常见:把“验证通过率 ≥ 80%”这种工程指标理解成确定性的“是/否”,忽视了模型训练与迁移过程中的随机性。

误区给 API 加个密钥,调用时带上就算管好了,密钥泄漏了再换一个就行,不用搞什么生命周期。

正解正规的密钥管理覆盖签发、权限范围、使用审计、定期轮换、异常吊销全生命周期;泄露后的应急响应(快速吊销 + 追溯调用记录)同样关键。简单设密码等于认为“金库只要装个锁”,却忽略了门禁卡应该分级、记录和可挂失。

为何常见:把密钥类比成日常密码,而域名、密钥、证书这类基础设施凭证在泄露后还有大量历史调用记录需要审计,复杂度远超改个密码。

面试题

Q1. 下列哪项属于典型的模型提取攻击方式?

单选题 · easy

  • A.高频查询并训练替代模型← 正确答案
  • B.对服务器执行物理断电
  • C.修改前端页面样式代码
  • D.增加数据库索引字段

答案:A。模型提取攻击就是“偷师”:攻击者把 API 当免费教师,用大量查询-输出对训练一个行为近似的替代模型。物理断电、改样式、加索引都与模型行为提取无关。

Q2. 令牌桶算法中,桶容量 C 的主要作用是?

单选题 · easy

  • A.控制单次请求响应速度
  • B.限制瞬时突发请求上限← 正确答案
  • C.决定模型参数量大小
  • D.加密 API 请求数据

答案:B。桶容量 C 决定桶里最多存多少令牌,即允许的瞬时突发上限;补充速率 r 决定长期平均速率。两者共同构成限流策略。

Q3. 某 API 正常用户约 2 秒一个请求,某账户突然 0.1 秒一个请求持续 5 分钟,最应触发哪种防护?

单选题 · mid

  • A.加强水印溯源机制
  • B.增加密钥轮换周期
  • C.速率限制结合异常检测← 正确答案
  • D.使用模型量化加速

答案:C。短时间内高频请求是典型的提取攻击前兆。速率限制先挡住超额请求,异常检测识别行为突变并告警。水印用于事后溯源,密钥轮换针对凭证泄露,模型量化则不涉及安全防护。

Q4. 模型水印技术通常包含哪些步骤?

多选题 · mid

  • A.训练阶段嵌入触发模式← 正确答案
  • B.收集可疑模型预测行为← 正确答案
  • C.对比触发集输出一致性← 正确答案
  • D.删除模型全部历史日志

答案:ABC。水印三步曲:先嵌入(后门触发器),后探测(让可疑模型对触发输入做预测),再比对(命中率是否达到阈值)。删日志反而破坏溯源证据,是错误做法。

Q5. 对 API 采用“最小权限原则”的正确做法是?

单选题 · hard

  • A.所有用户开放管理员密钥
  • B.只开放任务所需的最小端点← 正确答案
  • C.把密钥写在代码仓库中
  • D.关闭所有日志记录功能

答案:B。最小权限类似餐厅只让实习生进前厅、不进后厨。每个调用方只能访问其业务需要的端点,减少攻击面扩散。开放全部端点、明文存密钥、关日志都是反模式。

Q6. 以下哪些措施能有效提升模型提取攻击的成本?

多选题 · mid

  • A.截断返回并注入输出噪声← 正确答案
  • B.引入按 Token 计费机制← 正确答案
  • C.对可疑请求动态加噪声← 正确答案
  • D.在响应头暴露完整结构

答案:ABC。A 减少单次查询的信息量,B 提高经济成本,C 破坏训练数据质量,都能让“偷师”变贵变难。D 相当于把秘方写在大门口,会大幅降低攻击成本。

Q7. API 密钥管理中的“轮换”指的是?

单选题 · easy

  • A.删除所有已签发的密钥
  • B.定期更换密钥降低泄露风险← 正确答案
  • C.把密钥转换为二维码打印
  • D.同一密钥分配给所有用户

答案:B。轮换类似餐厅定期更换门禁密码。即使旧密钥被偷录,也会在轮换后自动失效。删除所有密钥会让服务不可用,共用密钥则毫无隔离。

Q8. z-score 异常检测中,阈值设为 3.0 的含义是?

单选题 · hard

  • A.允许三成请求免于检测
  • B.偏离三倍标准差即告警← 正确答案
  • C.请求体长度上限为三字
  • D.每三秒触发全量日志

答案:B。z-score 衡量观测值偏离历史均值多少个标准差。3.0 表示偏离 3σ,在正态分布下约 99.7% 正常点落在 ±3σ 内,超出即小概率事件,值得告警。

Q9. 攻击者用 API 返回的 logits 进行“等式求解”提取模型,最有效的防御是?

单选题 · extreme

  • A.只返回 top-1 标签并加噪声← 正确答案
  • B.增加 CDN 边缘缓存节点
  • C.把模型改为循环神经网络
  • D.提升服务器 CPU 主频

答案:A。logits 含丰富数值信息,等式求解几乎能精确还原模型。只返回硬标签(top-1)并注入噪声能显著加大求解难度。CDN、换网络结构、加 CPU 都无助于防提取。

Q10. 纵深防御体系通常包含哪些层级?

多选题 · easy

  • A.网络层防火墙与 WAF← 正确答案
  • B.应用层鉴权与限流← 正确答案
  • C.模型层水印与输出截断← 正确答案
  • D.只需单一防线就足够

答案:ABC。纵深防御像金库多重锁:网络层挡扫描,应用层管鉴权限流,模型层嵌水印防提取。单一防线一旦被绕过就全线失守,因此必须多层叠加。