Skip to content

Commit

Permalink
fix(platform/router-outlet): remove inline styles for CSP compliance
Browse files Browse the repository at this point in the history
Inline styles require a nonce if CSP blocks 'unsafe-inline' styles.

closes #287
  • Loading branch information
Marcarrian authored and danielwiehl committed Oct 29, 2024
1 parent d8e62e8 commit 40e4fbd
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 36 deletions.
5 changes: 4 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,10 @@
"buildTarget": "microfrontend-platform-testing-app:build:production-ci"
},
"development": {
"buildTarget": "microfrontend-platform-testing-app:build:development"
"buildTarget": "microfrontend-platform-testing-app:build:development",
"headers": {
"Content-Security-Policy": "default-src 'self'; connect-src 'self' blob: localhost:*; frame-src 'self' localhost:*; font-src 'self' https://fonts.gstatic.com; style-src 'self' https://fonts.googleapis.com 'nonce-STATIC_NONCE'; script-src 'self' 'nonce-STATIC_NONCE'; frame-ancestors 'self' localhost:*"
}
}
},
"defaultConfiguration": "development"
Expand Down
2 changes: 1 addition & 1 deletion apps/microfrontend-platform-testing-app/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<app-root ngCspNonce="STATIC_NONCE"></app-root>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
{
"headers": [
{
"source": "**",
"headers": [
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; connect-src 'self' blob: localhost:*; frame-src 'self' localhost:*; font-src 'self' https://fonts.gstatic.com; style-src 'self' https://fonts.googleapis.com 'nonce-STATIC_NONCE'; script-src 'self' 'nonce-STATIC_NONCE'; frame-ancestors 'self' localhost:*"
}
]
},
{
"source": "**",
"headers": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,6 @@ const ATTR_NAME = 'name';
const ATTR_SCROLLABLE = 'scrollable';
const ATTR_KEYSTROKES = 'keystrokes';
const HTML_TEMPLATE = `
<style>
:host {
display: block;
overflow: hidden;
position: relative; /* positioning context for splash */
}
iframe {
width: 100%;
height: 100%;
border: none;
margin: 0;
}
/* Ensure transparent router-outlet if empty.
*
* An iframe is transparent only if the embedded content has the same color scheme as the embedding document.
* An empty router-outlet loads the 'about:blank' page. This page has the user's preferred OS color scheme,
* which may be different from the application's color scheme, making the iframe opaque. Therefore, we hide
* the iframe to make the router-outlet transparent again.
*
* More information about iframe transparency:
* - https://github.com/w3c/csswg-drafts/issues/4772#issuecomment-591553929
* - https://fvsch.com/transparent-iframes
*/
:host-context(.sci-empty) iframe {
display: none;
}
div[part="splash"] {
position: absolute;
inset: 0;
}
</style>
<iframe src="about:blank" scrolling="yes" marginheight="0" marginwidth="0"></iframe>
<template id="splash">
Expand All @@ -68,6 +34,40 @@ const HTML_TEMPLATE = `
</div>
</template>
`;
const STYLE_SHEET = `
:host {
display: block;
overflow: hidden;
position: relative; /* positioning context for splash */
}
iframe {
width: 100%;
height: 100%;
border: none;
margin: 0;
}
/* Ensure transparent router-outlet if empty.
*
* An iframe is transparent only if the embedded content has the same color scheme as the embedding document.
* An empty router-outlet loads the 'about:blank' page. This page has the user's preferred OS color scheme,
* which may be different from the application's color scheme, making the iframe opaque. Therefore, we hide
* the iframe to make the router-outlet transparent again.
*
* More information about iframe transparency:
* - https://github.com/w3c/csswg-drafts/issues/4772#issuecomment-591553929
* - https://fvsch.com/transparent-iframes
*/
:host-context(.sci-empty) iframe {
display: none;
}
div[part="splash"] {
position: absolute;
inset: 0;
}
`;

/**
* Web component that allows embedding web content using the {@link OutletRouter}. The content is displayed inside
Expand Down Expand Up @@ -274,6 +274,12 @@ export class SciRouterOutletElement extends HTMLElement {
this._outletName$ = new BehaviorSubject<string>(PRIMARY_OUTLET);
this._shadowRoot = this.attachShadow({mode: 'open'});
this._shadowRoot.innerHTML = HTML_TEMPLATE.trim();

// Add styles using a constructable stylesheet instead of inline styles, as inline styles require a nonce if CSP blocks 'unsafe-inline' styles.
const styleSheet = new CSSStyleSheet();
styleSheet.replaceSync(STYLE_SHEET);
this._shadowRoot.adoptedStyleSheets.push(styleSheet);

this._iframe = this._shadowRoot.querySelector('iframe')!;
this._contextProvider = new RouterOutletContextProvider(this._iframe);
this._splash = new Splash(this._shadowRoot, this._iframe);
Expand Down

0 comments on commit 40e4fbd

Please sign in to comment.