santifer/career-ops · error · Error

oraclecloud: untrusted hostname "${parsed.hostname}" — must

Error message

oraclecloud: untrusted hostname "${parsed.hostname}" — must match *.fa[.<region>][.ocs].oraclecloud[1-99].com

What it means

Thrown by oraclecloud's assertOracleUrl() when the hostname doesn't match ORACLE_HOST_RE (/^[a-z0-9-]+\.fa\.(?:[a-z0-9-]+\.)?(?:ocs\.)?oraclecloud(?:[1-9][0-9]?)?\.com$/i). Third SSRF gate: allows tenant subdomains of Oracle's FA (Fusion Applications) cloud (e.g. acme.fa.eu.oraclecloud.com, acme.fa.ocs.oraclecloud.com, acme.fa.oraclecloud1.com) while blocking everything else. The regex permits an optional region segment, an optional 'ocs.' segment, and an optional numeric suffix on 'oraclecloud'.

Source

Thrown at providers/oraclecloud.mjs:70

const PAGE_SIZE = 200;
const MAX_PAGES = 25;             // safety cap (~5000 jobs); hard ceiling like workday
const RETRY_POLICY = { retries: 3 };
const INTER_PAGE_DELAY_MS = 150;  // WAF-aware spacing between same-host pages

// facetsList is a fixed constant on the finder; %3B is the encoded ';' separator.
const FACETS_LIST = 'LOCATIONS%3BWORK_LOCATIONS%3BWORKPLACE_TYPES%3BTITLES%3BCATEGORIES%3BORGANIZATIONS%3BPOSTING_DATES%3BFLEX_FIELDS';

/** @param {string} url */
function assertOracleUrl(url) {
  let parsed;
  try {
    parsed = new URL(url);
  } catch {
    throw new Error(`oraclecloud: invalid URL: ${url}`);
  }
  if (parsed.protocol !== 'https:') throw new Error(`oraclecloud: URL must use HTTPS: ${url}`);
  if (!ORACLE_HOST_RE.test(parsed.hostname)) {
    throw new Error(`oraclecloud: untrusted hostname "${parsed.hostname}" — must match *.fa[.<region>][.ocs].oraclecloud[1-99].com`);
  }
  return url;
}

// NaN-safe Date.parse — `|| undefined` would also coerce a valid epoch 0.
// (copied from greenhouse.mjs)
function toEpochMs(value) {
  if (!value) return undefined;
  const parsed = Date.parse(value);
  return Number.isNaN(parsed) ? undefined : parsed;
}

function sleep(ms, ctx) {
  if (typeof ctx?.sleep === 'function') return ctx.sleep(ms);
  return new Promise((resolve) => setTimeout(resolve, ms));
}

/**

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Verify the URL matches the expected pattern: <tenant>.fa.<region>.oraclecloud.com — confirm the .fa. segment is present.
  2. Get the correct URL from the Oracle HCM career site: navigate to the company's career page and copy the full URL from the browser.
  3. If Oracle introduced a new URL format (new region, new subdomain), update ORACLE_HOST_RE at providers/oraclecloud.mjs:50 to match.
  4. Check for TLD confusion: must be .com, not .net or .cloud.

Example fix

// before — wrong URL shape
careers_url: 'https://acme.oraclecloud.com/careers'
// hostname 'acme.oraclecloud.com' fails: missing '.fa.' segment

// after
careers_url: 'https://acme.fa.eu.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1'

// OR if Oracle introduced a new subdomain pattern, update the regex:
// const ORACLE_HOST_RE = /^[a-z0-9-]+\.fa\.(?:[a-z0-9-]+\.)?(?:ocs\.)?oraclecloud(?:[1-9][0-9]?)?\.com$/i;
Defensive patterns

Strategy: validation

Validate before calling

const ORACLE_HOST_RE = /^[a-z0-9-]+\.fa\.(?:[a-z0-9-]+\.)?(?:ocs\.)?oraclecloud(?:[1-9][0-9]?)?\.com$/i;

/** Check hostname matches Oracle FA cloud pattern. */
function isOracleFaHost(url) {
  try { return ORACLE_HOST_RE.test(new URL(url).hostname); } catch { return false; }
}

if (!isOracleFaHost(entry.careers_url)) {
  console.warn(`oraclecloud entry ${entry.name} URL doesn't match *.fa.*.oraclecloud.com`);
  continue;
}

Type guard

/** @param {string} url @returns {boolean} */
function isOracleCloudUrl(url) {
  const ORACLE_HOST_RE = /^[a-z0-9-]+\.fa\.(?:[a-z0-9-]+\.)?(?:ocs\.)?oraclecloud(?:[1-9][0-9]?)?\.com$/i;
  try { return ORACLE_HOST_RE.test(new URL(url).hostname); } catch { return false; }
}

Try / catch

try {
  await oracleProvider.fetch(entry, ctx);
} catch (err) {
  if (String(err.message).includes('untrusted hostname')) {
    console.warn(`oraclecloud entry ${entry.name} wrong host — needs *.fa.*.oraclecloud.com`);
    continue;
  }
  throw err;
}

Prevention

When it happens

Trigger: The hostname is valid HTTPS but not an Oracle FA cloud host: e.g. 'oraclecloud.com' (bare, no tenant.fa. prefix), 'careers.oracle.com', 'acme.fa.oraclecloud.net' (wrong TLD), or an attacker-controlled domain. Common misforms: missing the '.fa.' segment, using '.oci.' instead of '.fa.', or a non-cloud Oracle domain.

Common situations: The entry points to a non-careers Oracle domain (oracle.com instead of oraclecloud.com). The tenant URL was copied incorrectly, missing the .fa. path segment. Oracle restructured their cloud URL format (e.g. new region or ocs subdomain) and the regex needs updating. A developer used an OCI (Oracle Cloud Infrastructure) console URL instead of the HCM career site URL.

Related errors


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/680f9583ad9c09b1. Report an issue: GitHub.