Chrome 152 DevTools can Resend XHR and other fetchable requests, and it can display binary request payloads as Hex, Base64, or UTF-8. The fastest safe habit is to create a redacted evidence record before you replay anything.
The record should answer: Did the status, timing, route, or payload fingerprint change? It should not contain a reusable secret.
Define an allowlist, not a denylist
Do not try to enumerate every possible secret header. Keep only fields you know are necessary.
const SAFE_HEADERS = new Set([
"accept",
"content-type",
"content-length",
"user-agent",
"x-request-id",
]);
function safeHeaders(headers) {
const out = {};
for (const [name, value] of Object.entries(headers)) {
const key = name.toLowerCase();
if (SAFE_HEADERS.has(key)) out[key] = String(value);
}
return out;
}
This excludes Authorization, Proxy-Authorization, cookies, CSRF tokens, signed URLs stored in custom headers, and vendor-specific credentials by default.
Fingerprint the body locally
For binary or compressed payloads, store a digest and byte length instead of the full body.
async function bodyEvidence(arrayBuffer) {
const bytes = new Uint8Array(arrayBuffer);
const digest = await crypto.subtle.digest("SHA-256", bytes);
const sha256 = [...new Uint8Array(digest)]
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
return {
bytes: bytes.byteLength,
sha256,
};
}
Do not paste production payloads into an online hashing service. Compute the fingerprint in an approved local environment, then discard the raw copy when retention policy requires it.
Normalize one attempt
function normalizeAttempt(input) {
return {
capturedAtUtc: new Date(input.capturedAt).toISOString(),
browserVersion: input.browserVersion,
requestNumber: input.requestNumber,
method: input.method,
host: input.host,
status: input.status,
remoteAddressLabel: input.remoteAddressLabel,
proxyRegion: input.proxyRegion,
routeVerified: Boolean(input.routeVerified),
timingMs: {
queueing: input.timingMs.queueing,
connect: input.timingMs.connect,
ssl: input.timingMs.ssl,
waiting: input.timingMs.waiting,
total: input.timingMs.total,
},
headers: safeHeaders(input.headers),
payload: input.payloadEvidence,
result: input.result, // pass | fail | inconclusive
};
}
Use a label for the remote address if raw infrastructure details are not appropriate for the ticket. The important claim is whether the intended proxy route was verified and whether direct fallback was excluded.
Compare three attempts
Capture:
- the original failure;
- one unchanged DevTools resend;
- one single-variable test.
function diffAttempt(before, after) {
const fields = [
"status",
"remoteAddressLabel",
"proxyRegion",
"routeVerified",
"result",
];
const changes = {};
for (const field of fields) {
if (before[field] !== after[field]) {
changes[field] = { before: before[field], after: after[field] };
}
}
for (const phase of Object.keys(before.timingMs)) {
if (before.timingMs[phase] !== after.timingMs[phase]) {
changes[`timingMs.${phase}`] = {
before: before.timingMs[phase],
after: after.timingMs[phase],
};
}
}
if (before.payload?.sha256 !== after.payload?.sha256) {
changes.payloadSha256 = {
before: before.payload?.sha256,
after: after.payload?.sha256,
};
}
return changes;
}
Do not automate the actual resend for destructive methods. A human should review POST, PUT, PATCH, and DELETE side effects and use a sandbox or idempotency mechanism.
Interpret the result by layer
| Signal | First place to look |
|---|---|
407 before destination headers |
Proxy authentication |
| Proxy certificate failure | Browser-to-proxy TLS |
| Timeout before destination response | DNS, network, or gateway |
Destination 403
|
Application authorization or target policy |
Destination 429
|
Rate limit; stop replaying |
| Success only in a warm tab | Cookies, service worker, token, or connection state |
Chrome 152 may represent the resend as a fetch() call. Record execution context and console originator; browser replay is not guaranteed to be byte-identical at the wire.
Minimum gate
- Use an authorized test account and endpoint.
- Replay only idempotent or duplicate-safe operations.
- Keep a strict request budget.
- Capture the original before changing anything.
- Change one variable at a time.
- Verify the proxy route and block direct fallback.
- Store fingerprints, not credential-bearing bodies.
- Mark uncertain results
inconclusive.
Disclosure: I work with 98IP. We publish proxy engineering guides for authorized and policy-compliant testing. https://en.98ip.com/?k=dev
Top comments (0)