Implementation Guide

    How to Restrict URLs in LLM Responses

    Restricting URLs in LLM responses is an output-control problem. Prompt instructions can reduce unwanted links but cannot guarantee their absence. A dependable design layers retrieval source restrictions, structured output, post-generation URL parsing against a domain allowlist, and enforcement at runtime in the execution path, with a defined allow, redact or block action and a per-interaction record of each decision.

    Edge cases the policy must handle

    • Userinfo and backslashes: reject or strip credentials in the authority, and test inputs that mix '@' and backslashes.
    • Encoding and obfuscation: decode percent-encoding and normalize case, trailing dots and alternative host forms before comparison.
    • Redirects: an approved host can redirect elsewhere, so decide whether to resolve the final destination or permit only hosts known not to redirect.
    • URL shorteners: treat them as unapproved by default, since the destination is hidden from the check.
    • Markdown and HTML: inspect link and image syntax, reference-style links and raw HTML, not only plain-text URLs.
    • Streaming: a URL can span chunks, so buffer or evaluate before delivery rather than checking fragments.

    Why URLs appear in model output, and what they risk

    A model emits URLs for several reasons. Users ask for sources. Retrieved documents contain links that the model repeats. Tools return content with embedded references. And the model can generate a plausible-looking link that points to nothing real, because it produces text that fits a pattern rather than looking up a verified address.

    The risks follow from those paths. A link can send a user to a phishing page or to a domain nobody has approved. A link can present an unvetted source as authoritative. A link can also carry data out. OWASP notes that image tags with external URLs can exfiltrate conversation context through URL parameters, and it lists injected HTML or Markdown that is rendered in LLM responses as a known attack pattern. Because the client fetches an image automatically, the data can leave without any user click.

    Injection widens the problem. OWASP treats user messages, retrieved documents, API responses and emails as untrusted, and states that fetched web pages and MCP tool responses can become instructions when an agent reads them. Its Cornucopia cards describe indirect prompt injection arriving through external tool output and through documents, emails or web pages the model processes. An attacker who controls that content can therefore try to place a link, or an exfiltrating image, in the response without ever talking to the model directly.

    Comparing the control points

    Each control point acts at a different stage and fails in a different way. The comparison below is editorial analysis of reliability, not a ranking of products.

    • System prompt instructions: Cheap and useful for shaping behavior. The model follows them probabilistically, and injected content can contradict them, so they cannot be the enforcement mechanism.
    • Constraining retrieval sources: An allowlist of approved document sources with an approval workflow for additions, as OWASP recommends for RAG. It limits what enters context but does not stop the model generating or repeating other links.
    • Structured output and schema validation: Confines links to defined fields so they can be inspected. It does not make the field values safe, and free-text fields can still carry URLs.
    • Post-generation URL parsing: Extracts URLs from the final text and checks them against an allowlist or denylist. Deterministic, but only as strong as the parser and normalization, and only effective if it runs before the response is delivered.
    • Runtime policy enforcement: Applies the policy in the execution path to each response or tool call, with an action taken at that moment. It depends on the same parsing quality, but removes reliance on the model and on later review.

    Define the allowlist policy and the enforcement action

    Start with the policy, not the tooling. An allowlist entry should state the scheme, the exact host or the subdomain pattern, and any permitted path prefix. Decide whether subdomains are covered by default. A wildcard on a parent domain extends trust to every subdomain, including ones that are abandoned or user-controlled. Prefer HTTPS only, and decide whether URLs with embedded credentials or non-standard ports are ever acceptable. A denylist is useful as a supplement for known-bad destinations, but it cannot be the primary control because the set of unapproved domains is unbounded.

    Then decide what happens to a non-compliant URL. Allow is appropriate for approved destinations, possibly with a record only. Redact removes or neutralizes the link, for example by keeping the visible text and dropping the destination, so the answer remains usable. Block withholds the whole response and suits high-risk contexts, such as a URL with query parameters that appear to contain session or document content, or a URL that arrived from untrusted retrieved content in a workflow with sensitive data. Escalating to a human reviewer is a reasonable fourth option for ambiguous cases.

    A workable default is to redact unapproved links in low-risk interactions and block when the URL looks like an exfiltration attempt. Whatever you choose, make the decision a function of policy configuration rather than application code, so it can be versioned and changed through a recorded approval.

    Layering the controls and enforcing at runtime

    Use the layers together, with each doing the job it is suited for. The prompt sets expectations. Retrieval restrictions reduce the amount of untrusted content in context, and least-privilege tool scopes limit what injected instructions can do. Structured output makes links easier to find. Post-generation parsing then decides, deterministically, whether each URL is permitted.

    The remaining question is where that last check runs and when. A filter that runs in application code can be skipped by a new code path, and a review of logs happens after a user has already seen the link or the browser has already fetched the image. Enforcement in the execution path, applied to each response before it is delivered, closes that gap. This also matters for agents: OWASP lists unrestricted browsing or arbitrary URL fetching without egress controls as a practice to avoid, which supports applying controls outside the model's own instructions.

    Trussed enforces policy in the execution path across models, agents, tools and MCP servers, and can allow, redact or block responses containing non-approved URLs. Enforcement is at runtime, not reviewed after the fact, and applies to individual interactions and tool calls.

    Evidence that the control operated

    A control you cannot demonstrate is hard to defend to an auditor or a security review. For each interaction, retain enough to reconstruct the decision: the interaction identifier, each URL detected, the normalized host that was evaluated, the policy version applied, the action taken (allow, redact or block) and a timestamp. These fields are a design suggestion rather than a formal requirement, but they answer the questions reviewers typically ask: what was permitted, what was stopped, and under which rules.

    Keep the allowlist itself under change control. If new entries require an approval workflow, as OWASP recommends for document sources, the approval record becomes part of the evidence. Retain blocked and redacted events as well as allowed ones, because the denials show the control working. Set retention and residency to match your own obligations.

    Trussed generates continuous audit-ready evidence from enforcement, mapped to HIPAA, NAIC, NYDFS, the EU AI Act and NIST. It can be deployed self-managed in the customer cloud, with configurable retention and data residency.

    Layered URL controls

    Prompt

    Instructions that discourage unapproved links

    Retrieval

    Approved document sources only

    Schema

    Links confined to validated fields

    Parsing

    Normalized URLs checked against an allowlist

    Runtime

    Allow, redact or block before delivery

    Enforce URL policy where responses are produced

    Talk through how allow, redact or block decisions on URLs are enforced at runtime and recorded as audit-ready evidence.

    Talk to an Expert