Skip to content

fix: join service worker path with a single slash#1471

Merged
sherwinski merged 2 commits into
mainfrom
sherwin/fix-worker-path-double-slash
Jun 4, 2026
Merged

fix: join service worker path with a single slash#1471
sherwinski merged 2 commits into
mainfrom
sherwin/fix-worker-path-double-slash

Conversation

@sherwinski

@sherwinski sherwinski commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Description

1 Line Summary

Harden the service-worker path join so a leading slash in serviceWorkerPath can't produce a protocol-relative // URL that fails worker registration.

Details

Adds a guard to prevent the potential for a simple misconfiguration from silently breaking push.

getServiceWorkerManager (src/shared/helpers/context.ts) builds the worker URL by directly concatenating userConfig.path and userConfig.serviceWorkerPath:

new Path(`${config.userConfig.path}${config.userConfig.serviceWorkerPath}`)

path defaults to "/". If an integration configures serviceWorkerPath: "/OneSignalSDKWorker.js" (with a leading slash), the result is "//OneSignalSDKWorker.js". The browser interprets a leading // as a protocol-relative URL, treating onesignalsdkworker.js as a hostname (https://onesignalsdkworker.js/). Worker registration is then rejected cross-origin:

SecurityError: Failed to register a ServiceWorker: The origin of the provided scriptURL
('https://onesignalsdkworker.js') does not match the current origin (...).

With no worker, no push token is ever acquired, which downstream surfaces as subscription-10 ("Subscription can't change notification_types to positive integer while disabled") because the subscription is sent with an empty token.

The fix strips a trailing slash from path and a leading slash from serviceWorkerPath, then joins them with exactly one slash — so both "/" + "OneSignalSDKWorker.js" and "/" + "/OneSignalSDKWorker.js" resolve to /OneSignalSDKWorker.js.

Systems Affected

  • WebSDK
  • Backend
  • Dashboard

Validation

Tests

Info

Added src/shared/helpers/context.test.ts covering the join logic:

  • default root path + worker file name
  • leading-slash serviceWorkerPath no longer yields //
  • nested path with a trailing slash
  • slashes on both sides of the join

Checklist

  • All the automated tests pass or I explained why that is not possible
  • I have personally tested this on my machine or explained why that is not possible
  • I have included test coverage for these changes or explained why they are not needed

Screenshots

Checklist

  • I have included screenshots/recordings of the intended results or explained why they are not needed (config/URL normalization, covered by unit tests)

Related Tickets

Surfaced while investigating SDK-4341.

A leading slash in the user-supplied serviceWorkerPath combined with the
default path ("/") produced a "//..." prefix, which the browser treats as a
protocol-relative URL and rejects with a SecurityError during worker
registration. Normalize the join so exactly one slash separates path and
serviceWorkerPath.
@sherwinski sherwinski marked this pull request as ready for review June 4, 2026 19:00
@sherwinski

Copy link
Copy Markdown
Contributor Author

@claude review

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — small, well-tested URL normalization fix.

Extended reasoning...

Overview

This PR tightens the service-worker URL construction in src/shared/helpers/context.ts. Previously getServiceWorkerManager concatenated userConfig.path and userConfig.serviceWorkerPath directly, which could produce //OneSignalSDKWorker.js when path defaulted to / and serviceWorkerPath had a leading slash. Browsers treat //foo as protocol-relative, sending the worker request to a cross-origin URL and failing registration with a SecurityError. The fix strips a trailing slash from path and a leading slash from serviceWorkerPath, then joins with exactly one slash. A new context.test.ts covers the four relevant join cases.

Security risks

None substantive. The change actively reduces a misconfiguration risk (worker URL ending up on an attacker-controlled-looking origin). The regex anchors (/\/+$/ and /^\/+/) are bounded to leading/trailing slashes and safe from ReDoS. No auth, crypto, or permissions surfaces touched.

Level of scrutiny

Low. This is a defensive string-normalization fix with unit-test coverage for the relevant edge cases (root path, leading-slash worker path, nested trailing-slash path, slashes on both sides). The change is localized to a single helper, mechanical in nature, and follows an obvious pattern. The PR description clearly explains the failure mode (subscription-10 symptom) and the fix.

Other factors

The test reaches into the manager via manager['_config'].workerPath._getFullPath(), which is a private-field access; that is a minor stylistic concern but matches how the join result must be inspected without a public accessor, and a future refactor that exposes the path would naturally update the test. No outstanding reviewer comments, and the requester (sherwinski) explicitly asked for review.

@sherwinski sherwinski requested a review from fadi-george June 4, 2026 19:07
@fadi-george

Copy link
Copy Markdown
Contributor

any changes to size limit?

@sherwinski sherwinski merged commit b7bb0cf into main Jun 4, 2026
3 checks passed
@sherwinski sherwinski deleted the sherwin/fix-worker-path-double-slash branch June 4, 2026 20:54
@github-actions github-actions Bot mentioned this pull request Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants