如何通过Security Rules实现增量(+1)字段安全防护,避免前端滥用?
问题描述
前端通过Firebase的increment(+1)操作更新文档的count字段,用于限制关联子集合的文档创建次数,但当前Security Rules无法有效防止恶意篡改:
当前前端代码
// Initial Payload const surfacePayload: SurfacePayload = { gender: selected.gender, unit: unit.current, // 预期让数据库count字段自增+1 count: increment(+1), src: currentUser?.uid!, }; await setDoc(doc(db, docRef), surfacePayload);
现有Security Rules
// 仅校验类型和最大值,无增量逻辑校验 request.resource.data.count is number && request.resource.data.count <= 12
核心顾虑
恶意前端可篡改count值(比如反复传入0或1),绕过基于当前文档状态的增量限制;曾尝试用resource.data校验当前状态,但因未区分文档首次创建和更新场景而失败。
解决方案
通过区分文档首次创建和已有文档更新两种场景,实现严格的增量校验:
最终Security Rules
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{docPath}/{document=**} { allow write: if // 基础校验:类型合法且不超过上限 request.resource.data.count is number && request.resource.data.count <= 12 && // 增量逻辑校验:分场景判断 ( // 场景1:文档首次创建,count必须为1(对应首次+1的结果) !exists(resource) && request.resource.data.count == 1 || // 场景2:已有文档更新,count必须等于当前值+1 exists(resource) && request.resource.data.count == resource.data.count + 1 ); } } }
关键逻辑说明
exists(resource)用于判断目标文档是否已存在:- 首次创建时,
resource为空,此时count必须为1(符合前端首次调用increment(+1)的预期) - 已有文档更新时,强制要求新
count值等于旧值+1,彻底阻断恶意篡改增量的可能
- 首次创建时,
- 保留原有的类型和最大值校验,确保
count始终在合法范围内
内容的提问来源于stack exchange,提问作者Richardson
相关产品推荐
相关产品推荐

