fix-csp-compliance
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.
How do I install this agent skill?
npx skills add https://github.com/ui5/plugins-coding-agents --skill fix-csp-complianceIs this agent skill safe to install?
- Gen Agent Trust Hubpass
This skill provides instructions for refactoring UI5 applications to be compliant with Content Security Policy (CSP) by moving inline scripts to external files. It promotes security best practices and does not contain any malicious patterns.
- Socketpass
No alerts
- Snykfail
Risk: HIGH · 1 issue
What does this agent skill do?
Fix CSP Compliance - Unsafe Inline Scripts
Key Rules
- NEVER delete inline script content. Always extract it to an external
.jsfile 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. - File naming: use a descriptive name matching the content's purpose (e.g.,
appConfig.jsfor configuration,init.jsfor 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 ID | Message Pattern | Severity | This Skill's Action |
|---|---|---|---|
csp-unsafe-inline-script | Use of unsafe inline script | Warning | Move 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-script
test.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
srcattribute AND - Have inline JavaScript content
Flagged:
<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:
<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.
<!-- 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.
<!-- 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>
// config.js
window.myConfig = {
apiUrl: "/api/v1",
debug: true
};
// my/app/init.js
sap.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.
<!-- 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.
<!-- 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>
// webapp/init.js
sap.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.
<!-- 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.
<!-- After - Option A: JSON file -->
<script src="config.js"></script>
// 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);
})();
// config.json
{
"apiEndpoint": "https://api.example.com",
"features": {
"darkMode": true,
"analytics": false
}
}
Fix Strategy B: UI5 module with configuration.
// my/app/config.js
sap.ui.define([], function() {
"use strict";
return {
apiEndpoint: "https://api.example.com",
features: {
darkMode: true,
analytics: false
}
};
});
// Usage in other modules
sap.ui.define(["my/app/config"], function(config) {
console.log(config.apiEndpoint);
});
4. Inline Event Handlers → External Scripts
Problem: Inline event handlers in HTML attributes.
<!-- 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.
<!-- After -->
<button id="myButton">Click me</button>
<img id="logo" src="logo.png">
<body>
// app.js
document.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.
<!-- 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).
<!-- 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.
<!-- Before -->
<script>
var userId = "<%= user.id %>"; // Server-side template
var token = "<?php echo $token; ?>";
</script>
Fix Strategy: Use data attributes or meta tags.
<!-- After -->
<meta name="user-id" content="<%= user.id %>">
<meta name="csrf-token" content="<?php echo $token; ?>">
<script src="app.js"></script>
// app.js
var userId = document.querySelector('meta[name="user-id"]').content;
var token = document.querySelector('meta[name="csrf-token"]').content;
Implementation Steps
-
Identify all inline scripts from linter output
-
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
- UI5 initialization → Use
-
Create external files for the script content
-
Update HTML to reference external files
-
Test the application to ensure functionality is preserved
Common Patterns
| Inline Pattern | CSP-Compliant Solution |
|---|---|
<script>code</script> | <script src="file.js"> |
data-sap-ui-on-init with inline | data-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 bootstrap | Test Starter runTest.js |
Notes
- CSP compliance is a warning (not error) because some environments may not require it
- The
data-sap-ui-on-initattribute acceptsmodule:path/to/moduleformat for AMD modules - For server-rendered dynamic values, use
<meta>tags ordata-*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
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/ui5/plugins-coding-agents/fix-csp-compliance">View fix-csp-compliance on skillZs</a>