santifer/career-ops · error · Error
larajobs: untrusted hostname "${parsed.hostname}" - must be
Error message
larajobs: untrusted hostname "${parsed.hostname}" - must be ${TRUSTED_HOST} What it means
The third guard in assertLarajobsUrl: even a valid HTTPS URL must have hostname exactly equal to TRUSTED_HOST ('larajobs.com'). Any other host — including look-alikes or subdomains — is rejected. This is an SSRF defence: it stops a config change from making the scanner fetch an attacker-controlled or off-brand endpoint.
Source
Thrown at providers/larajobs.mjs:28
// `<job:company>` and `<job:location>`, so company and location come straight
// from the feed (no title-splitting heuristics needed).
//
// Wire in via a `job_boards:` entry with `provider: larajobs`.
const FEED_URL = 'https://larajobs.com/feed';
const TRUSTED_HOST = 'larajobs.com';
/** @param {string} url */
function assertLarajobsUrl(url) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new Error(`larajobs: invalid URL: ${url}`);
}
if (parsed.protocol !== 'https:') throw new Error(`larajobs: URL must use HTTPS: ${url}`);
if (parsed.hostname !== TRUSTED_HOST) {
throw new Error(`larajobs: untrusted hostname "${parsed.hostname}" - must be ${TRUSTED_HOST}`);
}
return url;
}
// NaN-safe Date.parse - `|| undefined` would also coerce a valid epoch 0.
function toEpochMs(value) {
if (!value) return undefined;
const parsed = Date.parse(value);
return Number.isNaN(parsed) ? undefined : parsed;
}
function fallbackCompany(entry) {
return typeof entry?.name === 'string' && entry.name.trim() ? entry.name.trim() : 'LaraJobs';
}
/** @type {Provider} */
export default {
id: 'larajobs',View on GitHub (pinned to 9b17a8ac97)
Solutions
- Correct the URL to use exactly https://larajobs.com (no subdomain).
- If the feed legitimately moved hosts, update TRUSTED_HOST in providers/larajobs.mjs after verifying the new host is the official Larajobs endpoint.
- Audit git history of portals.yml for the offending change.
Example fix
// before api: https://www.larajobs.com/feed // after api: https://larajobs.com/feed
Defensive patterns
Strategy: validation
Validate before calling
import { URL } from 'node:url';
const TRUSTED = new Set(['larajobs.com']);
export function isTrustedLarajobsHost(value) {
try { return TRUSTED.has(new URL(value).hostname); } catch { return false; }
} Type guard
/** @param {string} url */
function isLarajobsHost(url) {
try { return new URL(url).hostname === 'larajobs.com'; } catch { return false; }
} Try / catch
try {
assertLarajobsUrl(url);
} catch (err) {
// an untrusted-host error is a security signal — log loudly, do not silently fall back
if (err.message.includes('untrusted hostname')) console.error(`[security] ${err.message}`);
throw err;
} Prevention
- Never override TRUSTED_HOST to silence the error without verifying the new host is the official Larajobs endpoint.
- Audit portals.yml for look-alike domains (larajobs.net, larajob.com) in CI.
- Treat an untrusted-hostname failure as a potential SSRF attempt, not a routine config typo.
When it happens
Trigger: An HTTPS URL whose hostname is not 'larajobs.com' — e.g. www.larajobs.com, api.larajobs.com, larajobs.com.evil.com, feed.larajobs.net, or an internal IP/host. The offending hostname is interpolated into the message.
Common situations: Someone added a www. prefix or a subdomain; a copy-paste brought in a similar domain; a malicious or mistaken config points the feed elsewhere; the trusted host genuinely moved and the constant needs updating.
Related errors
- lever: untrusted hostname "${parsed.hostname}" — must be one
- manfred: untrusted hostname "${parsed.hostname}" — must be $
- Refusing non-HTTP(S) URL: ${url}
- arbeitnow: untrusted hostname "${parsed.hostname}" — must be
- ashby: untrusted hostname "${parsed.hostname}" — must be one
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/de721dc69a08c9a2.
Report an issue: GitHub.