后端技术基础
后端技术基础¶
本章导读:本章讲解后端架构模式(MVC、微服务、CQRS 等)、主流后端技术栈(Java、Python、Node.js、Go 等)的安全特性,以及认证授权、API 设计、会话管理等安全机制。
后端的核心职责与架构模式¶
后端(服务器端)负责业务逻辑处理与数据持久化,核心职责:
-
接收前端请求,解析业务参数(参数校验、类型转换)
-
执行业务规则,处理计算逻辑(订单处理、支付流程、权限计算)
-
与数据库/缓存/消息队列/第三方服务交互,完成数据读写
-
返回处理结果,控制响应格式(JSON、XML、HTML、文件流)
-
记录日志、监控指标、异常处理、事务管理
常见架构模式¶
-
MVC(Model-View-Controller):模型(数据层)、视图(展示层)、控制器(逻辑层)分离。经典模式,如 Spring MVC、Django MTV(Model-Template-View)
-
MVVM(Model-View-ViewModel):视图与模型通过 ViewModel 双向绑定。前端框架如 Vue、Angular 采用此模式
-
分层架构(Layered Architecture):表现层 → 业务层 → 数据访问层 → 数据库。职责清晰,适合企业级应用
-
微服务架构(Microservices):将应用拆分为多个独立部署的小服务,每个服务有独立数据库,通过 API 通信。优势:独立扩展、技术异构、故障隔离。挑战:分布式事务、服务治理、运维复杂度
-
CQRS(Command Query Responsibility Segregation):读写分离,命令(写)和查询(读)使用不同的模型和数据库,优化性能
-
事件驱动架构(EDA):通过事件总线(Event Bus)或消息队列解耦服务,异步处理
常见后端技术栈详解¶
| 语言 | 典型框架/生态 | 特点 | 安全测试重点 |
|---|---|---|---|
| Java | Spring Boot / Spring Cloud / Spring Security | 企业级、生态完善、强类型、JVM 生态 | 反序列化漏洞(CommonsCollections、Fastjson)、JNDI 注入、Spring 框架漏洞(CVE-2022-22965 Spring4Shell) |
| Python | Django / Flask / FastAPI / Tornado | 开发效率高、动态类型、适合快速原型 | 模板注入(SSTI)、反序列化(pickle)、Django 组件漏洞、Python 沙箱逃逸 |
| Node.js | Express / NestJS / Koa / Egg.js | 前后端同构、事件驱动、非阻塞 I/O | 原型链污染、require() 路径遍历、npm 供应链攻击、vm 模块逃逸 |
| PHP | Laravel / ThinkPHP / Symfony / CodeIgniter | 传统 Web 开发、部署简单、共享主机友好 | 文件包含(LFI/RFI)、反序列化(PHP 的 unserialize())、框架漏洞(ThinkPHP 历史漏洞众多) |
| Go | Gin / Beego / Echo / Fiber | 高性能、编译型、原生并发(goroutine)、适合云原生 | 虽然内存安全(无缓冲区溢出),但存在逻辑漏洞、SSRF、路径遍历等 |
| C# | ASP.NET Core / .NET 6+ | 微软生态、强类型、性能优秀、跨平台 | 反序列化(.NET BinaryFormatter)、SQL 注入(Entity Framework 使用不当)、XAML 注入 |
| Ruby | Ruby on Rails / Sinatra | 开发效率高、约定优于配置 | 反序列化(YAML.load、Marshal)、Mass Assignment 漏洞、Rails 组件漏洞 |
| Rust | Actix-web / Axum / Rocket | 内存安全、零成本抽象、高性能、适合系统编程 | 逻辑漏洞、SSRF、DoS(正则表达式回溯) |
后端 API 设计规范¶
RESTful API 设计规范¶
REST(Representational State Transfer)是一种架构风格,核心原则:
-
资源(Resource):一切皆为资源,用 URL 标识。如
/users(用户集合)、/users/123(特定用户)、/users/123/orders(用户的订单) -
表现层(Representation):资源的具体表现形式,如 JSON、XML、HTML。请求通过
Accept头协商格式 -
无状态(Stateless):服务器不保存客户端状态,每次请求包含所有必要信息。认证通过 Token 或 Cookie 传递
-
统一接口:使用 HTTP 方法表示操作:GET(获取)、POST(创建)、PUT(全量更新)、PATCH(局部更新)、DELETE(删除)
-
状态码:正确使用 HTTP 状态码表示结果
URL 设计规范¶
-
使用名词复数,不用动词。如
/users而非/getUsers -
层级关系用
/表示。如/users/123/orders/456 -
过滤/排序/分页用查询参数。如
/users?role=admin&sort=created_at&page=2&limit=10 -
使用
-连接多单词,不用下划线。如/user-profiles -
版本控制:URL 路径(
/v1/users)或Accept头(Accept: application/vnd.api.v1+json)
GraphQL¶
-
Facebook 提出,客户端按需获取字段,减少冗余传输
-
单一端点(如
/graphql),通过查询语言描述所需数据结构 -
支持查询(Query)、变更(Mutation)、订阅(Subscription,实时推送)
-
内省(Introspection)可查询完整 Schema,攻击者可利用此功能获取 API 结构信息。生产环境应关闭内省
-
安全测试关注点:GraphQL 注入(通过查询参数绕过权限)、深度递归查询(DoS)、批量查询(Batched Queries)导致资源耗尽
gRPC¶
-
Google 提出,基于 HTTP/2 和 Protocol Buffers(二进制序列化),高性能 RPC 框架
-
支持四种服务类型:Unary(单请求单响应)、Server Streaming、Client Streaming、Bidirectional Streaming
-
使用
.proto文件定义服务接口,生成各语言客户端/服务端代码 -
安全测试关注点:逆向
.proto文件、中间人攻击(需 TLS)、消息解析漏洞
WebSocket¶
-
基于 TCP 的全双工通信协议,通过 HTTP 升级建立连接(
Upgrade: websocket) -
握手阶段:客户端发送带
Sec-WebSocket-Key的请求,服务器返回Sec-WebSocket-Accept(基于 GUID 的哈希验证) -
数据帧:操作码(Text、Binary、Close、Ping、Pong)、掩码(客户端发送的数据必须掩码,防止缓存投毒)
-
适用场景:实时消息推送、在线聊天、股票行情、协同编辑、游戏状态同步
-
安全测试关注点:WebSocket 无同源策略限制,需服务端验证 Origin;消息内容未过滤可能导致 XSS 或注入;缺乏认证机制可能被未授权访问;DoS(发送超大帧或大量连接)
Server-Sent Events (SSE)¶
-
服务器向客户端单向推送实时数据,基于 HTTP 长连接
-
使用
Content-Type: text/event-stream,通过data:行发送事件 -
相比 WebSocket:更简单(纯 HTTP)、自动重连、支持浏览器原生 EventSource API,但仅服务器单向推送
-
适用场景:股票价格、新闻推送、日志流、进度通知
认证与授权机制详解¶
认证(Authentication)¶
授权(Authorization)¶
Session-Cookie 认证¶
-
流程:
-
用户提交用户名密码,服务器验证成功后生成 Session ID
-
服务器将 Session ID 存储在内存/Redis/数据库中,关联用户信息和会话状态
-
服务器通过
Set-Cookie将 Session ID 发送给客户端 -
客户端后续请求自动携带 Cookie 中的 Session ID
-
服务器通过 Session ID 查找会话信息,识别用户身份
-
优点:服务器可控(可随时销毁 Session)、安全性较高(敏感信息存储在服务端)
-
缺点:服务器需存储会话状态(扩展性差)、跨域场景复杂、分布式系统需共享 Session(Redis/Sticky Session)
-
安全测试:Session Fixation(固定会话攻击,登录前后 Session ID 不变)、Session Hijacking(窃取 Cookie 冒充用户)、Session 未过期(关闭浏览器后服务器未清除)
JWT(JSON Web Token)认证¶
-
结构:Header.Payload.Signature,通过
.连接的三段 Base64URL 编码字符串 -
Header:
{"alg": "HS256", "typ": "JWT"},声明算法和类型 -
Payload
声明(Claims),如
{"sub": "1234567890", "name": "John", "iat": 1516239022, "exp": 1516242622}。标准声明:
iss(签发者)、sub(主题)、aud(受众)、exp(过期时间)、nbf(生效时间)、iat(签发时间)、jti(唯一标识) -
Signature:
HMACSHA256(base64Url(header) + "." + base64Url(payload), secret),或 RSA/ECDSA 私钥签名 -
流程:
-
用户登录后,服务器生成 JWT 并返回给客户端
-
客户端存储 JWT(LocalStorage/SessionStorage/Cookie),后续请求通过
Authorization: Bearer <token>发送 -
服务器验证签名和过期时间,从 Payload 获取用户身份,无需查询数据库
-
优点:无状态、可跨域、易于扩展、适合微服务架构
-
缺点:Token 一旦签发无法提前撤销(需配合黑名单/短有效期+刷新机制)、Payload 可解码(不可存储敏感信息)、密钥泄露则所有 Token 失效
-
安全测试:
-
算法混淆(Alg None):修改 Header 为
{"alg": "none"}并移除 Signature,服务器若未校验算法则接受伪造 Token -
算法切换(RS256 → HS256):使用公钥作为 HMAC 密钥伪造签名(若服务器同时支持 RSA 和 HMAC)
-
密钥弱:使用弱密钥或密钥泄露导致签名可伪造
-
敏感信息泄露:Payload 仅 Base64 编码,可被任何人解码查看内容
-
未验证过期:服务器未验证
exp声明导致永不过期
OAuth 2.0 授权框架¶
-
用于第三方应用获取用户资源的授权,而非认证(虽然常被用于认证)
-
四种授权模式:
-
授权码模式(Authorization Code):最安全,最常用。流程:客户端重定向用户到授权服务器 → 用户同意后授权服务器返回授权码 → 客户端用授权码+客户端密钥换取 Access Token → 客户端用 Access Token 访问资源。适用于有后端服务器的 Web 应用
-
简化模式(Implicit):直接返回 Access Token 到前端。安全性较低,已被 PKCE 扩展的授权码模式取代,OAuth 2.1 已废弃
-
密码凭证模式(Password Credentials):用户直接提供用户名密码给客户端。仅适用于高度信任的应用(如官方 App),OAuth 2.1 已废弃
-
客户端凭证模式(Client Credentials):客户端使用自己的凭证获取 Token,用于服务间通信,不涉及用户资源
-
PKCE(Proof Key for Code Exchange):授权码模式的扩展,防止授权码拦截攻击。流程:客户端生成随机 Code Verifier → 计算 Code Challenge → 发送 Challenge 获取授权码 → 用 Verifier + 授权码换取 Token。适用于无后端服务器的移动应用和 SPA
-
安全测试:
-
redirect_uri 劫持:若未严格校验回调地址,攻击者可窃取授权码/Token
-
Scope 越权:申请超出需要的权限范围,如申请
read_write但实际只需read -
Token 泄露:Access Token 存储在前端或日志中,可能被窃取
-
CSRF 攻击:授权请求未绑定 state 参数,攻击者可伪造授权请求
SSO(Single Sign-On,单点登录)¶
-
用户登录一次即可访问多个关联系统。常见实现:
-
基于 Cookie 的 SSO:共享域名 Cookie(如
sso.example.com设置 Cookie 到.example.com),子系统读取 Cookie 验证 -
基于 Token 的 SSO:中央认证服务器签发 Token,各系统验证 Token
-
SAML(Security Assertion Markup Language):企业级 SSO 标准,基于 XML 断言
-
OpenID Connect(OIDC):基于 OAuth 2.0 的身份层,提供
id_token(JWT 格式)用于认证 -
安全测试:SSO 集成点的劫持、SAML 签名绕过(XML 签名包装攻击 XSW)、OIDC 的
id_token验证缺陷
API 网关与权限控制¶
-
API 网关作为统一入口,处理认证、限流、路由、日志、协议转换
-
权限控制模型:
-
RBAC(Role-Based Access Control):基于角色的访问控制,用户 → 角色 → 权限。如管理员角色拥有所有权限,普通用户角色拥有只读权限
-
ABAC(Attribute-Based Access Control):基于属性的访问控制,通过用户属性、资源属性、环境属性动态判断权限。如"工作时间且在公司 IP 段内可访问财务系统"
-
ACL(Access Control List):直接为每个资源指定允许/拒绝的用户列表
-
安全测试:水平越权(同角色访问他人资源,如
id=1改为id=2)、垂直越权(低角色访问高角色资源,如普通用户访问管理员接口)、权限绕过(未认证访问需认证接口)
安全测试关联点¶
-
输入验证:所有用户输入必须验证(白名单 > 黑名单),防止 SQL 注入、命令注入、路径遍历、XXE、SSRF。验证包括类型、长度、格式、范围、业务规则
-
认证与授权:Session/JWT/OAuth 机制的安全性。测试 Token 是否可伪造、Session 是否固定、授权码是否可劫持、Scope 是否越权
-
业务逻辑漏洞:
-
支付金额篡改:修改支付接口的金额参数(如 1 元购买 1000 元商品)
-
越权访问:修改资源 ID 参数访问他人数据(如
user_id=1改为user_id=2) -
并发竞态条件(Race Condition):同时提交多个请求,利用时间差绕过限制(如同时提交多次抽奖、同时使用同一张优惠券)
-
条件竞争:在检查条件和执行操作之间的时间窗口内篡改状态(如先检查余额再扣款,利用延迟重复扣款)
-
敏感信息泄露:错误堆栈信息(
stack trace)、调试信息(debug=true)、配置文件(.env、.git、.svn)、API 文档(Swagger UI 未授权访问)、日志文件(包含密码、Token)
反序列化漏洞¶
- 反序列化漏洞
Java(ObjectInputStream)、Python(pickle/yaml.load/json.load 配合 __reduce__)、PHP(unserialize)、.NET(BinaryFormatter/Json.Net TypeNameHandling)的反序列化可导致 RCE。
防御:不使用原生反序列化、使用 JSON 等安全格式、白名单类名过滤。
- SSRF(Server-Side Request Forgery)
后端发起请求时的地址可控,攻击者让服务器访问内部资源(如 http://127.0.0.1、http://169.254.169.254 云元数据服务)、进行端口扫描、攻击内网服务。
防御:URL 白名单、禁用不必要的协议、内网 IP 黑名单、统一代理出口。
- XXE(XML External Entity)
XML 解析器处理外部实体时,可读取本地文件、发起 SSRF、执行 SSRF 导致的 DoS(Billion Laughs)。
防御:禁用外部实体、使用 JSON 替代 XML、使用安全的 XML 解析器配置。
- 不安全的直接对象引用(IDOR)
直接使用数据库 ID 暴露给用户,如 /api/orders/123 可通过遍历 ID 获取他人订单。
防御:使用 UUID 或随机 ID、严格的权限校验。
- Mass Assignment
批量赋值漏洞,客户端提交额外字段修改不应允许的属性(如注册时提交 is_admin=true)。
防御:白名单字段过滤、DTO 模式。
-
HTTP 参数污染(HPP):提交多个同名参数,不同框架/服务器取不同位置的值导致逻辑绕过。如
?role=user&role=admin,某些服务器取最后一个值 -
API 版本控制漏洞:旧版本 API 未废弃且未修补漏洞,攻击者通过指定旧版本绕过新版本的防护