Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSP header issue #158

Closed
daybugging opened this issue Feb 16, 2018 · 22 comments · Fixed by #528
Closed

CSP header issue #158

daybugging opened this issue Feb 16, 2018 · 22 comments · Fixed by #528

Comments

@daybugging
Copy link

Hey there,
great plugin, just one thing:
Currently I'm implementing CSP headers for more security, is there an easy way to access the <style> tag being injected at the end of the document? I want to get rid of all unsafe-inline tags, or at least need a way to add nonces / hashes to make them safe.

What's the best way to go about this?
Thx!

Tiny-slider version: current
Browser name && version: Firefox, Chrome

@S1SYPHOS
Copy link
Contributor

One could, however include the styles anyway, but .. since the inline-styles aren't loaded, the script won't work - instead, you'll receive this:

Uncaught TypeError: Cannot use 'in' operator to search for 'insertRule' in undefined:
var rule = 'insertRule' in sheet ? sheet.cssRules : sheet.rules;

@ganlanyuan
Copy link
Owner

I could give access to the sheet element, but yes, without the inline style, the slider won't work.
Please let me know what else I can do.
Thanks

@S1SYPHOS
Copy link
Contributor

Well, we'd need a way to pass a nonce to the <style> tag, which is basically just a string, eg:

<style nonce="SOME-STRING">
  <!-- tns rules -->
</style>

Passing a hash isn't an option imho, since we don't control the styles, and they may change.

@ganlanyuan
Copy link
Owner

sheet was included in the info object in this commit.
Please let me know if this helps

@daybugging
Copy link
Author

Hey @ganlanyuan and @S1SYPHOS,
with this new commit, how would I insert a nonce attribute to tiny-slider's inlined <style> tag?
THX!

@ganlanyuan
Copy link
Owner

var slider = tns(),
    sheet = slider.getInfo().sheet;

sheet.nonce = 'string';

@S1SYPHOS
Copy link
Contributor

S1SYPHOS commented Mar 1, 2018

@ganlanyuan:
Alright, I'm able to pass a value to the array's nonce attribute, but somehow it's not applied on the actual <style> HTML element ..

@ganlanyuan
Copy link
Owner

Can you get the nonce value if you do sheet.nonce after you set it?
Though it may not appears in the inspector panel of the dev tool.

@S1SYPHOS
Copy link
Contributor

S1SYPHOS commented Mar 1, 2018

Yeah:
console.log(sheet.nonce) outputs the nonce properly. Logging sheet gives this:

CSSStyleSheet
...
nonce: "Kjd1+yGHJIBFJCNQjY1jkuD0s7g="
...

@ganlanyuan
Copy link
Owner

I actually can't test whether it works for CSP headers or not.
Can you test it on your side?

@S1SYPHOS
Copy link
Contributor

S1SYPHOS commented Mar 1, 2018

Any way to check wether this gets applied or not with Chrome's dev-tools? I know it's complicated, being injected and all ..

@michielmetcake
Copy link

michielmetcake commented Jun 18, 2019

Any update on this issue? The inline animation style is blocking my CSP form passing without tge 'unsafe-inline' rule.

@codegain
Copy link

I ran into the same problem today. The problem is within the method createStyleSheet which is called on initialization:

      ...
      autoplayHoverPause = getOption('autoplayHoverPause'),
      autoplayResetOnVisibility = getOption('autoplayResetOnVisibility'),
      sheet = createStyleSheet(),
      lazyload = options.lazyload,
      lazyloadSelector = options.lazyloadSelector,
      ...

In this function, the <style> tag is created and appended to <head>:

// create and append style sheet
export function createStyleSheet (media) {
  // Create the <style> tag
  var style = document.createElement("style");
  // style.setAttribute("type", "text/css");

  // Add a media (and/or media query) here if you'd like!
  // style.setAttribute("media", "screen")
  // style.setAttribute("media", "only screen and (max-width : 1024px)")
  if (media) { style.setAttribute("media", media); }

  // WebKit hack :(
  // style.appendChild(document.createTextNode(""));

  // Add the <style> element to the page
  document.querySelector('head').appendChild(style);

  return style.sheet ? style.sheet : style.styleSheet;
};

It think it would be sufficient if there were an additional configuration option like nonce which would then be passed to createStyleSheet as an additional parameter.

Bufallo added a commit to Bufallo/tiny-slider that referenced this issue Jan 21, 2020
This option adds a nonce attribute to the inline style tag
created by tiny-slider. It allows the usage of tiny-slider
with a more strict Content Security Policy. Its not necessary
anymore to allow unsafe-inline.

Resolves: ganlanyuan#158
@Bufallo
Copy link
Contributor

Bufallo commented Jan 21, 2020

I added the option mentioned by @codegain.
I tested it with a strict CSP without the unsafe-inline source without problems.

Is the media parameter of the createStyleSheet method still used?

@ganlanyuan
Copy link
Owner

Thank you all!

@codegain
Copy link

@ganlanyuan Is a new release planned with this feature included?

@S1SYPHOS
Copy link
Contributor

S1SYPHOS commented Jul 22, 2020

@Bufallo:

I added the option mentioned by @codegain.
I tested it with a strict CSP without the unsafe-inline source without problems.

Is the media parameter of the createStyleSheet method still used?

Sorry to bring this up again, but ..

.. 'm getting the nonce from data-nonce, where my PHP code generates it and sends the corresponding CSP header - but it's still complaining about it: Refused to apply inline style because it violates the following Content Security Policy directive style-src .. the injected <style> tag is empty ..

@Xavier4492
Copy link

Hello, do you have any idea how to integrate the generated nonce in my server request at the file tiny-slider.js ?

Usually I get it while asking req.nonce, I tested with XMLHttpRequest(), but it doesn't work.

server.js :

const
    express = require('express'),
    app = express(),
    hbs = require('express-handlebars'),
    port = process.env.PORT || 3000,
    morgan = require('morgan');

  require('dotenv').config()
  
  // Morgan
  app.use(morgan('dev'))
  
  // Handlebars
  app.set('view engine', 'hbs');
  app.engine('hbs', hbs({
      extname: 'hbs',
      defaultLayout: 'main'
  }));
  
  // Express Static (Permet de pointer un dossier static sur une URL)
  // Exemple: le chemin /assets nous donnera accès au dossier public
  app.use('/assets', express.static('ressources'));
  
  //Inclus l'en-tête CSP dans chaque requette du serveur
  const { expressCspHeader, SELF, NONCE } = require('express-csp-header');
  app.use(expressCspHeader({
  
      directives: {
          'default-src': [SELF, 'http://localhost:3000', 'https://www.google-analytics.com/g/'],
          'font-src':[SELF, 'https://fonts.googleapis.com', 'https://fonts.gstatic.com'],
          'script-src': [SELF, NONCE, 'www.googletagmanager.com'],
          'style-src': [SELF, NONCE, 'https://fonts.googleapis.com'],
          'img-src': [SELF, 'data:', 'https://www.gstatic.com/images/', 'http://www.w3.org/2000/svg'],
          'frame-src' : [SELF, 'https://www.googletagmanager.com'],
          'block-all-mixed-content': true
      },
      reportOnly: true
  }));
  
  // Body Parser qui nous permet de parser des data d'une req a une autre
  app.use(express.json());
  app.use(express.urlencoded({
      extended: false
  }));
  
  module.exports = { app }
  
  // Router
  const ROUTER = require('./api/router')
  app.use('/', ROUTER)
  
  // Home
  app.use((req, res) => {
      res.render('home', {
          nonce: req.nonce,
          listScript:[
              { "module": "tinyslider", "styleURL": "/assets/vendor/tiny-slider/dist/tiny-slider.css", "scriptURL": "/assets/vendor/tiny-slider/dist/min/tiny-slider.js" }
          ]
      })
  })
  
  // Lancement de l'application
  app.listen(port, () => {
      console.log("le serveur tourne sur le port: " + port);
  });

@Bufallo
Copy link
Contributor

Bufallo commented Aug 23, 2021

Sorry to bring this up again, but ..

.. 'm getting the nonce from data-nonce, where my PHP code generates it and sends the corresponding CSP header - but it's still complaining about it: Refused to apply inline style because it violates the following Content Security Policy directive style-src .. the injected <style> tag is empty ..

I ran into an similar issue and searched the code for inline styles. It seems like there are still inline styles with the navigtion option.
So for me it is only working with nav: false

@Xavier4492
Copy link

Xavier4492 commented Sep 10, 2021

Désolé de revenir sur ce sujet, mais ..
.. j'obtiens le nonce de data-nonce, où mon code PHP le génère et envoie l'en-tête CSP correspondant - mais il s'en plaint toujours : Refused to apply inline style because it violates the following Content Security Policy directive style-src.. la <style>balise injectée est vide ..

J'ai rencontré un problème similaire et j'ai recherché dans le code des styles en ligne. Il semble qu'il existe encore des styles en ligne avec l'option de navigation.
Donc pour moi ça ne marche qu'avecnav: false

Yeaaaaaa
dist/tiny-slider.js
nonce: 'yourNonce' ------> put your nonce line 505
hiddenStr = navAsThumbnails ? '' : ''; ----> (delete style="display:none;") line 1489

@crustamet
Copy link

Can we please update this issue, i have moved from owl.carousel with this library, for the most part owl doesn`t have this issue and it is a library 5 years old.

We surely can make a css style sheet so it will be included the class instead of the dynamic inline style PLEASE fix this issue it would be a shame to go back to owl.carousel.

Putting a nonce inside there is not a fix it is a workaround

@dnwjn
Copy link

dnwjn commented Jan 10, 2024

I know this is old, but in case someone ends up here that doesn't know about it:

When calling tns(), you can do the following in order to set the nonce on inline styles:

tns({
   ...
   nonce: 'YOUR-NONCE'
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants