[External] : Re: PrivilegedAction et al and JEP411

Peter Firmstone peter.firmstone at zeus.net.au
Thu Jun 22 01:21:17 UTC 2023


On 21/06/2023 8:52 pm, Ron Pressler wrote:
>
>> On 21 Jun 2023, at 01:36, Peter Firmstone<peter.firmstone at zeus.net.au>  wrote:
>>
>>
>> I'm just disappointed that we are being prevented from reimplementing a replacement authorization layer in Java, without any compromise from OpenJDK it's not possible.  We at least need to retain some kind of privilege action mechanism.   That doesn't even have to be a privileged action, maybe it could be an annotation, that we can find using StackWalker.
> Maintaining that information is the very thing that makes the mechanism so expensive. Annotations wouldn’t make it any easier, because their placement would still have to be tested and maintained. No one is preventing you from maintaining that information yourself, and you are free to inject such annotations into the JDK to your heart’s content. If it really isn't too much work then we all win — we don’t have to do it and test it, and you still get to have it.


I wish it was that simple, it's an auditors nightmare.


>
>> If data protected isn't of high value, or is of low complexity, a solution of appropriate cost will be applied, in many cases that isn't SM, however removing SM will reduce security below an acceptable level for a percentage of developers and software projects, the number may be small, but the impact will be widespread, just look at how widely deployed ElasticSearch and OpenSearch are.
> That is clearly untrue because even the most security sensitive applications already prefer alternatives that they find superior. We’re not sending people over to other alternatives; people first abandoned SM in favour of alternatives and *then* we figured it’s time to remove SM when few were left using it. I believe ElasticSearch are now relying on strong encapsulation to maintain their Java-level security invariants.

I would suggest looking into it a little further before dismissing it 
out of hand or making assumptions.

This discussion on OpenSearch is worth a read. 
https://github.com/opensearch-project/OpenSearch/issues/1687

>     My question is still/why/? That's why I asked at davidlago
>     <https://github.com/davidlago>of what actual CVEs JSM mitigated.
>     There's some effort to "move security into core", with that, at rmuir
>     <https://github.com/rmuir>@uschindler
>     <https://github.com/uschindler>what is your argument for not
>     removing JSM?
>
> Because currently I don't see replacements for a lot of the 
> functionality. Meanwhile the protection still works so why discard the 
> only security mechanism that you have? I think I explained above, but 
> to summarize for specific vulnerabilities that are of concern (e.g. 
> have happened before), in a world without a security manager, I think 
> the easiest win is to harden the systemd service, Currently it is very 
> weak and 
> insecure:https://github.com/opensearch-project/OpenSearch/blob/main/distribution/packages/src/common/systemd/opensearch.service
>
> These are some of the historically problematic issues that the 
> security manager prevents... aka the worst-of-the-worst:
>
>   * RCE: there's some protection by seccomp etc via systemcallfilter
>     which disables fork/exec at OS level. So even without security
>     manager, there is at least basic protection from allowing someone
>     to execute coin miner or whatever. This piece has to remain as you
>     can't block fork/exec with systemd seccomp filters... But I'd
>     still recommend to start hardening the systemd service
>     with|SystemCallFilter=|to take it further (the seccomp bpf rules
>     will "nest" just fine).
>   * File/Directory traversal et al: currently the security manager is
>     the only thing restricting the filesystem. opensearch does not
>     need to be able to access files in users home directories or
>     anything like that. If there is a bug in the code that would allow
>     this, instead of accessing users private files, security manager
>     will deliver a SecurityException. but, alternatively, the
>     directories that can be read and written can be nicely restricted
>     with systemd service as well (stuff like|ReadWritePaths=|)
>
> I recommend looking at a secure systemd service as an example, and 
> comparing it to the current one, here is a good 
> one:https://github.com/archlinux/svntogit-community/blob/packages/dnscrypt-proxy/trunk/dnscrypt-proxy.service
>
> You may also use|systemd-analyze security opensearch.service|to track 
> your progress, it will suggest improvements.
>

<SNIP>


>> Lets discuss how it should be used, and what benefits it provides and the situations when you might want to use it.    I only ask that people keep an open mind and for the moment, forget all the horror stories.  I realise this is academic now, and unlikely to change anything, however documenting it here might serve some historical purpose.
> Okay, but we, .NET (the other platform that had a similar mechanism), and most security experts have lost faith in the approach and gained faith in newish OS-level protections that weren’t available when SM was introduced (and also offer protection for native code as well as better protection from some DOS attacks); no new security sensitive platform seems to take that stack-based approach, either. This means that even if we’re wrong on the technical merits, such a feature is so far from the mainstream practice that it has no room in a mainstream language. If some day it becomes mainstream again things may change.
>
> Still, here’s one thing about the technical aspect: “Trusted” does not mean “free of vulnerabilities” but "assumed to not be malicious.” Libraries can and do have vulnerabilities, but I think that strong encapsulation is much more effective in controlling their blast radius, and it has significant non-security-related benefits, too (not that most developers are rushing to apply strong encapsulation to their own code, but at least we’re able to encapsulate the JDK itself). By “effective” I don’t mean “powerful”, but rather “provides more value on average when all aspects are considered”. With strong encapsulation you only need to check that a particular code unit that performs an operation on behalf of a user (authorised at the application operation level) doesn’t do anything problematic. Other units cannot break your unit’s invariants, so only local reasoning is required (true, the size of the unit is not as small as could be afforded by a stack-based approach, but it is still local and contained). If you’re interested in gadget attacks, I suggest you think about how many of them can be prevented by strong encapsulation alone and how many could be prevented by a combination of strong encapsulation and OS-level protections that apply to the entire process (you can throw in serialization filters, too). In other words, don’t think just about what SM could do for you, but also think about what the more popular approaches do for you, too (taking your own advice of considering how they can be best applied, not misapplied) and then consider how much effort should be put to close the *delta* between the two.

I agree with you regarding the benefits of encapsulation.

Prior to serial filters, we reimplemented Java deserialization, we used 
a standardised constructor signature, and we removed the ability to 
serialize graphs with circular references, we placed data limits on 
streams, cumulative limits on array sizes and required a periodical 
reset, we basically applied strong encapsulation with atomic failure and 
input validation to serialization to eliminate gadget attacks.

We've got a mature implementation for managing authentication and 
authorization in a dynamic distributed environment.   It's not a simple 
problem to solve, so the complexity likely comes from the problem 
domain, rather than the solution.   I've been using it many years, and 
over those years, the problems have all been solved one by one, to the 
point where it's a well understood stable solution for our problem domain.

But the reality is, there are no other existing solutions, so we are 
unable to migrate, we need an actual concrete implementation, promising 
future developments are great, but we need a clear migration path, today 
no such alternative technology exists.  As you pointed out .NET has 
removed their equivalent, so we can't migrate to .NET either.   Like all 
problems, someone will come up with a better solution at some point, 
when they do, we'll migrate to that, until then, we have to continue 
using what we have. OpenJDK doesn't know the answer, and they don't want 
the burden of the existing solution, that's fair enough.   We need to be 
honest with our users, we don't have a future migration path with Java 
at this time.

Perhaps it will be solved like concurrency was with functional 
programming, another language will solve it elegantly, hey maybe Java 
will copy the functionality :)

Anyway, we know where we stand now and that's better than thinking we 
had a migration option when we didn't.

- Peter.

>
> Code signing is a completely separate topic; expect some developments in that area.
>
> — Ron
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20230622/a6a0da72/attachment.htm>


More information about the security-dev mailing list