PageSourceSearch

https://naval-group.com/modules/custom/naval_group_webfactory/js/csp-propagation.js

js naval-group.com collected 2026-10-02 02:39:25 UTC 2,862 bytes, 89 lines download raw bytes

1/**
2 * @file
3 * CSP Nonce Propagation.
4 *
5 * This script ensures that dynamically created elements (scripts, styles)
6 * and HTML injections (innerHTML, insertAdjacentHTML) inherit the CSP nonce.
7 */
8
9(function () {
10  'use strict';
11  // Recovery of the nonce from the script tag itself.
12  const scriptTag = document.currentScript;
13  const nonce = scriptTag ? scriptTag.nonce || scriptTag.getAttribute('nonce') : null;
14
15  if (!nonce) {
16    return;
17  }
18
19  const tags = ['script', 'style'];
20
21  /**
22   * Processes dynamic HTML strings to inject nonces and transform style attributes.
23   *
24   * @param {string} text
25   *   The HTML string to process.
26   * @param {string} nonceValue
27   *   The nonce to inject.
28   *
29   * @return {string}
30   *   The processed HTML string.
31   */
32  const processDynamicHtml = function (text, nonceValue) {
33    if (typeof text !== 'string') {
34      return text;
35    }
36
37    // 1. Nonce script/style tags.
38    let processedText = text.replace(/<(script|style)\b([^>]*)/gi, (m, tag, attrs) => {
39      if (attrs.indexOf('nonce=') === -1) {
40        return `<${tag}${attrs} nonce="${nonceValue}"`;
41      }
42      return m;
43    });
44
45    // 2. Transform style attributes to <style> tags (for CSP strict-dynamic compatibility).
46    processedText = processedText.replace(/<([a-z0-9]+)\b([^>]*)\bstyle=["']([^"']+)["']([^>]*)>/gi, (m, tag, before, val, after) => {
47      if (before.includes('data-csp-id=') || after.includes('data-csp-id=')) {
48        return m;
49      }
50      const id = `style-${Math.random().toString(36).substr(2, 9)}`;
51      return `<${tag}${before} data-csp-id="${id}" style=""${after}><style nonce="${nonceValue}">[${tag}][data-csp-id="${id}"] { ${val} !important; }</style>`;
52    });
53
54    return processedText;
55  };
56
57  // 1. Override createElement to handle manual element creation.
58  const oldCE = document.createElement;
59  document.createElement = function (tagName) {
60    const el = oldCE.apply(this, arguments);
61    if (tags.includes(tagName.toLowerCase())) {
62      el.setAttribute('nonce', nonce);
63    }
64    return el;
65  };
66
67  // 2. Override insertAdjacentHTML to handle string-based injections.
68  const oldIAH = Element.prototype.insertAdjacentHTML;
69  Element.prototype.insertAdjacentHTML = function (pos, text) {
70    const processed = processDynamicHtml(text, nonce);
71    return oldIAH.call(this, pos, processed);
72  };
73
74  // 3. Override innerHTML setter for template-based injections (CKEditor, AJAX).
75  const desc = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
76  if (desc && desc.set) {
77    Object.defineProperty(Element.prototype, 'innerHTML', {
78      set: function (text) {
79        const processed = processDynamicHtml(text, nonce);
80        desc.set.call(this, processed);
81      },
82      get: function () {
83        return desc.get.call(this);
84      },
85      configurable: true,
86    });
87  }
88
89})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.