Fix Csp Compliance

作者 UI52b8c4a944e39無授權條款收錄於 2026年10月8日更新於 2026年10月8日

Fix Content Security Policy (CSP) compliance issues that UI5 linter reports but cannot auto-fix. Use this skill when linter outputs: - `csp-unsafe-inline-script` with message "Use of unsafe inline script" Trigger on: inline JavaScript in HTML files, script tags without src attribute, onclick/onload handlers in HTML. Also use when user mentions 'security headers', 'inline script warning', 'CSP policy', 'unsafe-inline', or 'Content-Security-Policy'. Provides guidance on moving inline scripts to external files for CSP compliance.

AI 產生的概覽

指導將 UI5 HTML 檔案中的內嵌 JavaScript 移至外部檔案,以修正 CSP 檢查警告。

功能
此技能說明如何解決 UI5 檢查規則 csp-unsafe-inline-script,該規則會標記無法自動修正的內嵌 JavaScript。它提供前後對照模式,將內嵌指令碼、設定物件、內嵌事件處理常式和測試啟動程式碼擷取到外部 .js 檔案或 UI5 模組屬性中。它也涵蓋透過 meta 標籤處理伺服器端渲染的動態值,以及透過 Test Starter 處理 QUnit 測試檔案。
適用情境
當 UI5 檢查回報 csp-unsafe-inline-script,或 HTML 包含內嵌 script 標籤、onclick/onload 處理常式或 unsafe-inline CSP 問題時使用。它用於重構程式碼,以便套用 script-src 'self' 的內容安全政策。
執行需求
不隨附指令碼,僅為說明文件。它假定存在 UI5 專案和檢查輸出,並引用 UI5 執行階段功能,例如 data-sap-ui-on-init 和 Test Starter。

Fix CSP Compliance - Unsafe Inline Scripts

Key Rules

  1. NEVER delete inline script content. Always extract it to an external .js file and replace the inline <script>...</script> with <script src="filename.js"></script>. Even trivial config objects, debug flags, or seemingly unused code must be externalized — removal is a functional regression.
  2. File naming: use a descriptive name matching the content's purpose (e.g., appConfig.js for configuration, init.js for initialization).

This skill fixes Content Security Policy (CSP) compliance issues that the UI5 linter detects but cannot auto-fix because they require restructuring code into external files.

Linter Rule Handled

Rule IDMessage PatternSeverityThis Skill's Action
csp-unsafe-inline-scriptUse of unsafe inline scriptWarningMove to external JS file

When to Use

Apply this skill when you see linter output like:

index.html:15:5 warning Use of unsafe inline script  csp-unsafe-inline-scripttest.html:20:5 warning Use of unsafe inline script  csp-unsafe-inline-script

Background: Why CSP Matters

Content Security Policy (CSP) is a security feature that helps prevent:

  • Cross-Site Scripting (XSS) attacks
  • Data injection attacks
  • Unauthorized script execution

Inline scripts are considered unsafe because an attacker who manages to inject HTML can also inject malicious JavaScript. CSP-compliant apps use script-src 'self' which blocks inline scripts.

Documentation: Content Security Policy

Detection

The linter flags <script> tags that:

  • Have NO src attribute AND
  • Have inline JavaScript content

Flagged:

html
<script>    console.log("Inline code");  <!-- Flagged --></script>
<script type="text/javascript">    doSomething();  <!-- Flagged --></script>
<script type="module">    import { foo } from './foo.js';  <!-- Flagged --></script>

Not flagged:

html
<script src="app.js"></script>  <!-- External = OK -->
<script src="app.js">    // This content is ignored by browser anyway</script>
<script type="text/xmldata">    <!-- Non-JS MIME type = OK -->    <data>...</data></script>

Fix Strategy

The fix for every inline script is the same: move it to an external file and add a <script src="..."> tag in its place. The content of the inline script is preserved — just in a separate .js file instead of inside the HTML. Never delete inline script content; always externalize it.


1. Basic Inline Script → External File

Problem: Inline JavaScript in HTML.

html
<!-- Before - index.html --><!DOCTYPE html><html><head>    <meta charset="utf-8">    <title>My App</title>    <script>        window.myConfig = {            apiUrl: "/api/v1",            debug: true        };    </script>    <script        id="sap-ui-bootstrap"        src="resources/sap-ui-core.js"        data-sap-ui-async="true">    </script>    <script>        sap.ui.require(["my/app/init"], function(init) {            init.start();        });    </script></head><body class="sapUiBody" id="content"></body></html>

Fix Strategy: Move inline scripts to external files.

html
<!-- After - index.html --><!DOCTYPE html><html><head>    <meta charset="utf-8">    <title>My App</title>    <script src="config.js"></script>    <script        id="sap-ui-bootstrap"        src="resources/sap-ui-core.js"        data-sap-ui-async="true"        data-sap-ui-on-init="module:my/app/init">    </script></head><body class="sapUiBody" id="content"></body></html>
javascript
// config.jswindow.myConfig = {    apiUrl: "/api/v1",    debug: true};
javascript
// my/app/init.jssap.ui.define([], function() {    "use strict";
    return {        start: function() {            // Initialization code        }    };});

2. UI5 Bootstrap with Inline Init → data-sap-ui-on-init

Problem: Inline script after UI5 bootstrap.

html
<!-- Before --><script    id="sap-ui-bootstrap"    src="resources/sap-ui-core.js"    data-sap-ui-async="true"    data-sap-ui-resource-roots='{"my.app": "./"}'    data-sap-ui-compat-version="edge"></script><script>    sap.ui.getCore().attachInit(function() {        sap.ui.require([            "sap/m/Shell",            "sap/ui/core/ComponentContainer"        ], function(Shell, ComponentContainer) {            new Shell({                app: new ComponentContainer({                    name: "my.app",                    async: true                })            }).placeAt("content");        });    });</script>

Fix Strategy: Use data-sap-ui-on-init attribute.

html
<!-- After - index.html --><script    id="sap-ui-bootstrap"    src="resources/sap-ui-core.js"    data-sap-ui-async="true"    data-sap-ui-resource-roots='{"my.app": "./"}'    data-sap-ui-compat-version="edge"    data-sap-ui-on-init="module:my/app/init"></script>
javascript
// webapp/init.jssap.ui.define([    "sap/m/Shell",    "sap/ui/core/ComponentContainer"], function(Shell, ComponentContainer) {    "use strict";
    new Shell({        app: new ComponentContainer({            name: "my.app",            async: true        })    }).placeAt("content");});

3. Configuration Data → JSON or Module

Problem: Inline configuration object.

html
<!-- Before --><script>    window.APP_CONFIG = {        apiEndpoint: "https://api.example.com",        features: {            darkMode: true,            analytics: false        }    };</script>

Fix Strategy A: External JSON file loaded at runtime.

html
<!-- After - Option A: JSON file --><script src="config.js"></script>
javascript
// config.js - loads JSON(function() {    var xhr = new XMLHttpRequest();    xhr.open("GET", "config.json", false);  // Sync for config    xhr.send();    window.APP_CONFIG = JSON.parse(xhr.responseText);})();
json
// config.json{    "apiEndpoint": "https://api.example.com",    "features": {        "darkMode": true,        "analytics": false    }}

Fix Strategy B: UI5 module with configuration.

javascript
// my/app/config.jssap.ui.define([], function() {    "use strict";
    return {        apiEndpoint: "https://api.example.com",        features: {            darkMode: true,            analytics: false        }    };});
// Usage in other modulessap.ui.define(["my/app/config"], function(config) {    console.log(config.apiEndpoint);});

4. Inline Event Handlers → External Scripts

Problem: Inline event handlers in HTML attributes.

html
<!-- Before --><button onclick="handleClick()">Click me</button><img src="logo.png" onerror="handleError(this)"><body onload="init()">

Fix Strategy: Use external script with event listeners.

html
<!-- After --><button id="myButton">Click me</button><img id="logo" src="logo.png"><body>
javascript
// app.jsdocument.addEventListener("DOMContentLoaded", function() {    document.getElementById("myButton").addEventListener("click", handleClick);    document.getElementById("logo").addEventListener("error", function() {        handleError(this);    });    init();});
function handleClick() {    // Click handler}
function handleError(element) {    // Error handler}
function init() {    // Initialization}

5. Test HTML Files

Problem: QUnit test files with inline scripts.

html
<!-- Before - myTest.qunit.html --><!DOCTYPE html><html><head>    <script src="resources/sap-ui-core.js"        data-sap-ui-async="true">    </script>    <script>        sap.ui.getCore().attachInit(function() {            sap.ui.require(["my/app/test/myTest"]);        });    </script></head><body>    <div id="qunit"></div></body></html>

Fix Strategy: Use Test Starter (also fixes prefer-test-starter).

html
<!-- After - myTest.qunit.html --><!DOCTYPE html><html><head>    <script        src="resources/sap/ui/test/starter/runTest.js"        data-sap-ui-testsuite="test-resources/my/app/test/testsuite.qunit">    </script></head><body>    <div id="qunit"></div></body></html>

6. Dynamic Script Content

Problem: Script content generated dynamically.

html
<!-- Before --><script>    var userId = "<%= user.id %>";  // Server-side template    var token = "<?php echo $token; ?>";</script>

Fix Strategy: Use data attributes or meta tags.

html
<!-- After --><meta name="user-id" content="<%= user.id %>"><meta name="csrf-token" content="<?php echo $token; ?>"><script src="app.js"></script>
javascript
// app.jsvar userId = document.querySelector('meta[name="user-id"]').content;var token = document.querySelector('meta[name="csrf-token"]').content;

Implementation Steps

  1. Identify all inline scripts from linter output

  2. Categorize each script:

    • UI5 initialization → Use data-sap-ui-on-init
    • Configuration → External JS file
    • Event handlers → External script with addEventListener
    • Test boilerplate → Use Test Starter
  3. Create external files for the script content

  4. Update HTML to reference external files

  5. Test the application to ensure functionality is preserved

Common Patterns

Inline PatternCSP-Compliant Solution
<script>code</script><script src="file.js">
data-sap-ui-on-init with inlinedata-sap-ui-on-init="module:path/to/init"
onclick="fn()"element.addEventListener("click", fn)
onerror="fn()"element.addEventListener("error", fn)
onload="fn()"DOMContentLoaded event listener
Server-rendered config<meta> tags + JS reader
QUnit inline bootstrapTest Starter runTest.js

Notes

  • CSP compliance is a warning (not error) because some environments may not require it
  • The data-sap-ui-on-init attribute accepts module:path/to/module format for AMD modules
  • For server-rendered dynamic values, use <meta> tags or data-* attributes
  • Test files should use Test Starter for both CSP compliance and best practices
  • Some third-party libraries may require CSP adjustments - check their documentation
  • JSONP callbacks may need special handling in CSP configurations

來源與署名

來源:UI5/plugins-coding-agents位於plugins/ui5-modernization/skills/fix-csp-compliance提交2b8c4a9

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架