Semantic-UI breaks Content Security Policy - semantic-ui

Can Semantic-UI modal dialogs be used with Content Security Policy (CSP) directives but without requiring 'unsafe-inline'?
Semantic UI modals inject inline styles into the DOM. This then weakens the HTTP Content-Security-Policy header by requiring 'unsafe-inline' for styles.
Is it possible to externalize the inline styles into a stylesheet so that CSP can be used effectively?

Related

ReactJS - Refused to apply inline style because it violates the following Content Security Policy directive

I get the following error in the browser inspector (Chrome, Brave, Safari) when I load my ReactJS project in Production:
Refused to apply inline style because it violates the following Content Security Policy directive: "style-src-elem 'self' https://fonts.googleapis.com". Either the 'unsafe-inline' keyword, a hash ('sha256-TMIFk5ZjGNpczjRE6YVaBrPXVNzANj9JRK+w2bh9TX8='), or a nonce ('nonce-...') is required to enable inline execution.
I used the below command to build the ReactJS project (it solves the inline script issue, but not the inline style):
INLINE_RUNTIME_CHUNK=false npm run build
This is the CSP policy part referring to the style:
Header set Content-Security-Policy "default-src 'self'; style-src 'self'; style-src-elem 'self' https://fonts.googleapis.com; ..."
I believe the problem happens during the build phase, when React generates chunk files (with names such as '2.3c013fe3.chunk.js') and embeds inline style within the code, although I don't use inline style anywhere in my source code. All styles are contained in fileX.module.css and imported in the tsx files, like this example:
Example.tsx
import styles from './Example.module.css';
const Example = () => (
<div className={styles.container}>
Hello world
</div>
);
Example.module.css
.container {
display: flex;
flex-direction: column;
align-items: center;
}
If the auto-generated chunk files are the problem, I don't see how to solve this issue with hash or nonce alternatives, since React will always generate these inline styles. On the other hand, I assume unsafe-inline is not an option, since this essentially makes the CSP useless.
Any suggestion either on the CSP directives or React settings to solve this issue? (I read all similar Q&A but none of them refers to this specific problem with React)

How to override inline styles in AMP pages?

I have an html body with some tags containing inline styles.Normally we could override inline with !important
But as I need the page to be AMP valid , I couldn't use this method.
Any way to do this in AMP valid method ??
No. As you mentioned, in AMP you can not use the !important style. Also you can only have one style tag and it has to be in the head tag.
You can override the general styles inline but not the other way around.
AMP needs to be able to enforce its element sizing rules, allowing the !important style would interfere with that.

Angular: Component styles do not cascade to sub-components?

In my app.component.html I have the following, working class assignment.
<body>
<span class="test">SHABOO</span>
<div class="container">
<router-outlet></router-outlet>
</div>
</body>
In the outlet, a component is rendered and it contains the following.
<span class="test">HAZAA</span>
I expected it to get the same style as the first one but it seems that the style doesn't cascade down to the component. It made me uncertain if I'm mistaken about how the styles are supposed to behave between parent and child components in Angular.
I made sure that the name of the class isn't overriden (to exclude the risk of collision). At the moment, I'm putting similar chunks of SCSS code in each component and that's obviously bad practice.
If I #import "../app.component.scss", the styles kicks in. But I was under the impression that even without the import, the style is supposed to cascade.
Angular components use view encapsulation. This is by design so that components are reusable across applications. To treat a component's styles as global, set the view encapsulation mode to none (not recommended).
Instead of using none, register global style files in the Angular CLI styles section, which is pre-configured with the styles.css file.
Component CSS styles are encapsulated into the component's view and don't affect the rest of the application.
To control how this encapsulation happens on a per component basis, you can set the view encapsulation mode in the component metadata. Choose from the following modes:
ShadowDom view encapsulation uses the browser's native shadow DOM implementation (see Shadow DOM on the MDN site) to attach a shadow DOM to the component's host element, and then puts the component view inside that shadow DOM. The component's styles are included within the shadow DOM.
Native view encapsulation uses a now deprecated version of the browser's native shadow DOM implementation - learn about the changes.
Emulated view encapsulation (the default) emulates the behavior of shadow DOM by preprocessing (and renaming) the CSS code to effectively scope the CSS to the component's view. For details, see Appendix 1.
None means that Angular does no view encapsulation. Angular adds the CSS to the global styles. The scoping rules, isolations, and protections discussed earlier don't apply. This is essentially the same as pasting the component's styles into the HTML.
To set the components encapsulation mode, use the encapsulation property in the component metadata:
src/app/quest-summary.component.ts
// warning: few browsers support shadow DOM encapsulation at this time
encapsulation: ViewEncapsulation.Native
ShadowDom view encapsulation only works on browsers that have native support for shadow DOM (see Shadow DOM v1 on the Can I use site). The support is still limited, which is why Emulated view encapsulation is the default mode and recommended in most cases.
External and global style files
When building with the CLI, you must configure the angular.json to include all external assets, including external style files.
Register global style files in the styles section which, by default, is pre-configured with the global styles.css file.
See the CLI wiki to learn more.
This is how angular works. Every component is separated with it's CSS, even if it is child component of a parent. They can't inherit their parent CSS.
Haza span component is child of your app component, but it is separated component. So, you can't get those Shaboo styling to Haza.
Solution:
if you want to maintain same CSS, there are multiple ways.
Recommended way:
a) if it is only for onle class, copy the class to the child component.
b) if it is for huge number of classes, create a css file for them and import them in both parent and child component css.
Example:
#import '../span.css';
you can add this css to styles.css. then you will get it anywhere in the app. if you want this style many places, you can do it.
As #Christopher Peisert mentioned, by using
encapsulation: ViewEncapsulation.Native
end of the #component decorator in child.component.ts. It is not recommended way
The global CSS files are those that are listed in angular.json. All others CSS files are encapsulated by default (this can be removed but is not recommended.)
Keeping your global CSS organised is important as your application grows. What I like to do is create a global styles folder and then add new files for different widgets that I might be altering. Since removal of ::ng-deep these types of changes have to be done in the global scope.
It works like that. If you are in need of having a common style then add it in the global styles.scss file.
If you want a global style put it in the global file styles.css or styles.[Your css preprocessor]
See this example https://stackblitz.com/edit/angular-a5ntm6?file=src%2Fstyles.css
I put test class at the end
.test{
color:red;
}

How do I overwrite CSS generated from an outside widget?

I've embedded a widget on my page that links to this javascript file:
https://widget.zola.com/js/widget.js
The widget is generating a header section which i'd like to remove.
https://widget.zola.com/v1/widget/registry/taylorandjaredseptember7/html?:1
I've inspected the element and was able to target the section and add a display: none to it. That worked, but when I copied the code into my CSS style sheets, it was not working. I even tried adding !important to it with no luck.
Is there something obvious that I'm missing?
This is the code I added to my stylesheets.
.registry-header {
display: none !important;
}
I also tried targeting the classes it was nested in, like so:
.row registry-header-section .col-xs-12 .registry-header {
display: none !important;
}
Other background info that might be helpful:
- My site is a Wordpress site using the Divi theme.
Establish where the current rules are being generated from in the Document Tree and then use this question and answer to find how to effectively overwrite these rules.
Possible Routes:
You may need to use an id tag on the element and apply the style to the #id, because this will overwrite .class level styling.
You need to be as specific as possible with your targetting; your second example is better than your first.
Remember if the widget uses just a JS file then it's probably editing the CSS via Javascript inline, so it will be doing so inline, therefore you may need to add the style adjustment overwrite inline into the page itself. Set your <style> block to appear as late in the <head> as possible and add !important to the elements required
Create your own Javascript script to load after their widget script and to force CSS to adapt as you want it, with javascript or jQuery code blocks.
Crazy idea.... but it might just work.
You would first need to export from your Browser Inspector the current applied styling generated by the widget and save this to your own (domain-local) CSS file.
You can then use Content Security Policy to specifically block 'unsafe-inline' and 'unsafe-eval' in your style-src: part to block javascript and other inline styling from being applied to the page.
Replacing this with your export CSS style sheet should avoid Javascript/inline styling and allow you to tweak the styling as you need by simply editing your CSS code. You ca fine tune this depending on your dependancies and codebase.

Refused to apply inline style because it violates the following Content Security Policy: "style-src 'self' https://apis.google.com.

cb=gapi.loaded_0:formatted:2677
n.setAttribute("style", "position: absolute; width: 1px; height: 1px; left: -9999px;");
Here is the complete message:
Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' https://apis.google.com 'sha256-g1S9hiXQ4j0r+GB1Gi3NXXa9uB+5dR2H21SD7BToUKg='". Either the 'unsafe-inline' keyword, a hash ('sha256-WuACXZzzdKkWqck4qh4/nDEQy6ZpPTP0wGUXa/3oqT4='), or a nonce ('nonce-...') is required to enable inline execution.
I don't want to enable 'unsafe-inline'. What are my options? As shown above, it seems I can include only one sha1 hash in my style-src directive. But, I get multiple inline style violations each suggesting its own sha1 hash. May be I am using a wrong syntax to include multiple sha1 hashes? Any suggestions?
Thanks.
The problem is not that you can specify only one hash - this is not true. You can specify more hashes, e.g.
style-src 'self' 'sha256-g1S9hiXQ4j0r+GB1Gi3NXXa9uB+5dR2H21SD7BToUKg=' 'sha256-WuACXZzzdKkWqck4qh4/nDEQy6ZpPTP0wGUXa/3oqT4='
The problem is that at least some browsers (Chrome, Safari) apply 'shaXXX' rules to <style> elements only, not style attributes. See: https://bugs.chromium.org/p/chromium/issues/detail?id=546106
So, what are the options?
Use unsafe-inline (not recommended),
Rewrite the code to use <style> tags and use 'shaXXX' or 'nonce',
Use a separate style sheet (recommended).
I ended up using their OpenID Connect API since I didn't want to use unsafe-inline. It is more involved to (correctly) implement. Since google injects their code using an iframe, I thought they would quickly fix this issue using a <style> tag in the iframe. I think that would be more convenient for developers in the sense that they don't have to use OpenID Connect. Until that happens, I think OpenID Connect is the way to go.

Resources