Problem with video.js and Content Security Policy (CSP) - video.js

I am using a 'standard' setup of video.js on a page, the video tag code is as follows:
<video
id="my-video"
class="video-js"
controls
preload="auto"
width="640"
height="264"
poster="MY_VIDEO_POSTER.jpg"
data-setup="{}"
>
<source src="/videos/Sinéad O’Connor - Nothing Compares 2 U.mp4" type="video/mp4" />
<source src="MY_VIDEO.webm" type="video/webm" />
<p class="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading to a
web browser that
<a href="https://videojs.com/html5-video-support/" target="_blank"
>supports HTML5 video</a
>
</p>
</video>
I make usage of Content Security Policy (CSP), and I am having problems resolving the following issues:
Refused to create a worker from 'blob:http://localhost:3000/f215d47b-01ab-4ea4-943f-84c83cc5294c' because it violates the following Content Security Policy directive: "worker-src self".
Refused to load the font 'data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAABDkAAsAAAAAG6gAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIslek9TLzIAAAFEAAAAPgAAAFZRiV3hY21hcAAAAYQAAADaAAADPv749/pnbHlmAAACYAAAC3AAABHQZg6OcWhlYWQAAA3QAAAAKwAAADYZw251aGhlYQAADfwAAAAdAAAAJA+RCLFobXR4AAAOHAAAABMAAACM744AAGxvY2EAAA4wAAAASAAAAEhF6kqubWF4cAAADngAAAAfAAAAIAE0AIFuYW1lAAAOmAAAASUAAAIK1cf1oHBvc3QAAA/AAAABJAAAAdPExYuNeJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCACY7BUgAeJxjYGS7wTiBgZWBgaWQ5RkDA8MvCM0...2DDXbYkhKc+V0Bqs5Zt9JM1HQGBRTm/EezTmZNKtpcAMs9Yu6AK9caF76zoLWIWcfMGOSkVduvSWechqZsz040Ib2PY3urxBJTzriT95lipz+TN1fmAAAAeJxtkMl2wjAMRfOAhABlKm2h80C3+ajgCKKDY6cegP59TYBzukAL+z1Zsq8ctaJTTKPrsUQLbXQQI0EXKXroY4AbDDHCGBNMcYsZ7nCPB8yxwCOe8IwXvOIN7/jAJ76wxHfUqWX+OzgumWAjJMV17i0Ndlr6irLKO+qftdT7i6y4uFSUvCknay+lFYZIZaQcmfH/xIFdYn98bqhra1aKTM/6lWMnyaYirx1rFUQZFBkb2zJUtoXeJCeg0WnLtHeSFc3OtrnozNwqi0TkSpBMDB1nSde5oJXW23hTS2/T0LilglXX7dmFVxLnq5U0vYATHFk3zX3BOisoQHNDFDeZnqKDy9hRNawN7Vh727hFzcJ5c8TILrKZfH7tIPxAFP0BpLeJPA==' because it violates the following Content Security Policy directive: "font-src 'self' fonts.gstatic.com maxcdn.bootstrapcdn.com".
I am not understanding what my CSP directives should read in order to resolve these two errors. I added a "worker-src: 'self'" however that had no effect, I am unclear on what this 'worker' is supposed to do or how it is generated (I assume from the player code in video.js?) and where the 'font-woff' is being generated...?
Any advice greatly appreciated. I thank you in advance.

You have to modify CSP:
worker-src 'self' -> worker-src 'self' blob:;
font-src 'self' fonts.gstatic.com maxcdn.bootstrapcdn.com; -> font-src 'self' data: fonts.gstatic.com maxcdn.bootstrapcdn.com;
Note: worker-src: 'self' is wrong because of : is not allowed there.
And, yes, it's a video.js creates worker. data: in fonts is a common practice for Google fonts.

Related

Nuxt + Vuetify using Content Security Policy (CSP) header inline styling

For my company I need to update our Nuxt + Vuetify application to make use of a Content Security Policy (CSP) header.
'unsafe-inline' is not allowed for 'default-src'. The problem we are currently facing is that Vuetify adds style attributes at runtime to the DOM elements.
So for example:
<div id="app">
<v-system-bar app>
<v-container>Content</v-container>
</v-system-bar>
</div>
Results in:
<div class="v-system-bar v-system-bar--fixed theme--light" style="height: 24px;">
<div class="container">Content</div>
</div>
The CSP header does not allow the style="height: 24px". This gives me the following error:
Refused to apply inline style because it violates the following Content Security Policy directive: "style-src https://unpkg.com/ 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-gGKtWVlwtb9dj1Sa7K4ybKpqUOE61nkachaCJ1LfmFY='), or a nonce ('nonce-...') is required to enable inline execution.
This problem also occurs for other vuetify components, the v-system-bar is just an example. I know that adding a nonce for <style> elements is possible, but not for style attributes. Is there a way to solve this problem, besides setting the header to unsafe-inline? I want to keep using Vuetify together with the CSP header.
Here is a codepen link: https://codepen.io/erikeuserr/pen/WNpbOwx.
Thanks in advance!
The constructions like style="height: 24px" appear in the code as result of vue.js (not vuetify.js) script work. A vue.js uses a el.setAttribute() func to set style= property. The el.setAttribute('style', ...) is counted by CSP as unsafe therefore vue.js is not CSP-compatible.
But el.style.property = '...' is safe, so in order to make vue.js a CSP compatible, it need to replace all el.setAttribute('style', 'background-color:#e2e2e2; height: 24px; display:inline;') by the according sets of:
el.style.backgroundColor = '#e2e2e2';
el.style.height = '24px';
el.style.display = 'inline';
There is a rough hack to do this - globally redefine setAttribute() when it's called with a 'style' argument.
Before output the page into browser, you can catch and replace all style='...' by data-style='...' in the html code, and then use script like:
styleList = document.querySelectorAll("[data-style]");
styleList.forEach( function(style) {
// convert a 'background-color:#e2e2e2; height: 24px; display:inline;' strings
// to the set of 'el.style.backgroundColor = '#e2e2e2'; ... el.style.display = 'inline';'<br> });`
Yes, these are patches, but understanding the essence of the problem, you may be able to find a more elegant solution.

Issue playing a video on Jenkins HTML Publisher

I am using Testcafe for my project tests and I am generating a HTML report with screenshot and video in my project.
When I am trying to publish the report using HTML publisher, the video is not playing.
When I open the generated HTML file in the Jenkins agent via browser, the video is playing fine. not sure, why it is not playing on the Jenkins HTML publisher plugin.
MY HTML video code looks like below
<div class="row">
<div class="column">
<img id="myImg" class="errImage" src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAABAAAA" style="width:100%;">
</div>
<div class="column">
<video autoplay muted loop controls id="errorVideo" style="width:99%">
<source src="C:\Program Files (x86)\Jenkins\workspace\Free style node test\e2e\artifacts\videos\Getting Started\My First Test\1.mp4" type="video/mp4">
</video>
</div>
</div>
I tried configuring following content security policy
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "sandbox; default-src '';")
not sure what policy is blocking the video from playing on the Jenkins publisher.
Can someone help to resolve this issue? Thanks in advance.
The policy which blocking your video from playing is media-src == "none", derived from default-src == 'none' (see https://wiki.jenkins.io/display/JENKINS/Configuring+Content+Security+Policy)
Take a look at the solution in https://github.com/jenkinsci/screenrecorder-plugin/blob/master/src/main/java/org/jenkinsci/plugins/screenrecorder/ScreenRecorderBuildWrapper.java, it could work for you:
String curCsp = System.getProperty("hudson.model.DirectoryBrowserSupport.CSP","");
if (!curCsp.contains("media-src"))
{
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", curCsp + ";media-src 'self';");
}

Videojs can't play m3u8 blob URL

I am using Videojs version 7.6.6. It will not play a html5 video if the src is a blob URL. It will load the video time however, but will not play. I get this warning, and then it loads forever:
VIDEOJS: WARN: Problem encountered with the current HLS playlist. Trying again since it is the only playlist.
This is the way my code runs:
<video id="my_video" class="video-js vjs-matrix vjs-default-skin vjs-big-play-centered" controls
preload="none" width="640" height="268" data-setup="{}"></video>
<script type="text/javascript" src="/js/video-766.min.js"></script>
<script>
fetch("https://server/hls/index.m3u8").then(result => result.blob())
.then(blob => {
var blobURL = URL.createObjectURL(blob);
var player = videojs("my_video");
player.src({ src: blobURL, type: "application/x-mpegURL" });
}
);
</script>
If I try it without a blob, just a regular URL to the index.m3u8 file, then it works. So this is a problem with the creation of the blob URL I think. This works, the video starts playing:
<video id="my_video" class="video-js vjs-default-skin" height="360" width="640" controls preload="none">
<source src="https://server/hls/index.m3u8" type="application/x-mpegURL" />
</video>
<script>
var player = videojs('my_video');
</script>
I have searched for this issue and found a lot, but none of it helps me. Am I creating the blob wrong?
The object URL that is generated for the blob will start with file:// protocol if I'm not wrong. Browsers doesn't let you load data with file:// URL. I ran into a similar problem so I created a simple server on my app which returns the requested file over https:// .
The reason why your index.m3u8 is running because it is served over https protocol

Creating Vue instance comments out everything

I'm trying to create an Chrome extension with web accessible resources. Since my extension tries to create a modal with a list of available data, I decided to use VueJS to handle the dynamic nature of content.
However, When I create the sample files and initialize VueJS, it simply leads to all the DOM being commented out and my app not working.
Here's the code I'm using:
web_resources/vue.html
<html>
<head>
<script type="text/javascript" src="/web_resources/vue.js"></script>
</head>
<body>
<div id="app">
{{ message }}
</div>
<script type="text/javascript" src="/web_resources/app.js"></script>
</body>
</html>
web_resources/app.js
window.app = new Vue({
el: '#app',
data: {
message: 'Hello World'
}
})
When I run this, the entire div is replaced with: <!----> and nothing works.
On searching online for VueJS inside iframe, I came across this post which has this fiddle which surprisingly produces a blank page for me with no content. On inspecting the result, I find that the div has been replaced with <!----> here as well.
Why is VueJS not initializing properly within an iframe?
The problem was Content Security Policy (CSP). Since I was using a local copy of vue.min.js, I couldn't see any of the error messages. It looked like everything was initializing as expected except it wasn't. Once I replaced this with a un-minified version, I saw an error on the lines of:
I simply had to go update the CSP in manifest.json which I was able to do by adding:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",

videojs in Chrome: how to make a video starts where I choose?

I am playing with video.js. Here is my code:
<link href="//vjs.zencdn.net/5.4.6/video-js.min.css" rel="stylesheet">
<script src="//vjs.zencdn.net/5.4.6/video.min.js"></script>
<video id="example_video_1" class="video-js vjs-default-skin" style="margin-left:auto;margin-right:auto;"
controls autoplay preload="auto" width="1300" height="800"
data-setup='{}'>
<source src="/test.webm" type="video/webm" />
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video</p>
</video>
The above code was literally copied from the tool's website (except the video and autoplay):
http://docs.videojs.com/docs/guides/setup.html
My movie is played in both Chrome and Firefox. If I want to see something later in the movie, I am able to drag the dot in the progress bar to the point I want and the movie starts just there. However, when doing so in Chrome I got error:
A network problem caused the media download to fail part-way.
You can do it with javascript
videojs("last", {}, function () {
var myplayer = this;
myplayer.currentTime(s); // s being to time in second you want
}
Remove the data-setup attribute from the html tag and put what you had in second argument.
The first argument is the id of the video(be sure it has never been
initialized)
The second is optional it is what you want to have in data-setup
The third is a function that you want to call when it is
initialized.