{"record":{"id":"0f7e1579a4137b70","repo":"santifer/career-ops","slug":"blocked-request-to-restricted-destination-reque","errorCode":null,"errorMessage":"Blocked request to restricted destination: ${requestUrl}","messagePattern":"Blocked request to restricted destination: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"liveness-browser.mjs","lineNumber":256,"sourceCode":"    }\n  }\n}\n\nexport async function checkUrlLiveness(page, url, { extraSettleMs = 0 } = {}) {\n  const guardError = rejectPrivateOrInvalid(url);\n  if (guardError) {\n    return { result: 'uncertain', code: guardError.code, reason: guardError.reason };\n  }\n  if (page) {\n    page._blockedByGuard = null;\n  }\n  if (page && typeof page.route === 'function' && !page._routeInterceptorRegistered) {\n    page._routeInterceptorRegistered = true;\n    await page.route('**/*', async (route) => {\n      const requestUrl = route.request().url();\n      const errGuard = rejectPrivateOrInvalid(requestUrl);\n      if (errGuard) {\n        console.warn(`Blocked request to restricted destination: ${requestUrl}`);\n        page._blockedByGuard = errGuard;\n        return route.abort('blockedbyclient');\n      }\n      try {\n        await validateUrlSecurity(requestUrl);\n        return route.continue();\n      } catch (err) {\n        console.warn(`Blocked request to restricted destination (DNS): ${requestUrl} - ${err.message}`);\n        // A host that resolves to nothing is a DEAD THIRD-PARTY SCRIPT, not a\n        // statement about the posting. Measured 2026-08-14 over a 217-URL\n        // recheck: 78 live postings were returned as `uncertain` because an\n        // analytics or ad host on the page no longer exists — 53 on\n        // personalisation.visitorqueue.com, 17 on s7.addthis.com (AddThis was\n        // shut down in 2023), the rest on fluidads and cloudfront. One was\n        // opened by hand to confirm: 11,178 characters of live posting and a\n        // working apply control, called uncertain because of a dead tracker.\n        //\n        // The request is still aborted either way, so the egress guard loses","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/santifer/career-ops/blob/60398d6549a46f5266929538af21cfab94badc75/liveness-browser.mjs#L238-L274","documentation":"Not a malfunction: this is the first layer of the SSRF egress guard in liveness-browser.mjs reporting that it aborted a request. rejectPrivateOrInvalid examined a URL emitted by the checked page and matched a private or invalid destination — localhost/127.0.0.1, RFC1918 ranges (10.x, 172.16-31.x, 192.168.x), link-local 169.254.x, IPv6-mapped forms, .local names, non-http(s) protocols (code unsupported_protocol), or an unparseable URL (code invalid_url) — and the route was aborted with blockedbyclient. The liveness check continues; only that subresource was refused.","triggerScenarios":"A checked posting page loads a tracker, script, or image from http://localhost:*, a private-range IP, a .local hostname, or a non-http(s) URI; every such request is aborted and logged with its URL.","commonSituations":"Career pages wired to internal-only analytics collectors; staging/dev pages left public; test setups deliberately pointing the checker at pages that reference internal hosts.","solutions":["No action needed when the posting still renders — subresource blocks do not affect the verdict.","If the MAIN document URL is the blocked one, you passed a private-network URL to the checker; re-run with the public posting URL.","Do not disable the guard to silence the line — the block is the tool protecting your network from SSRF via fetched pages."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { rejectPrivateOrInvalid, validateUrlSecurity } from './liveness-browser.mjs';\nconst preflight =\n  rejectPrivateOrInvalid(url) ??\n  (await validateUrlSecurity(url).then(() => null, (e) => e));\nif (preflight) throw new Error(`Refusing non-public URL up front: ${url}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only feed public http(s) URLs to the liveness checker","Expect these lines on pages with internal or dead trackers — they are guard telemetry, not failures","Read the returned code (blocked_host / unsupported_protocol / invalid_url) to tell a guard hit from a dead posting"],"tags":["ssrf","egress-guard","playwright-route","security"],"backgroundTag":"ssrf-private-address-blocked","analyzedSha":"60398d6549a46f5266929538af21cfab94badc75","analyzedAt":"2026-08-20T23:00:06.764Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}