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

[Enhancement] Add decryption of the sig parameter for bypassing throttling #4649

Open
unixfox opened this issue Apr 26, 2024 · 11 comments
Open
Labels
enhancement Improvement of an existing feature

Comments

@unixfox
Copy link
Member

unixfox commented Apr 26, 2024

Currently we do not support fetching the streams using WEB client because by default the stream is too slow. So we are only relying on the ANDROID client. But recently the ANDROID client has started to be blocked from youtube unless you pass "droidguard" challenge: #4584

This issue is to discuss how to implement the decryption of the sig parameter in order to avoid throttling.

An atempt was done back in #2222 but was closed due to potential issues around missing isolation when executing untrusted JavaScript code from YouTube.

So there are other solutions:

More ressources:

@unixfox unixfox added the enhancement Improvement of an existing feature label Apr 26, 2024
@unixfox unixfox changed the title [Enhancement] Add decryption of throttling and the sig parameter [Enhancement] Add decryption of the sig parameter for bypassing throttling Apr 26, 2024
@iBicha
Copy link
Contributor

iBicha commented Apr 26, 2024

Worth mentioning https://github.com/LuanRT/Jinter used in https://github.com/LuanRT/YouTube.js

Because it implements ONLY what the decipher function needs (string, arrays, and Math.*) there's no risk with RCE (at least not that I can see). It can't read from disk, read env vars or make network requests, because the functionality doesn't exist.

I find it an interesting approach

Edit: I guess similar to youtube-dl's interpreter

@ChunkyProgrammer
Copy link
Contributor

Another option could be: https://bun.sh/

@syeopite
Copy link
Member

For C bindings there is https://github.com/jessedoyle/duktape.cr

@SamantazFox
Copy link
Member

* Execute a separate [node](https://nodejs.org/en) process which is not part of the main invidious process. May be too permissive.

* Execute a separate [deno](https://deno.com/) process which is not part of the main invidious process. [Good potential because by default deno lock down a lot of permissions.](https://docs.deno.com/runtime/manual/basics/permissions)

Either of those is something I'd prefer, yep. And the more we can contain it, the better. We don't know what kind of API Youtube will use in the future.

* Create bindings for using a C library that allows to evaluate isolated javascript code. I do not know any library like this.

* Use the minimal JS interpreter from yt-dlp by executing it using python: https://github.com/dirkf/youtube-dl/blob/master/youtube_dl/jsinterp.py

Not an option, imo. This would have to run a lot of times for each request.
We also need a solution which is caching the extracted JS for some time, so the function can be reused without making extra calls to Youtube.

@Theta-Dev
Copy link
Contributor

What would be the security issue when running untrusted code in an embedded JS interpreter like Duktape or QuickJS?
NodeJS and Deno add a lot of APIs for things like network and file IO, so they have to be locked down when running untrusted code.

None of this is possible with these embedded interpreters and they would be the fastest and most lightweight solution.

@SamantazFox
Copy link
Member

What would be the security issue when running untrusted code in an embedded JS interpreter like Duktape or QuickJS? NodeJS and Deno add a lot of APIs for things like network and file IO, so they have to be locked down when running untrusted code.

None of this is possible with these embedded interpreters and they would be the fastest and most lightweight solution.

That's a good question! I have not looked at any of those yet, so I don't know their strengths and weaknesses.

Though, whatever the selected solution, I'd greatly prefer for it to be in a separate process, at least to benefit from running on a separate thread than invidious.

@techmetx11
Copy link
Contributor

techmetx11 commented Apr 26, 2024

I'm making a helper for Invidious in C, It will use QuickJS and do the following:

  • Fetch player script and extract functions independently from Invidious
  • Communicate with Invidious via a UNIX or TCP socket
  • Execute the functions from within the helper (this allows it to be isolated using kernel security measures like AppArmor/SELinux and also not be able to access Invidious' memory)
  • (bonus) Store the extracted signature functions in a temporary location and perhaps, the pre-compiled bytecode version of it

In case of a RCE, syscalls can be isolated by the kernel using pledge (OpenBSD) or seccomp (Linux)

@Vizonex
Copy link

Vizonex commented Apr 29, 2024

  • Create bindings for using a C library that allows to evaluate isolated javascript code. I do not know any library like this.

Did you try duktape? It allows for compatibility with C and Javascript and there is less drag than using v8. It might be just what you guys were looking for.

@techmetx11
Copy link
Contributor

Check out what I'm making (switched to Rust after some talk with SamantazFox): https://github.com/techmetx11/inv_sig_helper

@unixfox
Copy link
Member Author

unixfox commented Apr 29, 2024

  • Create bindings for using a C library that allows to evaluate isolated javascript code. I do not know any library like this.

Did you try duktape? It allows for compatibility with C and Javascript and there is less drag than using v8. It might be just what you guys were looking for.

Yes already said in #4649 (comment)

And PR #2222 was implemented with duktape.

@techmetx11
Copy link
Contributor

Check out what I'm making (switched to Rust after some talk with SamantazFox): https://github.com/techmetx11/inv_sig_helper

My program is done (along with the protocol documentation in README), all that's needed is writing some interface code in Invidious

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement of an existing feature
Projects
None yet
Development

No branches or pull requests

8 participants