-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Evaluate the permission change for jackson-databind #5504
Comments
@davidlago, any thoughts? |
cc: @peternied |
From https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/ReflectPermission.html These permissions govern allow for the finding, altering, and executing private, protected, ... etc methods. By allowing these permissions it will be possible for the code in server to bypass access protections. Many serialization libraries rely on this reflection so its usage is not surprising. Having these permissions creates exposure of the code under server/... via tampering. I'd recommend we remove these permissions since server/... does things like establishing TLS, access control systems, or other security features. The databind library is used for OpenSearch/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java Lines 537 to 541 in 57d4485
|
@rmuir @uschindler, since we were just talking about JSM, maybe you have a moment to pitch in your 0.02c here |
You can apply the policy only to a specific jar file, but then you need to make sure that the code there uses AccessController.doPrivilegedvl around the reflection code. If not you would need to somehow otherwise sandbox it, by delegating all calls to that library sandbox through a proxy that sets the caller domain. |
We had a test in Lucene doing something like this, but this was actually to limit the permissions to run some code without any permission. I have to look it up. |
As far as the specific permissions, the risk IMO here really involves protection against untrusted code. The vectors for the untrusted code could be things such as scripting features, java serialization, etc. Historically (pre-java 9), if code could just call Probably a few things have changed since java 8.x times where we did a lot of cleanup around these permissions:
|
A couple thoughts when thinking about untrusted code wrt these permissions:
|
@rmuir @uschindler For this specific issue, what do you recommend we change in code, if anything? |
The problem here is that you have added the 2 permissions globally to the As said before there are 2 variants to overcome this:
Uwe |
Hi, I added the jackson-databind as a separate policy, but for the reason before I wasn't able to pass The "correct" way to fix this would be this draft PR: #5767 My recommendation: Avoid Jackson Databind, sorry! Alternative ways to fix this: Enclose any calls to jackson-databind into a wrapper JAR file that guards everything with Another alternative is to add a plugin like "jackson-databind-plugin" that is loaded in its own classloader like all plugins and that puts jackson ito a sandbox. But I am not sure if this is worth the trouble, my suggestion: kill broken jackson-databind. It is curretly only used in Elasticsearch plugin for special cases but it hsould NOT be added to core. |
FYI, I have no time to work on this, I just wanted to give you some options. The PR also shows the problem of this relaxing of policy that shortly after adding the additional highly debatable permission to Elasticsearch server's bootstrap policy the first one added a broken test: WriteableSettingTests.java This test adds SuppressForbidden and then calls setAccessible(). After I have seen that I got disappointed and gave up here. You opened the can of worns by this and now you are also ignoring forbiddenapis that complained already! |
Another option would be to revert the move of jackson to "server" (I would really recommend this) and instead make the ExtensionManager a plugin in its own codebase with a sandbox. This also allows to better control what it is doing. So I'd suggest to revert #5366. P.S.: There was a reason why the original code used jackson-databind only in plugin sandboxes and not globally! The current code has now also only one classloader with a single Jackson instance, so when something goes wrong and somebody deserializes a bad class with jackson the hell is open! RCE,.... like with Java serialization! |
if I will try not to mention how much work it took to remove this stuff from the core before, i hope there is a really good reason for adding the setAccessible stuff back :( |
As it looks like ExtensionsManager is the only one using that shitty jackson-databind, why not write your own hand-written (de)serializer for this single class |
Haha!
+1 |
I removed both permissions from the policy as part of #5768 |
Cool. Plain yaml is much better here. |
Ideally, we would like to keep jackson in the server module without using it to centralize versions for plugins. On the PR right now, a few native plugins are failing due to lack of access checks, even though their security policies grant the correct permissions. Is there a way to keep jackson in server and have the native plugins get the permissions from their own policies? |
i don't think its good to keep this library in core: nuke it with a passion. and any plugins depending on it, fix them too. setAccessible is bad news... the code uwe linked to is... (there are no adjectives in any language to properly communicate). it is not just about security permissions, again java 9+ modules will barf on this stuff too. move away from it... run, don't walk. |
Since Java 9, all serialization libs need to be revised at some point. whenever you serialize stuff in private fields, the correct way to do this is now by using a correct lookup instantiated using MethodHandles.lookup() by the class to serialize itself and that passed to the serializer to use it to access private stuff with same privileges like the caller (method handles instead of reflection). The problem is that all those libs like this libcowboy ähm jackson-databind are very old and should be rewritten for modern java, but the apis would dramatically change. So only way is to avoid them, because module system breaks with them due to encapsulation. |
@uschindler Thank you so much for insisting on this important issue, really appreciate your time. @ryanbogan since @uschindler said he isn't taking this to its logical conclusion whichever one it is, could you please followup on ^ and do the rightful? |
Now that Jackson has been removed from the server module, I'm attempting to find a solution that can mirror the functionality that jackson-databind provides. The other prominent JSON libraries are GSON and jsonsimple, but GSON also uses the reflective permissions and jsonsimple does not have the capability to match all of jackson's functionality. What is the best alternative to jackson? |
Thanks! I'll do some more research into GSON and see if I can get it to work |
@dblock @uschindler @rmuir As a quick update on our progress for this issue, I have replaced all instances of jackson-databind in the SQL plugin as a proof of concept. The new solution utilizes GSON with a reflective access filter. All unit tests are passing locally, but we are still looking into integration test failures. The draft PR here (opensearch-project/sql#1411) contains my implementation, and any feedback would be appreciated. We are currently planning to pause work on this issue for a month until April, at which point I will pick it up again. Are there any concerns with this course of action? |
Seems like a reasonable approach @ryanbogan. Hope you get to pick this up soon again, or maybe someone else can finish it up before you get back to it. |
Thanks @dblock . We are pausing this work for now and will pick it up in April, 2023. @ryanbogan will work on this in April. Thanks |
Hey @ryanbogan @dblock was there ever any final recommendation coming out of this issue? We're building a new plugin and trying to decide how to parse JSON. Any advice (here or on opensearch-project/flow-framework#46)? |
Coming from #5366 (comment) in order for jackson-databind to be used in the
server
folder, the SHAs, licenses, and notices had to be removed from all plugins and modules. They still have access to jackson through server, but the discovery-ec2 plugin also had theaccessDeclaredMembers
andsuppressAccessChecks
permissions in thebuild.gradle
. For the plugin to function properly with the jackson relocation, these permissions were added to the serverbuild.gradle
. We need to evaluate whether there are any unintended consequences of adding these permissions.Link to jackson relocation PR: #5366
The text was updated successfully, but these errors were encountered: