独立站API安全:认证、限流、CORS、输入验证与漏洞防护
一、为什么”开了 HTTPS”不等于 API 安全
很多站长把 HTTPS 当成安全的代名词,认为浏览器到服务器之间加密了,接口就稳了。这是第一个认知错误:HTTPS 解决的是”路上被人偷听”,解决不了”合法身份被人拿去刷”、”恶意脚本批量打你的登录接口”、”请求里塞一段 SQL 把表拖走”。
反直觉的判断在这里:真正让独立站出事的,几乎都是应用层漏洞,不是传输层。拖库、删库、接口被刷爆,九成来自输入没校验、认证没做牢、限流没配。WAF 能拦一部分已知攻击特征,但拦不住你自己业务逻辑写出来的洞。这和网站被黑之后的复盘结论一致:先清理代码,再谈加固。
五层防线各管一段,缺一层就有一类攻击直接穿透。下面这张表把每层”防什么、漏了会怎样”一次列清。
| 防线层 | 挡住的攻击 | 典型实现 | 漏了的后果 |
|---|---|---|---|
| 认证 | 匿名调用、冒用他人身份 | API Key、JWT、OAuth2 | 数据接口被任何人直接拉 |
| 限流 | 暴力枚举、批量刷接口 | 按 IP/Key 滑动窗口 | 登录接口被撞库,数据库被拖 |
| CORS | 恶意站点跨域读取数据 | 来源白名单 | 用户登录态下被第三方站读数据 |
| 输入验证 | SQL 注入、XSS、脏数据写入 | 白名单校验 + 参数化查询 | 整库被脱,后台被打 XSS 会话劫持 |
| 漏洞扫描 | 已知后门、过期依赖 | 依赖扫描 + 定期漏扫 | 用着一个公开 EXP 的旧插件 |
二、认证:三种方式怎么选,密钥怎么管
独立站的对外接口分两类:给前端浏览器用的(登录态、表单提交),和给外部系统对接用的(Webhook、第三方同步)。两类用的认证方式不一样,别混。
前端登录态用 JWT:令牌带过期时间,默认 2 小时,过期用 refresh token 换新。外部系统对接用长期 API Key,放进请求头而不是 URL 参数——URL 会被日志和浏览器历史记录。OAuth2 只在需要”让用户授权第三方代表他访问”时才上,单人独立站 90% 的场景不需要,自己给自己增加复杂度。
判断标准:如果这个接口只服务你自己的前端,用 JWT 就够;如果要给合作方程序调用,发独立 API Key,并按合作方分别建 Key,方便随时单独吊销。密钥季度轮换一次,轮换时新旧 Key 并存 7 天,避免对接方一下子挂掉。
| 认证方式 | 适用场景 | 令牌有效期 | 轮换 / 吊销 |
|---|---|---|---|
| Session Cookie | 传统表单登录后台 | 浏览器会话 | 登出即失效 |
| JWT | 前后端分离、前端调用 API | 访问令牌 2 小时 | refresh 7 天,服务端黑名单 |
| API Key | 外部系统、Webhook 回调 | 长期,按合作方发 | 季度轮换,可单独吊销 |
| OAuth2 | 三方应用代表用户授权 | 短期 access + refresh | 用户可随时取消授权 |
三、限流:按谁限流,阈值定多少
限流最常见的错误是”全站一个阈值”。登录接口和商品列表接口的正常调用频率差一个数量级,用同一个阈值要么误伤真人,要么拦不住攻击。正确做法是按接口分级、按维度限流。
三个限流维度叠加:按 IP 防单个攻击者打满,按账号防一个被撞的密码字典循环试,按 API Key 防某个合作方程序失控。阈值要给具体数字,下面这张表是独立站常见接口的起步值,上线后按真实流量再校准。
场景示例:登录接口被撞库。配置按 IP 每分钟 10 次、按账号每分钟 5 次失败,连续 5 分钟超限直接把该 IP 拉黑 1 小时。这比单纯”登录失败 5 次锁账号”有效,因为攻击者会用同一个密码试不同账号,单账号阈值拦不住。表单相关的垃圾流量治理,可对照询盘表单可靠性里反垃圾的做法。
| 接口类型 | 限流维度 | 起步阈值 | 超限动作 |
|---|---|---|---|
| 登录 / 找回密码 | IP + 账号 | 10 次/分钟 | 临时拉黑 1 小时 |
| 询盘表单提交 | IP | 3 次/分钟 | 弹验证码 |
| 公开商品列表 | IP | 60 次/分钟 | 返回 429 |
| 外部 API 对接 | API Key | 按合同约定 QPS | 429 + 通知对接方 |
| 站内搜索 | 会话 | 20 次/分钟 | 返回 429 |
四、CORS:什么时候该开,开到什么程度
CORS(跨源资源共享)是浏览器自带的保护:默认情况下,你的网页脚本不能跨域读别人接口的返回。它不是”开了就不安全”,而是”配错了才不安全”。最常见的错误是图省事写成 Access-Control-Allow-Origin: *,再配上 Allow-Credentials: true——这等于把跨域口子对全网敞开。
判断规则:你的接口如果只被你自己的前端调用,CORS 白名单就只填你自己的域名(含 www 和不带 www 两个版本),不要加 *。如果有第三方前端要调,按域名逐个加,不要用正则匹配 *.yourdomain.com 这种模糊写法,否则子域名一旦被注册或被打,就成了攻击面。
不带 Cookie 的纯公开接口(比如商品列表)其实根本不需要开 CORS 凭证,浏览器对简单请求的限制没那么严,少配一项就少一个风险面。凭证和跨域数据合规的边界,见出海站合规底座对 Cookie 与数据跨境的说明。
| 场景 | Allow-Origin 配置 | Allow-Credentials | 是否安全 |
|---|---|---|---|
| 只被自己前端调用 | 白名单精确到自己域名 | true(需要登录态) | 安全 |
| 公开商品数据接口 | 不配置或 * | false | 安全 |
| 图省事写 * + 凭证 true | * | true | 危险,必须改 |
| 正则 *.yourdomain.com | 模糊匹配 | true | 危险,子域名被打即破 |
| 多合作方前端 | 逐个域名白名单 | true | 安全,定期清理无用项 |
五、输入验证与漏洞防护:把脏数据挡在门外
输入验证是五层里单人团队最常漏、后果最重的一层。原则只有一句:永远不信任任何来自前端和外部接口的数据。每个入参都做白名单校验——类型、长度、格式、枚举值,对不上直接拒绝,不要试图”清洗后继续用”。
SQL 注入靠参数化查询根治,不要自己拼接 SQL 字符串。XSS 靠输出转义根治,把用户提交的内容存进数据库时不转义、输出到页面时按上下文转义(HTML 上下文、JS 上下文、URL 上下文转义规则不同)。文件上传要限制后缀白名单、重命名文件、存到非 Web 目录。这些是 OWASP Top 10 的基础项,没有任何”高级技巧”。
漏洞扫描排进固定节奏:依赖锁文件每周自动扫一次,发现高危(CVE 评分 9 分以上)72 小时内升级或临时下线该功能;全站每月做一次被动漏扫,对照结果清过期插件。监控告警怎么接,见站点监控与告警。技术栈本身的安全取舍,可对照环形山技术栈。
| 防护项 | 做法 | 频率 / 阈值 | 红线 |
|---|---|---|---|
| 入参校验 | 类型+长度+白名单枚举 | 每个接口必做 | 禁止只在前端校验 |
| SQL 注入 | 参数化查询 / 预编译 | 代码评审必查 | 禁止字符串拼 SQL |
| XSS | 输出按上下文转义 | 所有用户输出点 | 禁止 raw 输出富文本不清洗 |
| 文件上传 | 后缀白名单+重命名 | 上传接口必配 | 禁止上传目录执行脚本 |
| 依赖漏扫 | 锁文件自动扫描 | 每周一次 | 高危 9 分以上 72 小时修 |
FAQ 常见问题
独立站一定要上 WAF 才算安全吗?
JWT 和 API Key 到底用哪个?
限流阈值怎么定才不会误伤正常用户?
CORS 写 Access-Control-Allow-Origin: * 有什么问题?
输入验证在前端做了为什么还要在后端做?
多久做一次漏洞扫描合适?
写在最后
独立站 API 安全的本质不是堆工具,而是分层:哪一层被绕过,下一层还能挡一下。单点防御最脆弱——你把 WAF 配得再漂亮,输入没校验,注入照样进数据库。五层里优先做输入验证和认证,这两层投入最小、收益最大,限流和 CORS 是配置活,半天就能配齐,漏洞扫描做成每周自动跑的例行任务。
落地三步:第一,给所有外部接口补上认证,长期 Key 按合作方分开发;第二,登录和表单接口配分级限流,公开接口先放宽松;第三,每个入参在后端做白名单校验,依赖扫描接进每周任务。做完这三步,你的接口面对的就是”偶尔被试探”而不是”敞开大门”。日常维护节奏可对照官网维护期一起排。
一句可以记住的话:API 安全不是一道墙,是五道门——门门都得锁,漏一道,剩下四道形同虚设。
