63 lines
2.3 KiB
TypeScript
63 lines
2.3 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
// Detect requests to private/local address space or PNA preflight headers.
|
|
test('detect private/local network requests and PNA preflights', async ({ page }) => {
|
|
const privateRequests: Array<any> = [];
|
|
|
|
function isPrivateHostname(hostname: string) {
|
|
if (!hostname) return false;
|
|
// hostnames that resolve to local addresses or explicitly localhost
|
|
if (hostname === 'localhost' || hostname.endsWith('.localhost')) return true;
|
|
// IPv4 private ranges
|
|
if (/^(127)\.|^(10)\.|^(192\.168)\.|^172\.(1[6-9]|2[0-9]|3[0-1])\./.test(hostname)) return true;
|
|
return false;
|
|
}
|
|
|
|
page.on('request', (request) => {
|
|
try {
|
|
const url = new URL(request.url());
|
|
const headers = request.headers();
|
|
const hostname = url.hostname;
|
|
|
|
const pnaHeader = (headers['access-control-request-private-network'] || headers['Access-Control-Request-Private-Network']);
|
|
|
|
if (isPrivateHostname(hostname) || pnaHeader === 'true') {
|
|
privateRequests.push({
|
|
url: request.url(),
|
|
method: request.method(),
|
|
resourceType: request.resourceType(),
|
|
pnaPreflight: pnaHeader === 'true',
|
|
headers
|
|
});
|
|
}
|
|
} catch (e) {
|
|
// ignore parse errors
|
|
}
|
|
});
|
|
|
|
page.on('requestfailed', (r) => {
|
|
// capture failed requests that might be private and blocked
|
|
try {
|
|
const url = new URL(r.url());
|
|
if (isPrivateHostname(url.hostname)) {
|
|
privateRequests.push({ url: r.url(), method: r.method(), failure: r.failure() });
|
|
}
|
|
} catch (e) {}
|
|
});
|
|
|
|
// Navigate to the dev site used in other tests.
|
|
await page.goto('http://demo.localhost:5173/');
|
|
|
|
// Wait for network to settle.
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
if (privateRequests.length > 0) {
|
|
console.error('Detected private/local requests or PNA preflights:');
|
|
for (const r of privateRequests) {
|
|
console.error(JSON.stringify(r, null, 2));
|
|
}
|
|
}
|
|
|
|
expect(privateRequests.length, 'No private/local network requests or PNA preflights should be made').toBe(0);
|
|
});
|