Skip to content

Security by Design

Andre Kless edited this page Feb 5, 2026 · 24 revisions

Overview

CCM follows a security-by-design approach that is rooted in strict encapsulation, explicit references, and controlled resource loading.

Encapsulation by Reference (no global access)

Component instances are created and accessed exclusively via explicit JavaScript references returned by ccm.start() or ccm.instance(). There is no global registry of running instances and no implicit access via the DOM or global variables. As a result, externally loaded JavaScript code cannot discover or interact with component instances unless it has been given an explicit reference.

const instance = await ccm.instance("./ccm.quiz.mjs", {
  questions: [ /* ... */ ]
}, document.body);

// Only this reference can access the instance
await instance.start();

// ❌ Not possible:
window.findInstance(instance); // cannot be find
document.querySelector(...);   // no access to instance logic

Externally loaded or compromised scripts cannot “discover” or hijack running instances.

Immutable Component Registration

Component definitions are encapsulated by the framework. When a component is registered, the original definition is stored privately inside the ccmjs framework and is never exposed globally. Calls to ccm.component() return only a cloned copy of the registered component object. This ensures that once a component version is registered, it cannot be modified accidentally or intentionally by other scripts.

let comp = await ccm.component("./ccm.hello.mjs");

// This modifies only the cloned copy
comp.config.hacked = true;

// The internally registered component version remains unchanged

// Re-registering a component with the same name and version does not override the
// original definition, but only returns a clone of the already registered component.
comp = await ccm.component({
  name: "hello",
  hacked: true,
  // ...
});

console.log(comp.hacked);  // undefined

Once a component is registered, it is protected from accidental or malicious mutation by externally loaded JavaScript.

Subresource Integrity (SRI)

CCM supports Subresource Integrity when loading components or resources, ensuring that only resources matching a known cryptographic hash are executed.

ccm.start(
  "./ccm.quiz.mjs#sha384-...",    // component loaded with SRI
  {
    ccm: "./ccm.js#sha384-...",   // used ccmjs version loaded with SRI
    css: [ "ccm.load", {
      url: "styles.css",
      attr: {
        integrity: "sha384-...",  // CSS loaded with SRI
        crossorigin: "anonymous"
      }
    }],
    js: [ "ccm.load", {
      url: "script.js",
      attr: {
        integrity: "sha384-...",  // JS loaded with SRI
        crossorigin: "anonymous"
      }
    }],
    module: [ "ccm.load", {
      url: "./module.mjs",
      attr: {
        integrity: "sha384-...",  // Module loaded with SRI
        crossorigin: "anonymous"
      }
    }]
  }
);

Even if a CDN or server is compromised, manipulated resources are rejected by the browser because the integrity hash no longer matches.

Shadow DOM Isolation (optional & configurable)

Each component instance is rendered inside a Shadow DOM by default, with configurable control over its openness.

The root configuration option supports the following values:

  • "open" (default): a Shadow DOM is created and accessible via instance.root
  • "closed": a Shadow DOM is created but not externally accessible
  • "none": no Shadow DOM is used; the component renders directly into the host element
ccm.start("./ccm.hello.mjs", {
  root: "closed"
}, document.body);

When enabled, the Shadow DOM encapsulates DOM structure, styles, and internal markup from external scripts, reducing accidental interference and improving isolation.

Clone this wiki locally