Select documentation version:
Steps to configure a hardened version of the JavaScript SDK.

This guide shows you how to harden the JavaScript SDK by reducing its reliance on external resources that could be used to disrupt the events flow or compromise your app. For a hardened setup, RudderStack recommends installing the SDK using NPM. If you load the SDK from the RudderStack CDN, see Harden the CDN loading snippet.

SDK hardening steps

  1. Use a named export that bundles plugins while packaging RudderStack directly in your project using NPM. By using the NPM package export that bundles the plugins code, the SDK does not make any request to dynamically download the plugins.

You can also:

javascript
import { RudderAnalytics } from '@rudderstack/analytics-js/bundled';
  1. Override/mock source configuration data. By mocking the source configuration response to the SDK, RudderStack does not make any source configuration request again.
javascript
rudderAnalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  polyfillIfRequired: false,
  getSourceConfig: () => ({
    updatedAt: new Date().toISOString(),
    source: {
      // Use relevant valid values from the RudderStack dashboard
      name: SOURCE_NAME,
      id: SOURCE_ID,
      workspaceId: WORKSPACE_ID,
      writeKey: WRITE_KEY,
      updatedAt: new Date().toISOString(),
      config: {
        statsCollection: {
          errors: {
            enabled: false
          },
          metrics: {
            enabled: false
          }
        }
      },
      enabled: true,
      destinations: []
    }
  })
});
  1. Disable the loading of polyfills by setting polyfillIfRequired to false. By disabling polyfills, the SDK does not dynamically add a polyfills script from a third-party domain.
javascript
rudderAnalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  polyfillIfRequired: false
});

RudderStack also recommends using only the cloud mode destinations to avoid loading any other third-party SDKs on the website.

Harden the CDN loading snippet

RudderStack recommends the NPM installation described above. If you must load the SDK using the CDN loading snippet, apply the following edits to the Original snippet before adding it to your website. The examples pin version 3.35.2; replace it with the latest SDK version.

Pin the SDK version

Change only sdkVersion, and leave sdkFileName unchanged. Keep sdkBaseUrl unchanged unless you serve the SDK from your own domain:

javascript
var sdkBaseUrl = "https://cdn.rudderlabs.com";
var sdkVersion = "3.35.2"; // Changed: pin an exact SDK version.
var sdkFileName = "rsa.min.js";

The snippet builds the URL from these values and the build type it selects for the browser, resulting in https://cdn.rudderlabs.com/3.35.2/modern/rsa.min.js or https://cdn.rudderlabs.com/3.35.2/legacy/rsa.min.js.

Plugins and integration SDKs

The SDK derives the plugins and device mode integration SDK paths from the core SDK’s own script URL, so pinning sdkVersion also pins them — provided you do not set destSDKBaseURL or pluginsSDKBaseURL in your load options.

If your snippet sets either option (some RudderStack sample apps do), update it to the pinned version as well, or remove it so the SDK derives the path itself.

To avoid downloading these files from the RudderStack CDN, use the bundled NPM export in step 1 or self-host the plugins and integration SDKs.

Device mode destinations such as Google and Meta also load vendor SDKs from the vendors’ own CDNs, typically through unversioned URLs that RudderStack cannot pin. Use cloud mode destinations to avoid loading these vendor SDKs on your website.

A pinned SDK version does not receive fixes or security updates automatically. Upgrade to the latest version frequently: watch the JavaScript SDK releases and update sdkVersion with each release.

Final instrumentation

For CDN installations, pin sdkVersion in the loading snippet as described above and replace its existing load call with the one in the CDN tab.

javascript
import { RudderAnalytics } from '@rudderstack/analytics-js/bundled';

const rudderAnalytics = new RudderAnalytics();

rudderAnalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  polyfillIfRequired: false,
  getSourceConfig: () => ({
    updatedAt: new Date().toISOString(),
    source: {
      // Use relevant valid values from the RudderStack dashboard
      name: SOURCE_NAME,
      id: SOURCE_ID,
      workspaceId: WORKSPACE_ID,
      writeKey: WRITE_KEY,
      updatedAt: new Date().toISOString(),
      config: {
        statsCollection: {
          errors: {
            enabled: false
          },
          metrics: {
            enabled: false
          }
        }
      },
      enabled: true,
      destinations: []
    }
  })
});

export { rudderAnalytics };

Questions? Let's figure it out together.

Join the RudderStack Slack community to connect with other users, customers, and the RudderStack team — or reach out for direct support.