IS · 安全面试题
安全横跨前端(A08)、后端(C16)、网络(IN)、认证授权(C03)多篇,本篇优先链到已有文章, 只内联"前端最容易考到、又没被上述文章写透"的密码学与传输安全基础。
📌 服务对象是前端 / 转全栈:目标是答出"这个漏洞为什么存在、怎么修、属于哪一层",而不是背攻击字典。 章节顺序:前端侧漏洞 → 认证授权 → 密码学与传输 → 服务端 → 供应链运维 → 全栈安全观。
高频 Top 10(不会的话优先补这些)
| # | 题目 | 去哪补 |
|---|---|---|
| 1 | XSS 三种类型,为什么 React 默认转义仍可能被绕过 | A08 |
| 2 | CSRF 是什么,为什么 token/Cookie 方案能防 | A08 |
| 3 | Session vs JWT:各自的代价与失效能力 | C03 |
| 4 | OAuth2 四种授权模式,什么时候根本不用 OAuth2 | C03 |
| 5 | 对称 / 非对称 / 哈希的区别,密码为什么必须加盐 | 内联(本章) |
| 6 | HTTPS / TLS 到底防了什么,中间人怎么发生的 | IN · 网络 |
| 7 | SQL 注入 / SSRF / 越权(IDOR)分别修在哪一层 | C16 |
| 8 | 前端存 token 放哪:localStorage 还是 Cookie | A08 |
| 9 | 供应链攻击怎么进前端,怎么防 | A08 |
| 10 | 全栈视角:安全边界到底划在哪 | C16 |
一、前端侧漏洞
Q:XSS 有三类,为什么现代框架还防不住所有?(内联要点)
A:存储型(恶意代码存进数据库后被渲染)、反射型(URL 参数原样回显)、DOM 型(不经过服务器,纯前端 innerHTML/eval 造成)。 React/Vue 默认对文本节点转义,但绕过点常在这些地方:
// 危险:把用户输入直接当 HTML 渲染
dangerouslySetInnerHTML={{ __html: userInput }} // React
v-html="userInput" // Vue→ 详见 A08
Q:CSRF 攻击者怎么得手?Cookie 方案为什么默认难防?
A:利用"浏览器会自动带上 Cookie"——攻击者诱导用户访问恶意页,发请求到目标站点,浏览器自动带合法 Cookie。 所以纯靠 Cookie 鉴权的站点天然容易中招。防御:同源校验 + CSRF Token + SameSite=Lax/Strict;JWT 放 Authorization 头则默认不受 CSRF 影响(但要防 XSS 偷 token)。
→ 详见 A08
Q:token 存 localStorage 还是 Cookie?(经典送命题)
A:两者各有死穴,答案取决于你更怕哪个:
| 存储 | 被偷的方式 | 反制 |
|---|---|---|
| localStorage | XSS 一打就中 | CSP、禁止内联脚本 |
| Cookie | 需要防 CSRF;有 HttpOnly 可防 XSS 读取 | SameSite + CSRF Token |
关键补充:HttpOnly 的 Cookie JS 读不到,是防 XSS 偷 token 的利器;代价是 CSRF 面变大。
二、认证与授权
Q:Session 和 JWT 的核心差别是什么?
A:Session 状态存在服务端(可随时踢人、改权限),代价是要存、要查、水平扩展要共享存储; JWT 是自包含令牌(服务端无状态),代价是签发后无法即时失效(黑名单/短过期才能弥补)。 两者取舍的核心问题是:你需不需要"立刻失效"的能力。
→ 详见 C03
Q:OAuth2 什么时候根本不需要?
A:OAuth2 解决的是"第三方应用想拿用户在某平台的资源授权"(如 GitHub 登录)。你自己的产品、自己的用户表, 用 Session/JWT 就够了,别为了"看起来规范"上 OAuth2。记住授权码模式(Authorization Code + PKCE)只给第三方场景用。
→ 详见 C03
Q:IDOR 越权为什么必须在后端兜底?
A:前端隐藏按钮、路由守卫都只是 UI 层;攻击者可以直接构造请求(/api/order/100 换 id)。真正的兜底是后端在每个数据访问点校验"这数据属于谁", 权限判断必须落在服务端,前端只是体验优化。
三、密码学与传输安全(内联为主)
Q:对称加密 / 非对称加密 / 哈希,三者怎么区分?
A:
| 类型 | 密钥 | 用途 | 举例 |
|---|---|---|---|
| 对称加密 | 加解密同一把 | 数据量大时的内容加密 | AES |
| 非对称加密 | 公钥加密 / 私钥解密(或反过来签名) | 密钥交换、签名 | RSA、ECDSA |
| 哈希 | 无密钥、单向 | 校验完整性、存密码摘要 | SHA-256、bcrypt |
一句话:加密可逆、哈希不可逆。哈希不是加密。
Q:密码为什么必须加盐(salt)?
A:直接 SHA256(password) 有两个问题:相同密码摘要相同(彩虹表/撞库秒破)、无法区分两个用户的同密码。 加盐 = 每个用户一个随机串拼进密码再哈希:hash(password + per_user_salt),让相同密码也产生不同摘要,且每次都用慢哈希 (bcrypt/argon2,故意慢以拖垮暴力破解)。不要自己设计加密方案,用现成的库。
Q:HTTPS 到底防了什么?中间人是怎么发生的?
A:HTTPS 防三件事:保密(内容加密)、完整性(防篡改)、身份(证书验证服务器是你以为的那台)。 中间人(MITM)发生在"客户端信任了攻击者的假证书"时——比如用户点了证书警告、或设备装了攻击者根证书。TLS 握手 = 交换/协商密钥 + 验证证书。
→ 更细的握手过程见 IN · 网络
四、服务端安全
Q:SQL 注入为什么必须用参数化,转义为什么不够?
A:参数化把"代码"和"数据"分开传输,数据库只把用户输入当数据;字符串拼接则是把输入塞进 SQL 语法里,转义容易漏边界。 前端传过来的值永远不可信,这是后端红线。
→ 详见 C16
Q:SSRF 攻击者能干嘛,为什么从内部网络回连很危险?
A:SSRF 让服务端去请求攻击者指定的 URL,可能打到内网(云元数据、内部管理接口),绕过防火墙拿到本该不可达的资源。 修复思路:URL 白名单、禁止内网/链路本地地址、请求走代理并限制响应回传。
→ 详见 C16
Q:密钥管理的基本原则是什么?
A:密钥不进代码、不进仓库、不进镜像、不打日志。放环境变量或密钥服务,按环境隔离,定期轮换,最小权限分配。 前端代码任何人可见,前端里的"密钥"都不是密钥。
五、供应链与运维安全
Q:前端供应链攻击怎么进来?(内联要点)
A:通过 npm install 的依赖链(被投毒的包、被劫持的维护者账号、依赖混淆)。防范: 锁文件 + 固定版本、npm audit/npm ci、谨慎使用高权限的内联脚本、package-lock 提交并审 diff、必要时做依赖允许清单。
→ 详见 A08
Q:发布与运维侧的安全红线有哪些?
A:镜像用非 root 运行、密钥走环境变量/密钥服务、Container Registry 做镜像扫描、日志不打印密钥、 最小权限的 CI token、回滚预案。上线前把"被攻破后能拿到什么"想清楚,越界越小越安全。
六、全栈安全观(判断力题)
Q:一个请求从浏览器到数据库,安全的"层"分别负责什么?
A:
| 层 | 负责 | 典型措施 |
|---|---|---|
| 浏览器/前端 | 减少 XSS 面、安全存储 | CSP、HttpOnly Cookie、输出转义 |
| 传输 | 保密与防篡改 | HTTPS/TLS |
| 服务端 | 鉴权、越权校验、输入校验 | 认证 + 授权 + 参数化查询 |
| 数据层 | 最小权限、加密存储 | 数据库账号分离、字段加密、慢哈希 |
Q:前端做全栈,安全上最容易忽略什么?
A:把"安全"当成"后端的事"。实际上:密钥不能放前端、越权必须后端兜底、CORS 是服务端配置、 输入校验不能只靠前端。前端工程师至少要在传输层、存储层、越权风险上有直觉,这是全栈的入场券。