Skip to content

Conversation

@ArneBab
Copy link
Contributor

@ArneBab ArneBab commented Jan 23, 2021

This change allows streaming playlists directly from the browser. It increases convenience of streaming and is required for streaming via freenet mobile ( https://github.com/freenet-mobile/app ), because Android apps don’t usually have access to the locally running Freenet node.

With this change, adding a media-tag that references an m3u-list like

<audio src="stream.m3u" controls="controls">
	not supported?
    </audio>

or

<video src="stream.m3u" controls="controls">
	<a href="stream.m3u">stream.m3u</a>, starting with <a href="sff-000.ogv">sff-001.ogv</a>. Putting the video here causes freesitemgr to more likely
put the first video into the container, giving a better initial impression.
    </video>

into a Freesite will turn the media-tag into an m3u-player that
dynamically loads consecutive entries from the m3u file as needed to
provide continuous play.

For a screencast of that, see https://www.youtube.com/watch?v=MHhyAf-bdLk

Limitation: there are still short but audible gaps on changing the track. These do not hurt when playing several audio-files but they can be annoying for streaming video — I worked around this by splitting the video at silence.

There are two example sites that go with this change:

  • Audio-Playlist: USK@1wpsnrzb9fiFmmq6OozoZ0Mnk376AlizUKjKPh3TXwM,CwfRO8X0xaCUzH28eoHigxUV-5TkRV8hCoQdO2kmsQM,AQACAAE/streaming-over-fproxy/3/

  • Streaming Video: USK@UGh1rxaHczJVr4k4LwxWrxFBc-Dt5P0F3IuPONpp8ZQ,klWF5g9B2PLst8tRO8c9tzk6XvisGynFVJRzM8-9718,AQACAAE/stream-36c3-sff/3/

The script pre-loads entries as blobs to circumvent the latency challenges within Freenet.

Security-relevant changes

There are three changes in this pull-request that need careful review:

  • The default-src CSP-header changed from default-src 'self' to default-src 'self' blob: to allow the media-tags to access blobs created by the inline-Javascript.
  • The script-src CSP-header for freesites changed from script-src 'none' to script-src 'sha256-{HASH}', explicitly allowing only the m3u-player to be inlined (if byte-by-byte the same).
  • The content of m3u-player.js is injected into Freesites. This is active Javascript (without dependencies), so it needs very careful checking.

For easier testing, here’s a compiled jar you can drop into your Freenet folder (stop Freenet, replace both freenet.jar and freenet.jar.new, then start it again): freenet-jar.zip

With this change, adding a media-tag that references an m3u-list like

<audio src="stream.m3u" controls="controls">
	not supported?
    </audio>

or

<video src="stream.m3u" controls="controls">
	<a href="stream.m3u">stream.m3u</a>, starting with <a href="sff-000.ogv">sff-001.ogv</a>. Putting the video here causes freesitemgr to more likely
put the first video into the container, giving a better initial impression.
    </video>

into a Freesite will turn the media-tag into an m3u-player that
dynamically loads consecutive entries from the m3u file as needed to
provide continuous play.
When splitting video by silence there are too often two consecutive
small segments. I did not see three consecutive small segments in the
example stream, and this should work for the example stream. Further
optimization can come with more experience with different streams.

Example-Stream:
  SSK@UGh1rxaHczJVr4k4LwxWrxFBc-Dt5P0F3IuPONpp8ZQ,klWF5g9B2PLst8tRO8c9tzk6XvisGynFVJRzM8-9718,AQACAAE/stream-36c3-sff-5/
@desyncr
Copy link
Contributor

desyncr commented Mar 6, 2021

Two small things mentioned over IRC as well:

  • Would be worth checking if there's an actual audio/video tag in the body?
  • Worth adding a configuration for this thing? So people can enable/disable it?

@nextgens
Copy link
Contributor

nextgens commented Mar 7, 2021

I don't understand why it's inlined at all... Can't you just add a <script src="/js/m3u-player.js"></script> to the < head>? The actual player isn't dynamically generated, is it?

This would avoid changing the CSP, would avoid any escaping concerns in the JS, would allow the browser to cache the result... and would save CPU cycles/latency.

@ArneBab
Copy link
Contributor Author

ArneBab commented Mar 7, 2021

I can add the script-tag, but then I could not use the strict by-hash CSP (I tried, it didn’t work) which ensures that even if fproxy misses a script tag that bleeds to the browser, the browser will still not execute it. Instead I would have to change script-src to self, which would allow referencing any fproxy scripts.

I want to avoid setting script-src to self, because that would expose users to attacks via dns rebinding and such.

Using script-src 'sha256...' is the smallest opening I can give in our CSP header that suffices to run the script.

@nextgens
Copy link
Contributor

nextgens commented Mar 7, 2021

Okay. You may want to consider adding 'strict-dynamic' too then

@ArneBab
Copy link
Contributor Author

ArneBab commented Mar 7, 2021

Wouldn’t that allow requesting external scripts that are not checked by hash?

Ideal would be to load the script with sri-check, but that did not work with the hash, and if I understand strict-dynamic correctly, I’d still have to get the script from an inlined script where I’m not sure whether the SRI-check would apply.

@ArneBab
Copy link
Contributor Author

ArneBab commented Mar 13, 2021

I’ll keep the config easier for now: Enable this only if fproxy has javascript enabled.

@ArneBab
Copy link
Contributor Author

ArneBab commented Mar 13, 2021

I now added a config option. Was easier than expected …

@ArneBab ArneBab merged commit 1785628 into next Mar 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants