redlib-org / redlib

Private front-end for Reddit
GNU Affero General Public License v3.0
1.31k stars 90 forks source link

🐛 Bug Report: #98

Open d4rklynk opened 6 months ago

d4rklynk commented 6 months ago

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

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'

ButteredCats commented 6 months ago

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

d4rklynk commented 6 months ago

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

ButteredCats commented 6 months ago

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-Policyheader 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 cat@matrix.catsarch.com on Matrix or butteredcats on Discord.

d4rklynk commented 6 months ago

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.

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;