Thanks Erik,
This is the best argument I've heard for removal so far. Note that I
understand it will be removed, I'm not arguing to keep it, we are stuck
with versions of OpenJDK that provide it, as there are no migration
options, I was hoping we might be able to reimplement it, but it's not
possible without some low level language support. If someone does think
of something one day, a way that allows us to implement it, without
great cost to OpenJDK, I would appreciate if you would keep us in mind.
It isn’t. We have nothing to gain from removing a feature whose
benefits outweigh its cost, and removing a feature is itself a rather
costly process. Not to mention the negative social dynamics: the
majority don’t care and don’t know what they gain, while the minority
who use the feature become understandably upset. It’s unpleasant all
around. So if we do it, we’re sure the cost of the feature is high.
If you are able to share, I'd be interested to learn about challenges
you had with SM, if we one day have the opportunity to reimplement it,
the lessons might be valuable, so we can avoid the same mistakes.
To quote Thomas Sowell: "There are no solutions, only trade-off's."
Since we brought up encapsulation and serialization, which has been the
cause of many Java security issues, there is one performance / security
trade-off that I'd like to mention. Serialization filters are lazily
initialized, this is a performance optimisation (a security trade off),
however if a program doesn't utilise serialization and has disabled
serialization using a filter, this provides an opportunity for an
attacker. For the attack to be successful, the attacker needs to change
the serialization filter properties, prior to initialization, if the
attacker is successful, they will be able to disable the only security
mechanism protecting de-serialization against attack.
Serialization filters are an "allow list", Security Policy also uses an
"allow list", it would have been possible to add a simple permission
check during de-serialization, and we could have captured the classes
using tooling, it would have saved a lot of work creating serial
filters, but understandably, the code in OpenJDK, especially the policy
provider performs poorly, so I can see why the decision was made to
implement serialization filters separately, but had it had some
continued love when Java 5 introduced concurrency, and more tooling had
been built up around it, perhaps today it would be simpler to use and
more widely adopted...
The problem with "allow lists", and serialization is, it still lacks
encapsulation, so the vulnerability remains, this is why authentication
is important, who are we allowing? When we boil it all down, we call
it Authentication and Authorization, perhaps there will be something new
that provides this functionality again one day, and maybe the lessons
learned will provide a better trade off. That's why I'd like to
understand the challenges you had with SM. :)
Regards,
Peter.
On 23/06/2023 12:35 am, Erik Gahlin wrote:
> I'd suggest cost of maintenance also appears overestimated
It isn’t. We have nothing to gain from removing a feature whose
benefits outweigh its cost
The cost is very high. I've spent probably a year on the SM just for
jdk.jfr module.
Erik
------------------------------------------------------------------------
*From:* security-dev <security-dev-r...@openjdk.org> on behalf of Ron
Pressler <ron.press...@oracle.com>
*Sent:* Wednesday, June 21, 2023 12:52 PM
*To:* Peter Firmstone <peter.firmst...@zeus.net.au>
*Cc:* c...@anastigmatix.net <c...@anastigmatix.net>;
security-dev@openjdk.org <security-dev@openjdk.org>
*Subject:* Re: [External] : Re: PrivilegedAction et al and JEP411
> On 21 Jun 2023, at 01:36, Peter Firmstone
<peter.firmst...@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.
> 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.
> Arguments against SM, that I've read on this list are based on bad
practises, or the lack of tooling provided with the default
implementation, this indicates a lack of experience in use, I know
that Alan and Sean were involved during the early days with Li Gong,
but I'm pretty sure they don't have much experience deploying it, feel
free to prove me wrong if my assumption is incorrect.
While we disagree — and the “ground state”, i.e. what’s available
without SM is very different today from what it was in 1997 — it isn’t
our job to prove you wrong because even our most security-conscious
users demand something else. If you’re absolutely certain that you
have the answer, then it is you who have to prove us wrong by making
your answer popular.
> I'd suggest cost of maintenance also appears overestimated
It isn’t. We have nothing to gain from removing a feature whose
benefits outweigh its cost, and removing a feature is itself a rather
costly process. Not to mention the negative social dynamics: the
majority don’t care and don’t know what they gain, while the minority
who use the feature become understandably upset. It’s unpleasant all
around. So if we do it, we’re sure the cost of the feature is high.
> , this is partly due to policy, I have offered to assist with
maintenance, however my offer was rejected, as this is considered part
of security, I am not permitted to assist, I could submit patches to
this list, but I'm not sure they'll be welcomed or accepted.
The resources you can contribute aren't nearly sufficient and, like I
said, the problem is that maintaining the doPrivileged information is
not localised but imposes a tax on *everything*.
> however I've assumed that as it's deprecated, there will be little
interest in fixing them, is my assumption incorrect?
Actual bugs will have to be fixed until the mechanism is fully
degraded, but you are generally correct.
>
> 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.
Code signing is a completely separate topic; expect some developments
in that area.
— Ron