dotCMS / dotCMS/core

Strip 'www.' prefix from Origin/Referer header in CA logic

Open
#36,433 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

dotCMS : Analytics Team : Falcon Type : Defect
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Problem Statement

When persisting Content Analytics events to CAEM, dotCMS resolves the target Site by extracting the host from the Origin HTTP header (falling back to Referer) and matching it against a Site's name or alias. This happens in ContentAnalyticsUtil.getSiteNameOrAlias() / getSiteFromRequest() (com.dotcms.rest.api.v1.analytics.content.util.ContentAnalyticsUtil, lines ~229-252 and ~349-376), which is also called from SiteAuthValidator.validate() (com.dotcms.jitsu.validators.SiteAuthValidator) to validate each incoming event's site auth.

Many public sites serve their canonical pages under a www. subdomain (e.g. https://www.example.com), but the dotCMS Site's configured hostname and aliases typically do not include the www. prefix (e.g. example.com). The host extracted from the Origin/Referer header via URLUtils.parseURL() is passed as-is — with no normalization — into HostAPI.findByName() and then HostAPI.findByAlias(). Both lookups fail for a www.-prefixed host, so getSiteFromRequest() throws AnalyticsValidationException ("Site with name/alias '...' was not found").

Observed impact: SiteAuthValidator catches this exception per-event, so the individual event is silently dropped from the batch payload (ContentAnalyticsUtil.removeInvalidEventsFromPayload()) while other valid events in the same batch still persist — this makes the failure easy to miss since analytics keeps flowing for the site overall. Separately, getSiteFromRequestSilently() (used by includeInternalFields()) wraps the same exception as an unchecked RuntimeException, which can abort processing for that call site entirely.

This host-resolution logic is custom to ContentAnalyticsUtil and is not shared with dotCMS's general request-host resolution (HostWebAPIImpl.getCurrentHost(), which uses request.getServerName() and is unaffected by this bug), so the fix is fully contained to Content Analytics event ingestion. No backwards compatibility needs to be preserved for this change.

Out of scope: ContentAnalyticsUtil.sendEvents() resolves the host for logging via HostWebAPI.getCurrentHost() (server name) rather than getSiteFromRequest() (Origin/Referer), so the host used to persist/log an event can already differ from the one used to validate site auth. That inconsistency is a separate issue and is not addressed here.

Steps to Reproduce

  1. Configure a dotCMS Site with hostname example.com (no www.example.com alias configured).
  2. Enable Content Analytics tracking for that Site (Content Analytics app with siteAuth and contentImpression/contentClick configured).
  3. Load a page served under https://www.example.com/... so that the browser sends Origin: https://www.example.com (or Referer: https://www.example.com/...) with the analytics event request.
  4. Trigger a Content Analytics event (e.g. page view / click) so it is submitted for persistence.

Expected: The event resolves to the example.com Site and is persisted.

Actual: getSiteNameOrAlias() extracts host www.example.com, which matches neither the Site's name nor its aliases. getSiteFromRequest() throws AnalyticsValidationException, SiteAuthValidator drops the event from the batch, and it is never persisted — with no visible error to the caller since other events in the batch may still succeed.

Acceptance Criteria

  • When the Origin or Referer header host starts with www. (case-insensitive) and the remainder matches a configured Site name or alias, the event resolves to that Site and is persisted (e.g. Origin: https://www.example.com matches Site example.com).
  • When the Origin or Referer header host does not start with www., existing Site matching behavior is unchanged.
  • Only a single leading www. label is stripped; hosts such as shop.example.com or www2.example.com are not modified by this normalization.
  • The www. prefix match is case-insensitive (e.g. WWW.example.com and Www.Example.com are also normalized before lookup).
  • If, after stripping www., the host still does not match any Site name or alias, the existing AnalyticsValidationException ("Site with name/alias '...' was not found") is thrown, unchanged from current behavior.
  • Unit test coverage added covering www.-prefixed Origin and Referer headers resolving correctly to the underlying Site, plus a case confirming non-www hosts are unaffected.

dotCMS Version

Latest from main branch

Severity

Medium - Some functionality impacted

Links

  • NA

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ContentAnalyticsUtil.getSiteNameOrAlias() and getSiteFromRequest(), then trace their use from SiteAuthValidator.validate(). Add unit coverage for www.-prefixed Origin and Referer hosts, unchanged non-www behavior, and the existing failure path. Run the relevant Content Analytics tests and confirm matching events resolve to the configured Site.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
analytics, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
75/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.