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

Custom javascript injection #309

Closed
in4u opened this issue Nov 18, 2018 · 26 comments
Closed

Custom javascript injection #309

in4u opened this issue Nov 18, 2018 · 26 comments
Labels
duplicate This issue or pull request already exists

Comments

@in4u
Copy link

in4u commented Nov 18, 2018

uBO's quite powerful and efficient as it is. However, in light of some recent filter-related issues, I realized that if support for custom javascript injection was added then there would be no base left uncovered by uBO.

Like for uBlockOrigin/uAssets#4143, Adguard has this nifty solution.

And such a feature would have also helped in uBlockOrigin/uAssets#4138 (comment). In the same thread, there was a discussion about implementing something along the lines of ABP's $rewrite (useful for certain other issues too) which I feel could probably be redundant if custom javascript injection was supported.

The risk of misuse of this powerful feature can be mitigated to a large extent by allowing it for trusted lists only, similar to Adguard's implementation.

Please note that I tried searching for issues related to this feature enhancement here but couldn't find one. So, my apologies in case this has been discussed before and a decision has already been taken in this regard.

@uBlock-user
Copy link
Contributor

uBlock-user commented Nov 18, 2018

Cookie injection is that what you're proposing ?

Won't happen, see - uBlockOrigin/uAssets#4080 (comment)

Although you can create/add a custom cookie scriptlet on your own and use that as a fix which I do.

@uBlock-user uBlock-user changed the title Feature request: Custom javascript injection Custom javascript injection Nov 18, 2018
@uBlock-user uBlock-user added the enhancement New feature or request label Nov 18, 2018
@in4u
Copy link
Author

in4u commented Nov 18, 2018

What I proposed includes but is not restricted to cookie injection.

@uBlock-user
Copy link
Contributor

I have updated my reply FYI

@uBlock-user
Copy link
Contributor

uBlock-user commented Nov 18, 2018

Adguard's nifty solution relies on cookie insertion which is what your proposal is based on and $rewrite will not be implemented as it was already declined before - #46 (comment)

@in4u
Copy link
Author

in4u commented Nov 18, 2018

I have addressed how to mitigate security concerns in my post. The feature could be limited to trusted lists only, including official uBO lists and user's personal list. If even uBO's lists can't be trusted then IDK how to feel about that. Maybe just allow for user list to begin with?

@uBlock-user
Copy link
Contributor

uBlock-user commented Nov 18, 2018

Maybe just allow for user list to begin with?

Like I said, you could use a custom scriptet and allocate the URL in userResourcesLocation via advancedsettings.html

@in4u
Copy link
Author

in4u commented Nov 18, 2018

Yes, that might take care of begin with. But what about the next step? Can't uBO's own lists be trusted?!

@uBlock-user
Copy link
Contributor

It's not more about uBO's own lists but rather external lists making use of uBO's scriptlets.

@in4u
Copy link
Author

in4u commented Nov 18, 2018

That is not a problem at all. As I noted earlier, only trusted lists could be allowed to use proposed functionality. How can external lists make use of it if they are not explicitly allowed? Quoting from Adguard's implementation page:

Please note that this type of rules can be used only in trusted filters. This category includes your own User filter and all the filters created by AdGuard Team.

Something similar can be done for uBO where only uBO's official lists are allowed along with user's own.

@jspenguin2017
Copy link

Privileged scriptlets were discussed before: uBlockOrigin/uAssets#2099

@in4u
Copy link
Author

in4u commented Nov 19, 2018

I'm not much familiar with uBO's internal scriptlet system and it was only recently that I was introduced to this page (which somehow isn't prominently, if at all, linked to in the main wiki). Going through the link shared by @jspenguin2017 gave me an idea, so I am just going to think out loud here:

  1. Create a scriptlet custom.js which accepts one string parameter.

  2. The parameter's value can be any javascript code.

  3. custom.js contains a function which executes the javascript code passed as parameter value.

  4. Any rule invoking custom.js from a list outside uBO's official ones or user's own, gets discarded.

That's it. Something like this might achieve what I am proposing? Just my immediate thoughts as a layman who's still trying to figure out scriptlets.

@uBlock-user
Copy link
Contributor

Sure it can work out, it's not impossible so to speak, but it's upto @gorhill.

@jspenguin2017
Copy link

jspenguin2017 commented Nov 19, 2018

@in4u That would violate Firefox extension store policy. I don't really care but gorhill probably will.

@in4u
Copy link
Author

in4u commented Nov 19, 2018

Oh well, I am not aware of the technicalities @jspenguin2017, so you guys are the best judge regarding implementation. I guess going about it Adguard's way is always an option. And if they are also violating some policy then surely uBO can too.

@jspenguin2017
Copy link

jspenguin2017 commented Nov 19, 2018

Adguard releases a limited version for Firefox, which have all script inject rules hard coded. For uBO right now, the resource manifest is frozen for Firefox builds, but rules that use the resource manifest can update.

I think the user can still add their own rules to Adguard, but it is really awkward to use last time I checked. You have to edit one rule at a time and your code have to be all on one line. If you want to inject your own script, try Tampermonkey or Violentmonkey.

@in4u
Copy link
Author

in4u commented Nov 20, 2018

Interesting. Anyways, one thing I still can't wrap my head around is how what I suggested violates a policy when it's no different from what already exists?

Based on whatever little I understand, in ELI5 terms, scriptlet is like a function with parameters. There are already many such functions which uBO currently uses. I just added a new one. Now either this whole scriptlet thingy should already be in violation of that policy or else adding one more shouldn't be violating any policy. What am I missing?!

@jspenguin2017
Copy link

jspenguin2017 commented Nov 20, 2018

A scriptlet is a function with parameters that is safe no matter what parameters are passed in.

@in4u
Copy link
Author

in4u commented Nov 20, 2018

Thanks for that clarification! Can't this be tackled somehow? Like instead of passing exact javascript code as parameter, encapsulate it in some block so that it just becomes harmless text parameter on its own, e.g. UBO# [actual javascript code] #UBO or encode it or something.

Am wondering what the definition of safe as per that policy is. Whatever it doesn't allow should simply not be implemented in the function. By the way, does the Firefox team manually check and approve every single scriptlet?

@uBlock-user
Copy link
Contributor

By the way, does the Firefox team manually check and approve every single scriptlet?

No, their approval system is now automated like Chrome's Web Store's, Firefox doesn't want any extension which can cause code execution via a file which is part of the extension and gets updated remotely via an external server anytime, this is their AMO policy, this only applies to Firefox stable builds, not dev builds, as dev builds are hosted directly on github, so AMO is bypassed if you're using a dev build on Firefox.

@in4u
Copy link
Author

in4u commented Nov 20, 2018

Okay, let's leave it for @gorhill to decide the best course of action. At this point, we don't even know if he's at least open to the idea of implementing such a feature. This issue could very well be stamped with a nice big red decline and trashed away as we speak, haha!

@jspenguin2017
Copy link

jspenguin2017 commented Nov 20, 2018

encapsulate it in some block so that it just becomes harmless text parameter on its own

How do you plan to use the "harmless text"? Wouldn't it just become an expensive no-op machine?

Am wondering what the definition of safe as per that policy is.

Their policy is written in very generic language, honestly no one knows. But executing untrusted code is probably not safe enough.

@in4u
Copy link
Author

in4u commented Nov 20, 2018

You're right. Actually, there's no need to encapsulate or sugarcoat the parameter at all. Parameter on its own is harmless anyway. Like, javascript code can be passed as parameter for any of the existing scriptlets too. How the function deals with it is what matters.

Let's say the policy doesn't allow X, Y and Z. The function can then parse the parameter to check for validity and only proceed if X/Y/Z aren't included or applicable, otherwise just drop the rule.

I don't know the technical nitty-gritty. You guys are the expert. Brainstorm together and figure things out. As they say, where there's a will there's a way. Right now things are probably stuck at the will stage, so the question of finding a way doesn't even arise!

@jspenguin2017
Copy link

jspenguin2017 commented Nov 20, 2018

The function can then parse the parameter to check for validity and only proceed if X/Y/Z aren't included

The resource database effectively limit what code you can execute. More resources will be added as needed.

Securely evaluate a string as JavaScript is not possible without changing browser code. The top engineers from Google couldn't do it, we can't neither.
See: https://blog.angularjs.org/2016/09/angular-16-expression-sandbox-removal.html

@in4u
Copy link
Author

in4u commented Nov 20, 2018

Um, I meant figuring out a way to handle this feature request and not necessarily beat Google engineers. Adguard has their way of implementing this. You guys can probably think of something else. Worst case, go about it their way. Or, don't. Just create scriptlets which solve relevant issues. As long as the issues can be resolved via official filter lists instead of personal hacks, who even cares about javascript?!

@jspenguin2017
Copy link

jspenguin2017 commented Nov 20, 2018

Gorhill doesn't want to bloat the resource database with annoyance filters, and he doesn't want to implement privileged filters just for dealing with annoyance.
See: uBlockOrigin/uAssets#2099 (comment) and uBlockOrigin/uAssets#2099 (comment)

If you just want to write cookies with filters, which should solve the issue you linked in the opening, this and maybe this are what you're looking for.

@gorhill gorhill added the duplicate This issue or pull request already exists label Nov 20, 2018
@gorhill
Copy link
Member

gorhill commented Nov 20, 2018

Duplicate of gorhill/uBlock#3307.

@gorhill gorhill closed this as completed Nov 20, 2018
@uBlock-user uBlock-user removed the enhancement New feature or request label Nov 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

4 participants