redlib icon indicating copy to clipboard operation
redlib copied to clipboard

🐛 Bug Report:

Open d4rklynk opened this issue 1 year ago • 4 comments

Describe the bug

When setting Content Security Policy, it throws me an error (in the web console) that 'about:blank' is blocked by media-src 'self' blob:

It makes impossible to play videos with HLS turned on.

(I can play videos that didn't originally have sound though)

I can't allow about:blank since it's not a correct source.

Steps to reproduce the bug

  • Implement CSP.
  • Go to the instance.
  • Throw an error at the web console.

What's the expected behavior?

I should not have this error when media-src to 'self' blob: is set. And videos with sound should play when HLS is enabled.

Here's my CSP:

default-src 'none'; connect-src 'self'; font-src 'self'; img-src 'self' http://www.w3.org data:; media-src 'self' blob:; manifest-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; worker-src 'self' blob:; frame-ancestors 'none'; upgrade-insecure-requests; base-uri 'none'

d4rklynk avatar Apr 19 '24 11:04 d4rklynk

You don't have to set up the content security policy, Redlib sends those headers on it's own.

If you have a need to override them the defaults are: default-src 'none'; font-src 'self'; script-src 'self' blob:; manifest-src 'self'; media-src 'self' data: blob: about:; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none'; connect-src 'self'; worker-src blob:;

Those are from this: https://github.com/redlib-org/redlib/blob/27f25e0fb1962f3b3b8883e81889c5ccf148cf3a/src/main.rs#L192

You're missing data: and about: from your media-src

ButteredCats avatar Apr 20 '24 17:04 ButteredCats

Hi, thanks for your quick answer and for your time.

If I don't set the CSP on my own. They seem to be not set at all 🤔.

I never see in any URL the CSP in the response headers (c.f. below) (while I can see them when I set them on my own):

image

And about: scheme does not seem to be recognized as a source (from CSP pov) from what I saw in w3c documentation: https://www.w3.org/TR/CSP3/#security-inherit-csp

If I insert the URL of my instance in https://csp-evaluator.withgoogle.com/, it says that no CSP has been set. Same goes for Hardenize and internet.nl checkers

d4rklynk avatar Apr 21 '24 11:04 d4rklynk

Huh, yeah you're right about the about: directive. It looks like instead of being "special" like data: or blob: it's there because the src for the video is about:blank until you click on it when HLS is on (probably to prevent preloading). However when HLS is off this isn't the case and it just starts with the src being the link to the video.

In combination with that I found with just media-src 'self' blob: about: you can get videos working, data: doesn't seem to be included in any of the videos I'm testing with. Hence why you were able to get this to work without HLS turned off.

Regardless of any of that, the Content-Security-Policy header should be passed by the reverse proxy (seemingly Nginx based on the Server header).

If you connect directly Redlib without going through Nginx you should see the Content-Security-Policy header served (you can open devtools and if you click on a request in the network tab you can see the headers). It looks like Nginx isn't passing it. By any chance do you have a proxy_hide_header Content-Security-Policy; hiding somewhere in your Nginx configuration?

Unless the Content-Security-Policy header doesn't appear when connecting to Redlib without going through Nginx this isn't a Redlib bug though.

Assuming Redlib isn't bugged, if you want help troubleshooting your Nginx configuration over something faster than Github comments I'm [email protected] on Matrix or butteredcats on Discord.

ButteredCats avatar Apr 21 '24 22:04 ButteredCats

My bad, yes I added a proxy_hide_header to avoid duplicate of CSP. When I tested it, I forgot to remove it, your CSP does work.

Everything actually work as expected, the about: got in my head and my tests were poorly done.

Here's my final (working) CSP:

default-src 'none'; font-src 'self'; script-src 'self' blob:; manifest-src 'self'; media-src 'self' data: blob: about:; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none'; connect-src 'self'; worker-src blob:; upgrade-insecure-requests; webrtc 'block'; require-trusted-types-for 'script'; trusted-types 'none'

Weirdly, about: still needs to be added or video controls will be gray.

  • I added upgrade-insecure-requests because sometimes outbond links are unencrypted (most likely from some posts).
  • Added webrtc 'block', it's a new CSP directive only in experimental browser versions as of now.
  • Also added require-trusted-types-for 'script'; trusted-types 'none'. I can't really tell you what's for since I'm not a dev: but here some useful if you're interested: https://web.dev/articles/trusted-types. Videos still work but here's a screenshot error if you need:

image image

Here's my full security header (if someone in the future would need it).

proxy_hide_header 'Strict-Transport-Security';
proxy_hide_header 'Content-Security-Policy';
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'none'; font-src 'self'; script-src 'self' blob:; manifest-src 'self'; media-src 'self' data: blob: about:; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none'; connect-src 'self'; worker-src blob:; upgrade-insecure-requests; webrtc 'block'; require-trusted-types-for 'script'; trusted-types 'none'" always;
add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(self), battery=(), camera=(), clipboard-read=(), clipboard-write=(), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(self), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), screen-wake-lock=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always;
add_header Referrer-Policy "same-origin" always;
#add_header X-Content-Type-Options "nosniff" always; # Already added by redlib
add_header X-UA-Compatible "IE=Edge" always;
add_header X-XSS-Protection "0" always;
#add_header X-Frame-Options "DENY" always; # Already added by redlib
add_header Cross-Origin-Resource-Policy same-origin;
add_header Cross-Origin-Embedder-Policy require-corp;
add_header Cross-Origin-Opener-Policy same-origin;

d4rklynk avatar Apr 22 '24 06:04 d4rklynk