Skip to content

Security by Design

Andre Kless edited this page Feb 11, 2026 · 30 revisions

Overview

CCM follows a security-by-design approach that is rooted in strict encapsulation, explicit references, and controlled resource loading. It does not replace general web security practices such as CSP, input validation, or protection against XSS. It focuses on structural isolation and controlled component composition.

Encapsulation by Reference (no global access)

Access to instances follows a capability-based model: only code that holds a reference can interact with an instance. 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.

Verified Resource Loading (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);

Shadow DOM primarily provides structural and styling isolation. It does not create a separate JavaScript execution context.

Clone this wiki locally