santifer/career-ops · error · Error

nofluffjobs: URL must use HTTPS: ${url}

Error message

nofluffjobs: URL must use HTTPS: ${url}

What it means

Thrown by nofluffjobs' assertNoFluffUrl() when the URL parses but its protocol is not 'https:'. This is the second SSRF gate preventing plaintext HTTP fetches that are vulnerable to MITM and redirect-based SSRF. Fires before any network request.

Source

Thrown at providers/nofluffjobs.mjs:21

// NoFluffJobs provider — hits the public search posting API.
// It intentionally returns only the core scanner job fields; richer skill and
// salary metadata can be added later if the provider contract is expanded.

const ALLOWED_HOSTS = new Set(['nofluffjobs.com']);
const API_URL = 'https://nofluffjobs.com/api/search/posting';
const JOB_BASE = 'https://nofluffjobs.com/pl/job/';
const PAGE_SIZE = 20;
const MAX_PAGES = 5;

function assertNoFluffUrl(url) {
  let parsed;
  try {
    parsed = new URL(url);
  } catch {
    throw new Error(`nofluffjobs: invalid URL: ${url}`);
  }
  if (parsed.protocol !== 'https:') throw new Error(`nofluffjobs: URL must use HTTPS: ${url}`);
  if (!ALLOWED_HOSTS.has(parsed.hostname)) {
    throw new Error(`nofluffjobs: untrusted hostname "${parsed.hostname}" — must be nofluffjobs.com`);
  }
  return parsed;
}

function detectUrl(entry) {
  const url = entry.api || entry.careers_url || '';
  if (typeof url !== 'string' || !url.trim()) return null;
  try {
    return { url: assertNoFluffUrl(url).href };
  } catch {
    return null;
  }
}

function normalizeLocation(posting) {
  const parts = [];

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Update the URL in portals.yml (api or careers_url) to use https://.
  2. For local testing, run the mock on HTTPS or inject a test-only bypass.
  3. Audit any script that generates portals.yml entries to enforce https:// as the default scheme.

Example fix

// before
api: 'http://nofluffjobs.com/api/search/posting'

// after
api: 'https://nofluffjobs.com/api/search/posting'
Defensive patterns

Strategy: validation

Validate before calling

/** Normalize URL to HTTPS before passing to the provider. */
function ensureHttps(url) {
  if (typeof url !== 'string') return null;
  return url.replace(/^http:\/\//i, 'https://');
}

entry.api = ensureHttps(entry.api) || entry.api;

Type guard

/** @param {string} url @returns {boolean} */
function isHttpsUrl(url) {
  try { return new URL(url).protocol === 'https:'; } catch { return false; }
}

Try / catch

try {
  await nofluffProvider.fetch(entry, ctx);
} catch (err) {
  if (String(err.message).includes('must use HTTPS')) {
    entry.api = (entry.api || '').replace(/^http:/i, 'https:');
    await nofluffProvider.fetch(entry, ctx);
  } else throw err;
}

Prevention

When it happens

Trigger: A valid URL with an http: (or other non-https) scheme is passed. Typical: entry.api or entry.careers_url in portals.yml prefixed with http:// instead of https://. Also fires in test setups pointing at http://localhost.

Common situations: Copy-pasting a URL from a browser address bar that didn't auto-upgrade to HTTPS. A config-management tool or environment variable that strips the scheme or defaults to http. Local development against a non-TLS mock server.

Related errors


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