# Referrer-Policy Auditor (`phoenix2810/referrer-policy-auditor`) Actor

Fetch one public URL and deeply audit its Referrer-Policy HTTP header and meta referrer tag. Validates directives, detects deprecated values, flags conflicts, and returns a privacy posture score, grade, issues, and recommendations.

- **URL**: https://apify.com/phoenix2810/referrer-policy-auditor.md
- **Developed by:** [Sanskar Jaiswal](https://apify.com/phoenix2810) (community)
- **Categories:** Developer tools, SEO tools, Open source
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Referrer-Policy Auditor

Fetches one public URL and deeply audits its `Referrer-Policy` HTTP response header and HTML `<meta name="referrer">` tag. Validates policy directives against the Referrer Policy spec, detects privacy-leaking and deprecated values, flags conflicting multiple headers, evaluates effective policy precedence (HTTP header over meta tag), and returns a privacy posture readiness score, letter grade, issues, and recommendations. Built for security teams, devops engineers, privacy/compliance auditors, frontend platform teams, and site migration QA workflows.

### Use cases

- Verify that a `Referrer-Policy` header is set after a deploy or CDN cutover to prevent referrer URL leakage to third parties.
- Detect privacy-leaking directives such as `unsafe-url` or `no-referrer-when-downgrade` that send full URLs in `Referer` headers.
- Identify invalid directives that browsers silently ignore, leaving the page with no explicit policy.
- Check whether a `<meta name="referrer">` tag is used as a fallback and whether it conflicts with the HTTP header.
- Flag conflicting multiple `Referrer-Policy` header values where the last valid directive wins per spec.
- Evaluate the effective policy (header takes precedence over meta) and classify privacy posture as strong, balanced, weak, or none.
- Run scheduled checks on domains to catch referrer policy drift after deploys, CDN changes, and framework updates.
- Feed structured results into security dashboards or CI pipelines.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `startUrl` | string | Public HTTP or HTTPS URL to audit. The actor fetches this page and inspects the `Referrer-Policy` response header and `<meta name="referrer">` tag. URLs with credentials and private network targets are rejected. |
| `timeoutSeconds` | integer | Request timeout from 3 to 30 seconds. Defaults to 10. |

### Output

The actor pushes one dataset item per run.

| Field | Type | Description |
| --- | --- | --- |
| `inputUrl` | string | Original URL from input. |
| `normalizedInputUrl` | string | Normalized input URL after defaulting the scheme. |
| `finalUrl` | string | Final URL after redirects. |
| `https` | boolean | True when the page was served over HTTPS. |
| `ok` | boolean | True when the fetch succeeded. |
| `checkedAt` | string | ISO timestamp for the audit. |
| `httpStatus` | integer or null | HTTP status code from the response. |
| `hasHeader` | boolean | True when a `Referrer-Policy` response header is present. |
| `headerValues` | array | Raw `Referrer-Policy` header value(s). |
| `headerValueCount` | integer | Number of `Referrer-Policy` header values. |
| `parsedPolicies` | array | Valid policy directives parsed from the header. |
| `hasInvalidHeaderDirective` | boolean | True when the header contains unrecognized directives. |
| `hasDeprecatedHeaderDirective` | boolean | True when the header uses a privacy-leaking directive. |
| `hasConflictingHeaders` | boolean | True when multiple valid directives are present in the header. |
| `hasMetaReferrer` | boolean | True when a `<meta name="referrer">` tag is present in the HTML. |
| `metaReferrerValues` | array | Content values from meta referrer tags. |
| `metaReferrerCount` | integer | Number of meta referrer tags found. |
| `hasInvalidMetaDirective` | boolean | True when the meta tag contains an unrecognized directive. |
| `hasDeprecatedMetaDirective` | boolean | True when the meta tag uses a privacy-leaking directive. |
| `effectivePolicy` | string or null | The effective policy after header-over-meta precedence. |
| `effectivePolicySource` | string or null | Where the effective policy comes from: `header` or `meta`. |
| `privacyPosture` | string or null | Privacy classification: `strong`, `balanced`, `weak`, or `none`. |
| `specCompliant` | boolean | True when the effective policy is a valid spec directive. |
| `score` | integer | Privacy posture readiness score from 0 to 100. |
| `grade` | string | Letter grade from A+ to F. |
| `issues` | array | Human-readable issues. |
| `recommendations` | array | Suggested fixes. |
| `error` | string or null | Fetch-level error, if the request failed. |

### Example input

```json
{
  "startUrl": "https://example.com/",
  "timeoutSeconds": 10
}
```

### Example output

```json
{
  "inputUrl": "https://example.com/",
  "normalizedInputUrl": "https://example.com/",
  "finalUrl": "https://example.com/",
  "https": true,
  "ok": true,
  "checkedAt": "2025-01-01T00:00:00.000Z",
  "httpStatus": 200,
  "hasHeader": true,
  "headerValues": ["strict-origin-when-cross-origin"],
  "headerValueCount": 1,
  "parsedPolicies": ["strict-origin-when-cross-origin"],
  "hasInvalidHeaderDirective": false,
  "hasDeprecatedHeaderDirective": false,
  "hasConflictingHeaders": false,
  "hasMetaReferrer": false,
  "metaReferrerValues": [],
  "metaReferrerCount": 0,
  "hasInvalidMetaDirective": false,
  "hasDeprecatedMetaDirective": false,
  "effectivePolicy": "strict-origin-when-cross-origin",
  "effectivePolicySource": "header",
  "privacyPosture": "strong",
  "specCompliant": true,
  "score": 100,
  "grade": "A+",
  "issues": [],
  "recommendations": [
    "No Referrer-Policy issues detected."
  ],
  "error": null
}
```

### Security

- Only public HTTP and HTTPS URLs are fetched.
- URLs with usernames or passwords are rejected.
- Private IPv4, private IPv6, localhost, link-local, and private DNS resolutions are blocked before fetching.
- Redirect destinations are revalidated before they are followed.
- The actor does not require logins, cookies, browser sessions, or credentials.
- The actor fetches only the provided URL. It does not follow or fetch any URLs referenced in the page.

### Pricing

| Event | Suggested price |
| --- | ---: |
| Actor start | `$0.005` |
| URL audited | `$0.01` |

Suggested launch price: about `$0.015` per audited URL. Teams can schedule the actor for recurring checks on domains after deploys and CDN cutovers.

### FAQ

#### Does this actor crawl multiple URLs or a whole site?

No. It fetches one URL per run and inspects the `Referrer-Policy` header and meta referrer tag on that page. This keeps runs cheap and predictable for CI and scheduled monitoring.

#### How does the score work?

The score starts at 100 and is reduced for: no policy at all (score set to 40), meta-only without header (-15), invalid header directives (-15), privacy-leaking header directives (-20), conflicting multiple headers (-10), invalid meta directives (-5), privacy-leaking meta directives (-10), `unsafe-url` effective policy (-25), `no-referrer-when-downgrade` effective policy (-15), `origin-when-cross-origin` effective policy (-10), `origin` effective policy (-5), conflicting header vs meta values (-10). A bonus of +5 is added when both header and meta are present and consistent. Pages with no policy at all receive at most a D grade.

#### What are the valid Referrer-Policy directives?

Per the Referrer Policy spec (W3C / fetch standard), the valid directives are: `no-referrer`, `no-referrer-when-downgrade`, `same-origin`, `origin`, `strict-origin`, `origin-when-cross-origin`, `strict-origin-when-cross-origin`, and `unsafe-url`. The browser default since 2020 is `strict-origin-when-cross-origin`.

#### What is the difference between this actor and the HTTP Security Headers Auditor?

The HTTP Security Headers Auditor checks `Referrer-Policy` as one of ten headers and reports only presence, absence, or a weak-value warning. This actor deeply validates every directive against the spec, detects invalid and deprecated values, checks the HTML `<meta name="referrer">` tag, evaluates header-over-meta precedence, detects conflicting multiple headers and header-vs-meta mismatches, classifies privacy posture, and returns a focused referrer-policy diagnostic with a readiness score and recommendations.

#### What is the `<meta name="referrer">` tag?

The `<meta name="referrer" content="...">` tag is an HTML-level fallback for setting the referrer policy when an HTTP `Referrer-Policy` header is not present. Per spec, if both are set, the HTTP header takes precedence. This actor checks both and flags mismatches.

# Actor input Schema

## `startUrl` (type: `string`):

Public HTTP or HTTPS URL to audit. The actor fetches this page and inspects the Referrer-Policy header and meta referrer tag.

## `timeoutSeconds` (type: `integer`):

Request timeout from 3 to 30 seconds.

## Actor input object example

```json
{
  "startUrl": "https://example.com/",
  "timeoutSeconds": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrl": "https://example.com/"
};

// Run the Actor and wait for it to finish
const run = await client.actor("phoenix2810/referrer-policy-auditor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrl": "https://example.com/" }

# Run the Actor and wait for it to finish
run = client.actor("phoenix2810/referrer-policy-auditor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrl": "https://example.com/"
}' |
apify call phoenix2810/referrer-policy-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,phoenix2810/referrer-policy-auditor"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/mH0GgRjH370uf5jBT/builds/VHobnw30FPXrnVRqD/openapi.json
