For AI agents: the complete documentation index is available at /tc39-atlas/en/llms.txt, the full documentation bundle is available at /tc39-atlas/en/llms-full.txt, and this page is available as Markdown at /tc39-atlas/en/proposals/proposal-dynamic-import-host-adjustment.md.
  • English
  • Dynamic Import Host Adjustment ?

    Proposal details
    Proposal overview

    This proposal addresses security concerns with the dynamic import operator by giving the host more control over module loading. It adjusts the host callout to receive the original specifier (before stringification) and to control stringification, integrating with Trusted Types.

    Note

    The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.

    Dynamic Import Host Adjustment

    Stage2
    Specsource, output
    TestsTODO
    Champion@mikesamuel
    Reviewers@bakkot, @erights, @bmeck

    Trusted Types guards sensitive APIs; it double checks that values have been trusted by policy code before performing operations that cannot be undone.

    The dynamic import operator, import(...), loads code and initializes modules. Loading code from an untrustworthy source is an operation that cannot be undone.

    This adjusts the host callout which enables dynamic loading. With it:

    1. The host receives the original specifier (before it is stringified) so can use runtime type information to decide whether to allow code loading to proceed.
    2. The host callout can control stringification and convey the result to FinishDynamicImport to avoid repeated stringification, and to integrate with default policies.

    Testing

    Tests, to be written, will be implemented as web-platform-tests and will focus on the following properties:

    1. Polymorphic objects stringified once. Something like
      importScripts("/resources/testharness.js");
      
      test(
        () => {
          let stringifyCount = 0;
          import({
            toString() {
              let specifier = `data:text/javascript,export default ${ stringifyCount }`;
              ++stringifyCount;
              return specifier;
            }
          })
          .then(
            (defaultExport) => {
              assert_equals(stringifyCount, 1);
              assert_equals(defaultExport, 0);
            },
            (err) => {
              assert_equals(err, null);
            })
          .finally(done);
        },
        'DynamicImportStringifiesSpecifierOnce');
    2. The above, with coverage for both null and non-null referencing modules.
    3. Tests specific to trusted-types host implementation.

    See also webappsec-csp #243 on import('data:...') as CSP bypass.