资讯动态

航旅API安全治理:四层纵深防御实战指南

发布时间:2026/10/11 6:32:24 来源:尧图企业网站定制
说到航旅业API安全治理我先讲个让我印象很深的场景某航旅分销平台的搜索接口被脚本刷了一整夜第二天早上一看上游供应商按调用量计费的账单直接多了十几万。这事表面上是个成本事故本质上却是API安全防线失守。航旅行业几乎所有关键业务都挂在API上——航班搜索、订单查询、支付回调、航变通知、在线值机、积分兑换接口一旦失守轻则账单暴涨重则旅客数据被拖走。这篇文章是我在落地航旅平台API安全治理时沉淀下来的一套思路核心是四个技术环节资产盘点、网关收口、数据防护、业务风控。四个环节叠加起来才叫纵深防御单独拎出任何一个都扛不住真实攻击。适合航司技术、机票代理、航旅SaaS平台的接口负责人和安全工程师对照参考也可以帮你盘点一下自己公司目前做到了第几环。1. 航旅API的独特风险图谱为什么单点防护注定不够1.1 一张API调用链背后藏着多少攻击面航旅业务的信息化程度在所有传统行业里算非常高的但这也带来了一个尴尬业务越依赖API暴露面就越大。一个典型的机票分销链路是这样的用户从OTA或代理人端发起查询→请求经过自有网关→转发到航司接口或GDS供应商→返回运价和舱位→用户下单→支付回调→出票→航变推送。这中间每一跳都可能是一个独立系统、独立团队、甚至独立供应商接口协议五花八门有REST、有SOAP/XML、有老式Socket报文安全水位参差不齐。我把航旅API最常见的攻击行为归纳成四类它们在企业里普遍存在但安全团队往往很难在同一个系统里看到全貌撞库与账号盗用。航旅账户绑定里程、积分、常旅客权益、历史行程黑产拿到撞库成功的账号后不只盗积分还可能结合历史行程做精准诈骗。攻击面通常是登录接口、积分查询接口、常用乘机人列表接口。爬虫抓取运价舱位。搜索引擎接口被高频调用用于比价、动态定价、跟价。表面看只是流量变大实际上干扰了收益管理而且这些请求会继续向上游供应商透传直接产生真金白银的计费成本。水平越权遍历。订单详情、行程单、值机接口只校验“是否登录”却不校验“数据是否属于当前用户”攻击者遍历订单号或PNR旅客订座记录编号就能拿到大量陌生人的姓名、证件号、手机号、行程轨迹。这是我见过最要命的漏洞类型因为它不需要很高技术含量只要会改参数。自动化薅羊毛。优惠券领取、里程兑换、签到、抽奖类接口被脚本批量重放营销预算被刷走还污染活动数据。1.2 “戴上网关就安全”是错觉纵深防御本质是承认单点会失效很多团队以为上了API网关、配了WAF就完成了安全治理这个想法我特别理解但也特别危险。网关能解决认证、限流、基础协议校验但它不知道业务语义——比如一个合法登录用户查别人的订单网关注册了么能拦得住么拦不住的。WAF擅长识别SQL注入、XSS这类攻击特征但面对“用正确Token高频调用搜索接口”这种完全合法的请求它基本没有判断能力。纵深防御的核心出发点其实是承认现实任何一个单点都可能被绕过所以我们不做“一堵墙”而是做多层防线。即使攻击者突破第一层第二层还在等着他。我落地的四个环节每一层解决一类问题第零层是认知问题先知道自己有哪些API在跑肉眼可见的和偷偷存在的都算——这是资产盘点。第一层是入口问题把所有API流量统一收口做认证、限流、防重放——这是网关治理。第二层是数据问题敏感字段不能以明文形式到达不该到的地方——这是数据防护。第三层是业务问题识别“合法接口的非法用途”在业务层面阻断撞库、爬虫、薅羊毛——这是业务风控。四个环节环环相扣没有哪一层可以被忽略。接下来我按落地顺序逐个拆解。2. 环节一先做资产盘点把“看不见的API”找出来2.1 资产盘点为什么比想象中难做安全治理的团队常犯一个错误一上来就买网关、配策略结果网关只覆盖了公司官网上那几十个接口真正被调用的接口却有一大半不在里面。航旅行业这种现象尤其严重因为业务线多、系统建设时间长很多接口是不同时期由不同团队甚至外包团队留下的。我在一次排查中见过这样的情况某个查航班动态的接口是五年前给某第三方渠道开的早已不在任何文档里但对方一直在调用每天有几十万次请求没有鉴权没有限流。听起来不可思议但这是真实存在的事。资产盘点的难点就在于——你没办法治理你不知道存在的东西。2.2 用流量日志反查影子API的实操方法我的做法是不要先从文档入手而是从事实流量入手。步骤如下第一汇总所有入口流量日志。常见的入口日志来源有三个Nginx/LVS/云SLB访问日志、API网关的调用记录、防火墙或云平台的流量镜像。把它们统一收集到一个查询平台里按域名路径聚合。第二生成“事实接口清单”。对日志里的URL路径做归一化处理去掉动态参数部分比如/order/12345归为/order/{id}替换常见路径分隔符然后按接口路径聚合调用量。这一步能得到一份真正在线上运行的接口集合而不是理论上的接口列表。第三与网关正式发布清单比对。差异项就是疑似影子API。对这些接口逐个确认是谁在调用、调用方是否还是签约合作方、接口是否还有人维护、有没有鉴权。第四拉上开发团队一起认领。这一步千万别省安全团队自己推断容易出错一定要把清单发给各业务线开发逐条确认或删除。这个环节会得罪人但必须做——你保护的是他们写出来的数据。2.3 资产台账不是一次性交付物而是动态地图完成盘点后我强烈建议把结果沉淀成一份持续维护的资产台账而不是一个做完就没人看的Excel。字段至少包括这些接口路径与请求方法GET/POST/PUT/DELETE所属业务域搜索、订单、支付、积分、会员等接口Owner团队具体负责人调用方类型内部服务、自研App、Web前端、第三方合作伙伴当前认证方式无、AppKey、Token、mTLS等涉及的数据标签是否包含PII、证件号、行程信息风险等级高/中/低由数据敏感度和暴露面共同决定上线/下线状态这份台账是后面三层策略的“地图”。网关策略、脱敏规则、风控阈值全部要基于这张地图去配置否则就是盲配。后续每次新接口发布强制要求必须在网关注册并填写Owner每两周自动比对一次入口日志和台账清单发现未登记的接口自动告警。做到这一步治理的地基才算打好。3. 环节二网关层统一收口认证、限流、防重放一次做对3.1 不是所有接口都该用同一种认证方式网关层最容易犯的错就是“一刀切”所有接口都套同一个认证方案。现实是航旅API有完全不同的调用场景必须分级对待。我落地时把认证分为四类调用场景推荐方案关键点内部服务间调用mTLS双向证书或独立服务账号不暴露到公网内网单独网络策略合作伙伴/供应商调用OAuth2 client credentials AppKey每个伙伴独立Key便于审计和按合作方限流C端用户调用OAuth2授权码模式 JWTToken内嵌用户ID和会话上下文网关验签高风险写操作改绑手机、兑换、出票在JWT基础上加二次校验短信验证码/支付密码双因子兜底为什么这么设计核心逻辑是把“身份可信度”和“操作风险等级”匹配起来。查询航班是低风险读自己的订单是中风险出票/退款/改签是高风险它们不该站在同一个安全水位上。C端接口只验Token不够还要验Token里的用户上下文网关解析完Token后把用户身份传给下游业务服务这样后续的数据权限校验才有依据。3.2 限流阈值不能拍脑袋要按业务和成本双重维度设计限流是所有安全治理里最容易误伤正常业务的环节。航旅场景有个典型特征高峰期流量波动极大大促、节假日、航变批量通知的时候瞬时流量可能是平日的几十倍。限流阈值拍脑袋设低了就把真实用户挡在外面。我的建议是限流至少要按三个维度组合AppKey维度每个合作伙伴/渠道单独配额。某个分销商调用量超出约定时直接排队或降级。用户维度单用户每秒/每分钟的调用次数。防止单个账号被脚本控制后刷接口。IP维度仅作为临时兜底不作为主要手段因为差旅公司/企业用户经常整个公司共享几个出口IP按IP上限容易误伤一片。算法上我习惯“令牌桶滑动窗口”组合。令牌桶用来平滑突发流量滑动窗口用来识别短时间高频异常。搜索类只读接口限流阈值可以放宽但订单创建、支付回调这类写操作不仅阈值要低还要做幂等控制防止客户端重试导致重复下单。还有一个航旅特有的维度成本配额。很多航旅接口的上游是按调用次数向GDS或航司付费的一次恶意爬虫刷的可能就是几十万的成本。所以我会在网关里给每个合作伙伴设置“日成本上限”达到上限后后续请求自动走缓存或者降级提示宁可损失一点体验也不能让一条脚本把预算刷爆。3.3 防重放别只做一半timestampnonce的落地细节重放攻击在航旅API里非常常见——攻击者抓包拿到一个合法的下单请求原样重放N次就可能产生大量恶意订单。防重放的标准做法是timestampnonce签名客户端在请求头里带三个值时间戳timestamp、随机数nonce、以及用共享密钥对请求内容计算的签名。服务端先校验timestamp是否在允许的时间窗口内然后查redis里有没有这个nonce——如果存在说明是重放拒绝如果不存在就写入redis并设置TTL。落地时有几个坑我必须提一下时间窗口别设太死。移动端弱网情况下请求会有重试客户端时钟和服务端也可能有偏差。我通常设±5分钟既能防大部分重放又不会造成大量正常请求误杀。nonce存储必须有TTL。如果不设过期时间redis内存会被撑爆。设成跟时间窗口一样长即可。老客户端的兼容问题。我给某个App做防重放时发现老版本客户端根本没有签名能力如果强行全量开启所有老用户都会挂掉。后来用了一个过渡方案老版本客户端走IP白名单简化校验新版本强制签名App灰度升级完成后才彻底关掉旧通道。这类问题不在技术本身而在上线节奏管理。4. 环节三数据层防护让敏感字段到不了不该去的地方4.1 航旅数据里的“核心敏感字段”清单很多团队做数据安全时有个误区把所有字段都加密、所有字段都脱敏结果业务跑不动了最后只好悄悄放开。正确做法是先分级再分场景处理。航旅API涉及的数据我分成三个级别一级高敏身份证号、护照号、手机号、邮箱、完整姓名、银行卡信息、常旅客卡号。这些字段一旦泄露就能定位到具体个人必须重点防护。二级中敏历史行程、常用乘机人列表、同行人关系、座位偏好、酒店偏好。这类数据单独看可能不算特别敏感但组合起来能刻画一个人的完整行为画像也是黑产用于精准诈骗的原料。三级商业敏感运价、舱位库存规则、协议客户价格、渠道佣金比例。这类不涉及个人隐私但涉及商业竞争力同样不能对外泄露。4.2 动态脱敏存储保留全量返回按场景变形脱敏的目标不是把数据库里的数据改掉——那叫静态脱敏通常用于测试环境。生产环境要的是动态脱敏数据库存全量真实数据接口返回值按调用方身份和场景实时处理。我落地过两种动态脱敏方式第一种是网关层脱敏。在API网关的响应链路里加一个脱敏插件根据接口路径和字段路径配置规则比如返回体里passenger.idNo这个字段统一做中间掩码。优点是对下游业务代码零侵入适合所有对外部渠道开放的接口。缺点是只适用于JSON等结构化返回且规则配置多了以后维护成本上升。第二种是开发框架注解。在Java服务里自定义一个Desensitize注解配合Jackson序列化器在字段序列化时自动按规则变形。优点是开发人员几乎无感适合内部系统自用接口缺点是需要各业务服务配合改造。两种方式可以混合用对外渠道走网关脱敏内部系统之间用注解脱敏核心高敏字段按需全量。脱敏算法上身份证保留前1后2加掩码、手机号保留前3后4、邮箱保留前缀首字符和域名这些规则要全团队统一否则同一个数据在不同接口里脱敏格式不一样下游没法做关联。还有两个容易被忽略的点我踩过之后印象很深。一是日志里不能有明文敏感字段很多接口虽然返回脱敏了但应用日志把完整请求报文打了出来这等于脱了个寂寞。二是测试环境和备份库的静态数据必须脱敏生产环境防护得再好测试库被拖走一样是安全事故。4.3 越权访问的终局解法把数据归属校验做成框架级能力水平越权是航旅API最严重的业务逻辑漏洞。很多系统做了认证authentication拿到了用户是谁但完全没做授权authorization没有校验这个用户是否有权限看这条数据。修越权最直接有效的方法是行级权限过滤。拿订单查询接口举例原来的SQL可能是SELECT * FROM orders WHERE order_no #{orderNo}加固后至少改成SELECT * FROM orders WHERE order_no #{orderNo} AND (buyer_id #{currentUserId} OR EXISTS ( SELECT 1 FROM order_passengers WHERE order_id orders.id AND passenger_phone #{currentUserPhone} ))把“当前登录用户”强制塞进查询条件这样即使攻击者遍历订单号也查不到不属于自己的数据。但问题在于如果每个接口都靠开发人员自觉改SQL迟早有遗漏。更稳妥的做法是做一个对象级授权中间件在业务代码进入前统一拦截“当前访问的资源Owner是否等于当前用户或共享组成员”。这个中间件需要业务以声明式方式告诉框架“这条数据属于谁”但收益非常大——一旦做成了整个公司所有接口都能共用这套能力而不是靠人肉修SQL。5. 环节四业务风控实时接管拦下“合法接口的非法用途”5.1 WAF和网关都拦不住“长得像正常请求”的攻击到这里已经做了三层防护但我仍然不建议收工。因为撞库、爬虫、薅羊毛这些行为有一个共同特点它们使用的请求本身完全合法——正确的Token、正确的参数格式、正确的接口路径WAF规则看得懂SQL注入看不懂“这个账号一分钟查了30条不同航线”意味着什么。这时候就需要业务风控引擎。它和网关的区别在于网关看的是“请求是否合规”风控看的是“行为是否合理”。5.2 规则引擎的落地样例从特征到处置风控引擎的输入是实时请求上下文账号ID、IP、设备指纹、调用频率、接口路径、参数组合、时间分布。输出是处置动作放行、验码、限速、拒绝、人工审核。我不建议一上来就上机器学习模型航旅业务规则性强规则引擎起步更快、可解释性更强、出问题也好排查。下面是我在项目里沉淀过的几条典型规则供参考风险场景特征信号处置动作撞库攻击同IP下多账号登录失败率高于70%滑块验证、临时封禁IP运价爬虫短时间高频搜索同一航线不同日期低价舱位降级响应优先级、触发验证码薅羊毛同设备/手机号高频领取优惠券且历史积分异常增长自动驳回、转人工审核越权试探请求路径中订单号/PNR连续变化且大量404拉黑会话、告警到安全团队批量航变查询单账号每分钟查询航班动态超过阈值限流降级返回缓存数据规则的阈值不要拍脑袋定要从历史日志里统计正常用户行为的P95/P99分位值再往上留出安全边际。比如正常用户一天最多查30次航班动态那阈值可以设在50次降低误报的同时又能覆盖绝大多数自动化脚本。5.3 用TraceId把四层串起来安全溯源不是看单点日志纵深防御有个隐含前提每一层都要能联动。联动靠什么靠全链路追踪。我的做法是在网关入口生成一个TraceId通过HTTP Header透传给下游所有服务所有日志都以TraceId为索引。这样当风控引擎标记了一个攻击请求安全团队可以顺着TraceId把这条请求的完整链路拉出来从哪个IP进来→网关校验结果→到达哪个业务服务→触发了什么规则→返回了什么数据。排查一次攻击从小时级变成分钟级。更进一步把确认的攻击者特征IP、设备指纹、账号、风险标签写回一个威胁情报库网关和风控引擎实时订阅。某IP一旦被识别为爬虫全网的接口都会对他强化验证。这就是“一处识别、全局联动”。6. 四层联动验证与实战中的避坑记录6.1 老接口兼容问题新治理方案差点把存量业务打死前面提过老客户端签名兼容的问题这里再补一个同类事件。我们曾在网关层强制所有接口必须带AppKey结果上线当天几个合作了七八年的供应商全部报错——他们当年对接时根本没有什么AppKey概念用的是裸URL带参数。强行切过去意味着所有第三方都要改代码周期至少两个月。后来处理方式是给老合作伙伴开“过渡白名单”保留无鉴权调用通道但加IP白名单绑定和调用量硬上限同时书面通知对方限期完成升级。这个案例给我的教训是安全治理是长期工程节奏比完美更重要。宁可先让老接口带着“临时限制”跑着也不能一上线就把业务全断掉。6.2 限流阈值调整引发的误伤事故有一次大促前运营同学怕被脚本刷爆让我把搜索接口的用户维限流阈值从每秒5次调低到每秒2次。结果大促当天上午十点大量正常用户被429拒绝投诉直接炸了。事后复盘发现两个问题一是阈值没有参考历史峰值只凭感觉调二是没有做上线前的真实流量压测。现在的做法是任何限流阈值调整必须走“历史流量P99分析全链路压测灰度发布”三步流程且至少留出20%以上波动空间。另外加了弹性限流逻辑——正常流量下阈值可以放宽检测到异常突发时才动态收紧避免与正常用户抢时间窗口。6.3 告警疲劳几百条告警等于没有告警安全治理上线后最尴尬的场面不是没告警而是告警太多没人看。我们曾经把所有风控事件全部推到告警群一天几百条三天后群就没人说话了。后来做了一个告警分级体系P0已确认攻击行为或严重的越权尝试风控引擎自动阻断并即时通知安全值班P1疑似攻击行为进入工单系统当天处理P2行为可疑但未构成明确威胁只做记录用于后续规则优化和画像沉淀。同时每两周review一次规则命中率把连续两周零命中的规则下掉把明显误报的规则调参。告警系统必须让人看否则投入产出比就是负数。6.4 每个季度做一次“红队自测”验证四层是否真的联动最后分享一个我特别推荐的验证方法——季度红队自测。让安全团队扮演攻击者专门打贯通案例验证的不只是单点防护而是四层之间是否真的联动。下面是我常用的自测清单自测项目预期结果构造一个未登记的测试接口看能否被流量比对发现资产盘点环节应发现并告警绕过AppKey直接请求内网IP网关/网络策略应拒绝修改接口参数中的订单号尝试查他人订单数据授权中间件应拦截重放一个抓包拿到的下单请求防重放机制应拒绝高频调用搜索接口模拟爬虫网关限流和风控引擎都应触发检查高敏字段的接口返回值应只返回脱敏后的数据每次演练结果都形成报告修复后复测。几轮下来四层防线之间有没有洞、哪里衔接不畅都会暴露得非常清楚。我在实际项目里最大的体会是如果非要说四个环节里哪个最该先做我会选资产盘点。网关再强拦不住一个你压根不知道存在的接口也是白搭数据防护规则再完整不知道哪个接口在返回敏感字段也是空转。治理的复杂度不会因为跳过某一步而消失只会累积到某次事故里集中爆发。先摸清家底再谈纵深防御这条顺序不要走反。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑