santifer/career-ops · error · Error
arbeitnow: untrusted hostname "${parsed.hostname}" — must be
Error message
arbeitnow: untrusted hostname "${parsed.hostname}" — must be ${TRUSTED_HOST} What it means
The hostname-allowlist step of arbeitnow's SSRF guard. After scheme validation, the provider requires `parsed.hostname === 'www.arbeitnow.com'` exactly. Any other host — even a look-alike — is rejected so a server-side or config-level redirect cannot exfiltrate requests to an attacker-controlled domain.
Source
Thrown at providers/arbeitnow.mjs:34
// Wire in via a `job_boards:` entry with `provider: arbeitnow`.
const FEED_BASE = 'https://www.arbeitnow.com/api/job-board-api';
const TRUSTED_HOST = 'www.arbeitnow.com';
const PER_PAGE = 100;
const DEFAULT_MAX_PAGES = 3;
const MAX_PAGES_CAP = 50;
/** @param {string} url */
function assertArbeitnowUrl(url) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new Error(`arbeitnow: invalid URL: ${url}`);
}
if (parsed.protocol !== 'https:') throw new Error(`arbeitnow: URL must use HTTPS: ${url}`);
if (parsed.hostname !== TRUSTED_HOST) {
throw new Error(`arbeitnow: untrusted hostname "${parsed.hostname}" — must be ${TRUSTED_HOST}`);
}
return url;
}
/** Resolve the page cap: a positive integer `max_pages` on the entry, capped. */
function resolveMaxPages(entry) {
const v = entry?.max_pages;
if (Number.isInteger(v) && v > 0) return Math.min(v, MAX_PAGES_CAP);
return DEFAULT_MAX_PAGES;
}
/**
* Normalize a single Arbeitnow job. Exported for unit tests.
*
* Field mapping → the normalized Job shape:
* - title: `title`, trimmed (items without one are dropped).
* - url: `url` — an absolute `https:` posting URL host-locked to
* www.arbeitnow.com (an off-host or non-https URL is untrusted andView on GitHub (pinned to 9b17a8ac97)
Solutions
- Keep `TRUSTED_HOST` as `www.arbeitnow.com` and use only the canonical API endpoint.
- If a genuinely new host must be allowed, add it explicitly to a trusted set rather than loosening the check to a suffix.
- Audit the URL for trailing-host tricks (e.g. `www.arbeitnow.com.attacker.tld`) that pass naive `endsWith` checks.
Example fix
// before (rejected — wrong host) const FEED_BASE = 'https://api.arbeitnow.com/api/job-board-api'; // after const FEED_BASE = 'https://www.arbeitnow.com/api/job-board-api';
Defensive patterns
Strategy: validation
Validate before calling
const TRUSTED_HOST = 'www.arbeitnow.com';
function assertTrustedHost(u) {
const p = new URL(u);
if (p.hostname !== TRUSTED_HOST) {
throw new Error(`untrusted host ${p.hostname}; expected ${TRUSTED_HOST}`);
}
}
assertTrustedHost(FEED_BASE); Prevention
- Never loosen the host check to a suffix/contains test — that admits spoofed hosts.
- If a new host must be trusted, add it to an explicit allowlist set and document why.
- Audit config for URLs that bypass the constant FEED_BASE.
When it happens
Trigger: `parsed.hostname` is anything other than `www.arbeitnow.com`: a subdomain (`api.arbeitnow.com`), an apex (`arbeitnow.com`), a spoofed host (`www.arbeitnow.com.evil.tld`), or an entirely different domain.
Common situations: Pointing the provider at a mirror, staging, or proxy host; a typo in `FEED_BASE`; or an attempt to reuse the provider for a different job board that happens to share the API shape.
Related errors
- ashby: untrusted hostname "${parsed.hostname}" — must be one
- bamboohr: untrusted hostname "${parsed.hostname}" — must mat
- breezy: untrusted hostname "${parsed.hostname}" — must match
- larajobs: untrusted hostname "${parsed.hostname}" - must be
- lever: untrusted hostname "${parsed.hostname}" — must be one
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/7f27540777bf4ef6.
Report an issue: GitHub.