@salesforce/internal-lightning-out-containers 2.2.5 → 2.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,54 @@
1
+ /*
2
+ * Copyright 2026 salesforce.com, inc.
3
+ * All Rights Reserved
4
+ * Company Confidential
5
+ */
6
+
7
+ import { assertBareSpecifier } from "../env";
8
+
9
+ describe("assertBareSpecifier", () => {
10
+ describe("accepts bare identifiers", () => {
11
+ it.each([
12
+ "c/foo",
13
+ "c/dealerLocator",
14
+ "namespace/component",
15
+ "c/foo/v/1_0_0",
16
+ "aura/interop/v/0_0_1",
17
+ "ns/name/v/2_3_4",
18
+ "c:foo",
19
+ "namespace:component",
20
+ ])("accepts %s", (value) => {
21
+ expect(assertBareSpecifier(value)).toBe(value);
22
+ });
23
+ });
24
+
25
+ describe("rejects URL-shaped and unsafe strings", () => {
26
+ it.each([
27
+ "//www.arcgis.com/sharing/rest?f=json&callback=x",
28
+ "https://evil.com/payload.js",
29
+ "http://evil.com/payload.js",
30
+ "/absolute/path",
31
+ "../traversal/here",
32
+ "c/foo?query=1",
33
+ "c/foo#hash",
34
+ "c/foo/v/1_0_0?x=1",
35
+ "c/foo bar",
36
+ " c/foo",
37
+ "c/foo ",
38
+ "",
39
+ "c",
40
+ "/c/foo",
41
+ "c//foo",
42
+ "-invalid/foo",
43
+ "c/-invalid",
44
+ "c/foo/v/",
45
+ "c/foo/v/1.0.0",
46
+ ])("rejects %s", (value) => {
47
+ expect(() => assertBareSpecifier(value)).toThrow(/Invalid componentName/);
48
+ });
49
+ });
50
+
51
+ it("returns null for null input (missing URL param)", () => {
52
+ expect(assertBareSpecifier(null)).toBeNull();
53
+ });
54
+ });
@@ -4,12 +4,27 @@
4
4
  * Company Confidential
5
5
  */
6
6
 
7
+ // Bare LWC (namespace/name) or Aura (namespace:name) identifier, with optional /v/<version> suffix.
8
+ // Rejects URL-shaped strings — a specifier reaching `import()` must be resolved as a module,
9
+ // not a URL. LWR's AMD loader treats URL-shaped specifiers as fetchable script sources, which
10
+ // would allow an attacker who controls the `componentName` URL param to load arbitrary script
11
+ // from any origin permitted by the page's CSP.
12
+ const BARE_SPECIFIER = /^[a-zA-Z][a-zA-Z0-9_-]*[/:][a-zA-Z][a-zA-Z0-9_-]*(\/v\/[a-zA-Z0-9_]+)?$/;
13
+
14
+ export function assertBareSpecifier(value) {
15
+ if (value === null) return null;
16
+ if (!BARE_SPECIFIER.test(value)) {
17
+ throw new Error(`Invalid componentName: ${value}`);
18
+ }
19
+ return value;
20
+ }
21
+
7
22
  const urlSearchParams = new URLSearchParams(window.location.search);
8
23
 
9
24
  export function createEnvContext() {
10
25
  const loAppOrigin = urlSearchParams.get("loAppOrigin");
11
26
  const parentElementId = urlSearchParams.get("parentElementId");
12
- const componentNameParam = urlSearchParams.get("componentName");
27
+ const componentNameParam = assertBareSpecifier(urlSearchParams.get("componentName"));
13
28
  const testMode = urlSearchParams.get("testMode") === "true";
14
29
 
15
30
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/internal-lightning-out-containers",
3
- "version": "2.2.5",
3
+ "version": "2.2.6",
4
4
  "private": false,
5
5
  "description": "Lightning Out 2.0 Container Components",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",