TMS WEB CORE Application and CSP settings

We have TMS WEB CORE application running under IIS.
Application works fine if we don't set any CSP (Content Security Policy) options for our site.
To pass the security test we changed the OPTIONS option: style-src 'self'; script-src 'self';
All styles moved from html files to our CSS folder, all scripts to JS folder. But application stopped working.
A lot of error messages related to inline styles and inline scripts.

WEBLib.Controls.pas:2153 Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-xzrnHpGV3DuP1uvYmnBpMKoYpCWVa2wtX7c2ueBtdUU='), or a nonce ('nonce-...') is required to enable inline execution.

Does it consider an inline style when we assign a font-awesome icon which contains style to the button caption.
button.Caption := i class="fas fa-eye-slash" style="font-size:14px; padding-top:7px;">;

The error “Refused to apply inline style because it violates the Content Security Policy (CSP)” occurs when a web page’s Content Security Policy prevents the browser from executing or applying inline styles for security reasons. This is a mechanism designed to mitigate cross-site scripting (XSS) attacks by controlling what resources can be loaded or executed on a web page.

Causes of the Error

  1. Inline Styles Are Blocked:

• CSP policies typically disallow inline styles (style attributes on elements or tags with inline content) unless explicitly allowed.

  1. Unsafe Directives:

• If the CSP does not include a directive to allow inline styles, the browser will block them by default.

  1. ‘unsafe-inline’ Not Allowed:

• Allowing inline styles often requires the 'unsafe-inline' directive in the CSP. However, this is considered a security risk because it allows any inline code to execute, potentially including malicious scripts.

  1. Nonce or Hash Missing:

• Modern CSP implementations require either a nonce (a unique token) or a hash of the inline style to explicitly allow it. Without these, inline styles are rejected.

How to Fix the Problem

  1. Avoid Inline Styles:

• The best practice is to move all styles into external CSS files and reference them using tags in your HTML.

  1. Use a Nonce:

• Add a nonce (unique token) to your CSP header and use it to authorize specific inline styles.

• Example CSP header:

Content-Security-Policy: style-src 'self' 'nonce-abc123';

• Inline style with nonce:

body { background-color: blue; }
  1. Use a Hash:

• Compute the SHA-256 hash of the inline style and include it in your CSP.

• Example CSP header:

Content-Security-Policy: style-src 'self' 'sha256-B6D+IeOl4wZ8CvVu+Gp9fs39zB+anEUVd+eYojLg5nE=';

• Inline style:

body { background-color: blue; }
  1. Use 'unsafe-inline' (Not Recommended):

• As a last resort, you can include the 'unsafe-inline' directive in your CSP to allow all inline styles:

Content-Security-Policy: style-src 'self' 'unsafe-inline';

• However, this significantly reduces the security of your application and should be avoided if possible.

  1. Debug and Validate:

• Use browser developer tools to inspect the CSP and identify the exact directive causing the block.

• Use tools like CSP Evaluator to analyze your policy for weaknesses.

Thank you for the detailed explanation but what can i do with the scripts which are getting created at runtime by web core. It fails when tries to run this script in WebLib.REST.pas.:

class function TRESTClient.InstallCallback: boolean;
var
scriptsrc: string;
begin
scriptsrc :=
' function processAuthData(access_token) {'
+'var event = new CustomEvent("oauthcallback", {'#13
+' detail: {'#13
+' message: access_token'#13
+' },'#13
+' bubbles: true,'#13
+' cancelable: true});'#13
+' document.dispatchEvent(event);'
+'}';

asm
var script = document.createElement("script");
script.innerHTML = scriptsrc;
document.head.appendChild(script);

var scr = document.createElement('script');
scr.async = true;
scr.defer = true;
scr.type = 'text/javascript';
document.body.appendChild(scr);

end;

Result := true;
end;

The framework indeed needs in a few places dynamic script creation. I see no workaround for this.