Skip to content

Content Security Policy (CSP) Reference

This document provides the authoritative reference for Airbase's Content Security Policy implementation.

CSP Policy

Airbase enforces the following Content Security Policy for all deployed applications:

Content-Security-Policy: script-src 'self'

This policy is automatically applied by the Airbase platform and cannot be disabled.


Policy Directives

script-src 'self'

What it allows:

  • ✅ JavaScript files served from the same origin as your application
  • ✅ External .js files via <script src="/path/to/file.js"></script>

What it blocks:

  • ❌ Inline JavaScript in <script> tags
  • ❌ Inline event handlers (onclick, onload, onerror, etc.)
  • javascript: URLs (e.g., href="javascript:void(0)")
  • eval() and similar dynamic code execution
  • Function() constructor
  • setTimeout() and setInterval() with string arguments

What is Blocked

Blocked: Inline Scripts

<!-- ❌ BLOCKED -->
<script>
  console.log('This will not execute');
  alert('This will not show');
</script>

Blocked: Inline Event Handlers

<!-- ❌ BLOCKED -->
<button onclick="doSomething()">Click</button>
<body onload="init()">
<div onmouseover="show()">Hover</div>
<a href="javascript:void(0)">Link</a>

Blocked: eval() and Dynamic Code

// ❌ BLOCKED
eval('2 + 2');
new Function('return 2 + 2')();
setTimeout('doSomething()', 1000);
setInterval('checkStatus()', 5000);

Blocked: innerHTML with Scripts

// ❌ Scripts injected via innerHTML won't execute
element.innerHTML = '<script>alert("blocked")</script>';

What is Allowed

Allowed: External JavaScript Files

<!-- ✅ ALLOWED -->
<script src="/js/main.js"></script>
<script src="/static/bundle.js"></script>
<script src="/app.js"></script>

Requirements:

  • File must be served from same origin (your application)
  • File extension should be .js
  • Proper MIME type: application/javascript or text/javascript

Allowed: addEventListener

// ✅ ALLOWED - this is NOT inline
document.getElementById('button').addEventListener('click', function() {
  console.log('Clicked!');
});

Allowed: Direct Function Calls

// ✅ ALLOWED
setTimeout(doSomething, 1000);
setInterval(checkStatus, 5000);
const result = 2 + 2;

Allowed: External CSS

<!-- ✅ ALLOWED - CSP only affects scripts -->
<style>
  body { color: red; }
</style>
<link rel="stylesheet" href="/css/style.css">

Inline CSS and external stylesheets are not affected by this CSP policy.


Violation Error Messages

When CSP blocks code, you'll see errors in the browser console:

Error: Inline Script

Refused to execute inline script because it violates the following
Content Security Policy directive: 'script-src 'self''. Either the
'unsafe-inline' keyword, a hash ('sha256-Q+8tPsjVtiDsjF/Cv8FMOpg2Yg91oKFKDAJat1PPb2g='),
or a nonce ('nonce-...') is required to enable inline execution.

Fix: Move JavaScript to an external file.

Error: Inline Event Handler

Refused to execute inline event handler because it violates the following
Content Security Policy directive: 'script-src 'self''.

Fix: Use addEventListener in an external JavaScript file.

Error: eval()

Refused to evaluate a string as JavaScript because 'unsafe-eval' is not
an allowed source of script in the following Content Security Policy
directive: 'script-src 'self''.

Fix: Replace eval() with direct code execution.


CSP and Same-Origin Policy

Same origin means:

  • Same protocol (https://)
  • Same domain (myapp.app.tc1.airbase.sg)
  • Same port (default HTTPS port 443)

Examples:

URL Same Origin?
/js/app.js ✅ Yes - relative URL
https://myapp.app.tc1.airbase.sg/script.js ✅ Yes - same origin
https://staging--myapp.app.tc1.airbase.sg/script.js ❌ No - different subdomain
https://cdn.example.com/library.js ❌ No - different domain

Note: External CDN scripts are not allowed by default.


Framework Compatibility

Compatible Frameworks

These frameworks/libraries are generally CSP-compliant:

  • Next.js 13+: CSP-compliant by default
  • Vite: Bundles to external files
  • Create React App: CSP-compliant
  • Angular: CSP-compliant with proper config
  • Vue.js: CSP-compliant
  • Flask: Templates work fine with external JS
  • Streamlit: Generally works (see notes)

Potentially Problematic Libraries

Some libraries may generate inline scripts or use eval():

  • ⚠️ Older chart libraries (update to latest versions)
  • ⚠️ Some analytics libraries (use external configuration)
  • ⚠️ Template engines with inline script injection
  • ⚠️ Markdown renderers that allow <script> tags

Always check library documentation for CSP compatibility.


Technical Details

CSP Header Location

The CSP header is added by the Airbase platform at the edge, before responses reach the browser.

You cannot:

  • Override the CSP policy
  • Add additional CSP directives
  • Disable CSP enforcement

For Python apps requiring non-compliant libraries:

As a last resort, see the Nginx Proxy Workaround which allows overriding CSP headers within your container.

CSP Report-Only Mode

Airbase does not use CSP report-only mode. Violations are enforced, meaning non-compliant code will not execute.

Browser Support

All modern browsers support CSP:

  • Chrome/Edge: Full support
  • Firefox: Full support
  • Safari: Full support
  • Mobile browsers: Full support

Why This Policy?

Purpose: Prevent Cross-Site Scripting (XSS) attacks

How it helps:

  1. Blocks XSS payloads: Attackers can't inject <script> tags
  2. Prevents code injection: Even if HTML is compromised, inline scripts won't run
  3. Reduces attack surface: Limits ways malicious code can execute

Government context:

Airbase serves Singapore Government applications handling sensitive data. Strict CSP is a critical security control to protect:

  • Citizen data
  • Government systems
  • Public service applications

Compliance Requirements

For All Applications

  • ✅ All JavaScript must be in external .js files
  • ✅ No inline <script> tags with code
  • ✅ No inline event handlers
  • ✅ No eval() or dynamic code execution

Verification

Before deploying:

  1. Test application with CSP headers locally
  2. Check browser console for violations
  3. Verify all interactive features work
  4. Test on multiple pages/routes

See Test CSP Locally for testing procedures.


Exceptions and Workarounds

No Exceptions Available

The Airbase platform does not provide exceptions to the CSP policy.

You cannot:

  • Request 'unsafe-inline' to be added
  • Request 'unsafe-eval' to be added
  • Whitelist specific inline scripts
  • Use CSP nonces or hashes

Workaround for Python Apps

Only for Python applications (Streamlit, Dash, etc.) using libraries that cannot be made CSP-compliant:

⚠️ Warning: This weakens security. Use only as a last resort.


Other CSP Directives

Airbase currently only enforces script-src 'self'. Other directives (e.g., style-src, img-src, connect-src) are not restricted.

This means:

  • ✅ External stylesheets from CDNs: Allowed
  • ✅ Images from external sources: Allowed
  • ✅ API calls to external services: Allowed
  • ❌ External scripts: Not allowed

Future Policy Changes

The CSP policy may be extended in the future to include additional directives. Applications will be notified before changes take effect.


See Also

Guides

Explanation

Examples

All examples demonstrate CSP-compliant code:


External Resources


Summary

Airbase CSP Policy:

Content-Security-Policy: script-src 'self'

Key points:

  • Enforced for all applications
  • Cannot be disabled or overridden
  • External JavaScript files only
  • No inline scripts or event handlers
  • No eval() or dynamic code execution

Compliance ensures your application is protected against XSS attacks.