Postman 的优势在于其强大的脚本(Pre-request Script 和 Tests Script)和集合运行器(Collection Runner),能够自动化、系统化地模拟各种篡改情况。
主要API防篡改验证包括:
1.签名验证机制: API 服务器使用预定义的算法(如 HMAC-SHA256)为请求生成数字签名。任何对参数、Body 或头的修改都会导致签名失效。
2.参数完整性校验: 服务器会检查关键参数是否被篡改,特别是那些影响业务逻辑的参数(如 userId, amount, price)。
3.防重放攻击机制: 通过时间戳(Timestamp)、随机数(Nonce)或序列号确保同一请求不能被重复提交。
4.时效性验证: 请求是否在有效时间窗口内,防止过时请求被恶意重放。
Postman 的脚本能力可以精准地针对上述每一点进行自动化测试。

专业测试流程:
创建 Collection 和环境变量
新建一个 Collection,命名为 API Tamper Resistance Tests。
创建环境变量,用于集中管理配置:
api_base_url: https://api.yourdomain.com
api_key: your_api_key
secret_key: your_secret_key (用于签名计算,切勿硬编码在脚本中,最好通过变量在运行时注入)
auth_token: (用于存储登录后获得的令牌)
假设我们有一个转账 API:POST /api/v1/transfer
请求体 (JSON):
bash
json
{
"fromAccount": "user123",
"toAccount": "user456",
"amount": 100.00,
"currency": "USD",
"timestamp": 1627891234,
"nonce": "abc123def"
}
正常请求(基准测试)
在 Collection 的 Pre-request Script 选项卡中,编写通用签名函数。这样每个请求在执行前都会自动计算签名。
javascript
// Collection-Level Pre-request Script: 通用签名函数
function generateSignature(secret, method, path, body, timestamp, nonce) {
// 1. 构建待签名的字符串:方法、路径、排序后的参数、时间戳、随机数等
const stringToSign = `${method}\n${path}\n${JSON.stringify(body)}\n${timestamp}\n${nonce}`;
// 2. 使用 CryptoJS 库进行 HMAC-SHA256 签名
const signature = CryptoJS.HmacSHA256(stringToSign, secret).toString(CryptoJS.enc.Hex);
return signature;
}
// 获取当前时间戳和生成随机数
const timestamp = Math.floor(Date.now() / 1000);
const nonce = CryptoJS.lib.WordArray.random(16).toString(); // 生成16字节随机数
// 将变量设置到集合级别,供请求使用
pm.collectionVariables.set("timestamp", timestamp);
pm.collectionVariables.set("nonce", nonce);
// 计算当前请求的签名
const secretKey = pm.collectionVariables.get("secret_key");
const requestMethod = pm.request.method;
const requestPath = pm.request.url.getPath(); // 获取 URL 路径,如 /api/v1/transfer
const requestBody = pm.request.body.raw ? JSON.parse(pm.request.body.raw) : {};
const calculatedSignature = generateSignature(secretKey, requestMethod, requestPath, requestBody, timestamp, nonce);
pm.collectionVariables.set("request_signature", calculatedSignature);
在请求的 Headers 中,引用计算出的签名、时间戳和随机数:
bash
// 验证正常请求是否成功
pm.test("Normal request should be successful", function () {
pm.response.to.have.status(200);
pm.expect(pm.response.json().code).to.eql(0);
});
现在,我们复制上面的正常请求,创建多个副本,每个副本针对一种篡改场景。
使用错误的签名。
Postman 实现:
复制请求,重命名为 [Tamper] Invalid Signature。
在其 Pre-request Script 中,覆盖签名值为一个错误值。
javascript
// 覆盖正确的签名为一个明显错误的签名
pm.collectionVariables.set("request_signature", "invalid_malicious_signature_here");
API 应返回 401 Unauthorized 或 403 Forbidden。在 Tests 中验证:
javascript
pm.test("Tampered signature should be rejected", function () {
pm.response.to.have.status(401); // 或 403
});
修改业务参数
攻击方式: 修改请求体中的 amount(金额)或 toAccount(收款人)。
Postman 实现:
1.复制请求,重命名为 [Tamper] Modified Amount。
2.在 Body 选项卡中,将 "amount": 100.00 改为 "amount": 10000.00。
保持 Pre-request Script 不变。这样,请求体被修改了,但签名还是用原始参数计算的。服务器用收到的参数重新计算签名,会发现与请求头中的签名不匹配。
结果: 401/403 错误。
测试防重放攻击 - 重复使用 Nonce
重复发送完全相同的请求(包括相同的 Nonce 和 Timestamp)
Postman 实现:
复制请求,重命名为 [Tamper] Replay Attack。
在其 Pre-request Script 中,手动设置一个已经使用过的 nonce 和 timestamp。
javascript
// 使用一个固定的、已经用过的 nonce 和 timestamp
pm.collectionVariables.set("nonce", "previously_used_nonce_value");
pm.collectionVariables.set("timestamp", 1627891000); // 一个旧的 timestamp
// 注意:签名需要基于这些旧值重新计算,脚本会自动处理
结果:API 应返回 400 Bad Request 或 409 Conflict,并提示 "Nonce already used" 或 "Request expired"。
测试时效性验证 - 使用过期时间戳
发送一个时间戳远远超出服务器允许时间窗口(如 ±5 分钟)的请求。
Postman 实现:
复制请求,重命名为 [Tamper] Expired Timestamp。
在其 Pre-request Script 中,将时间戳设置为一天前。
javascript
const oneDayAgo = Math.floor(Date.now() / 1000) - (24 * 60 * 60);
pm.collectionVariables.set("timestamp", oneDayAgo);
结果: 400 Bad Request, "Request timestamp expired".