Security
Nicolai Parlog
nipa at codefx.org
Thu Oct 22 06:18:30 UTC 2015
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hi!
> Adding a "traditional" access level - even the simple approach of
> "weakening" package-private to module-private (even if just for
> Java 9+ module classes) - seems much safer to me because it's just
> another point in a well-understood linear spectrum of behavior
>
> [...]
>
> I think the principle of "Public is public" is important to
> maintain.
This is my theory regarding package-private vs public:
Developers who pick the first make a conscious decision about where
their code is going to be visible. They _want_ it to be limited to the
package. Public can mean different things:
* whatever, this is the default in my IDE
* truly public, i.e. planned to be visible to everybody
* damn, there is no "only in my JAR" and package-private doesn't cut it
So changing package-private would nullify a conscious decision. Not
good! Additionally, changing the meaning depending on whether the code
is inside a module or not (which is not even known at "write-time")
would make this much more complicated.
The first two meanings of public can be ignored for this discussion.
Instances of the third can be moved into new packages, which are then
not exported. Sounds like a good migration path to me.
Of course getting a new modifier "module" would be awesome but I guess
this is out of the question at this point.
so long ... Nicolai
On 21.10.2015 13:38, David M. Lloyd wrote:
> On 10/05/2015 01:45 PM, mark.reinhold at oracle.com wrote:
>> 2015/9/17 8:34 -0700, david.lloyd at redhat.com:
>>> On 09/17/2015 09:56 AM, mark.reinhold at oracle.com wrote:
>>>> 2015/9/11 10:15 -0700, forax at univ-mlv.fr:
>>>>> While this change may improve the security, it's a backward
>>>>> incompatible change is not strictly required to support
>>>>> modules it's more an enhancement of the current security
>>>>> model and i don't think it's a good idea to mix it with the
>>>>> introduction of the module support.
>>>>
>>>> This is not an enhancement of the security model per se
>>>> (which would, anyway, be beyond the scope of this JSR). This
>>>> change is, rather, in service of the strong-encapsulation
>>>> goal (which does, of course, help ensure security).
>>>
>>> I think this assertion should be substantiated with some
>>> examples.
>>>
>>> While strong encapsulation is good in terms of design
>>> principles, to me it's only evident that this somehow leads to
>>> better security in the most hand-wavy possible way (in
>>> particular, as it relates to this specific mechanism).
>>
>> Three of the five zero-day vulnerabilities reported since JDK 7
>> GA would have been prevented if we'd had the ability to strongly
>> encapsulate JDK-internal packages in the manner proposed, via
>> access-control checks enforced by the VM.
>>
>> Here are public analyses of two of them:
>>
>>
>> https://partners.immunityinc.com/idocs/Java%20MBeanInstantiator.findC
lass%200day%20Analysis.pdf
>>
>>
>>
>> http://immunityproducts.blogspot.com/2012/08/java-0day-analysis-cve-2
012-4681.html
>>
>>
>>
>>
The lead of Oracle's Java Vulnerability Team estimates that at least a
>> third of all the vulnerabilities reported since JDK 7 GA would
>> have been prevented if we'd had the ability to strongly
>> encapsulate JDK-internal packages.
>
> Fair enough, though I do want to point out that examining these
> two analyses doesn't lead me to believe that this would be the only
> (or best) way to prevent these exploits, which seem to be rooted in
> coding errors in other parts of the JDK.
>
>>> On the other hand, there is strong evidence to support the
>>> assertion that enhancing the security model in any way
>>> immediately leads to new CVEs. The more behavioral rules there
>>> are in place, the more vectors for exploitation will appear.
>>
>> In the abstract, I agree with you. The proposed means of
>> encapsulation, however, does not depend upon the existing complex
>> security architecture, so it should be easier to validate.
>
> The reason it concerns me is that the Java language access
> modifiers and this new access check solve the same problem in
> different ways, leading to a sort of NxM growth of possibilities
> for access checking behavior. Apart from the theoretical danger of
> the more complex rules, I don't know that the average developer
> will understand why the (now) two language-level access checks are
> separated rather than combined.
>
> Adding a "traditional" access level - even the simple approach of
> "weakening" package-private to module-private (even if just for
> Java 9+ module classes) - seems much safer to me because it's just
> another point in a well-understood linear spectrum of behavior, and
> thus I think can be shown to introduce little or no substantial
> negative impact on the security of existing code, while at the same
> time definitely improving the security of any code which
> deescalates the accessibility of otherwise public members. The
> simplicity of the model ensures that it will be well-understood by
> both existing and new developers, and also directly implies a lower
> risk in at least a couple of categories (security and compatibility
> spring to mind).
>
> I think the principle of "Public is public" is important to
> maintain.
>
>>> ...
>>>
>>>> To truly support strong encapsulation would require taking
>>>> setAccessible away completely. I think that's desirable in
>>>> the (very) long term, but it would break too much existing
>>>> code in the near term.
>>>
>>> I don't agree that this is true. Encapsulation is really a
>>> social construct; while accessibility can be used to create and
>>> enforce encapsulation-justified rules, it doesn't *have* to.
>>> You do need some kind of back door, no matter what, or else you
>>> severely limit the power and capability of the platform (as
>>> evidenced by the widespread usage of the reflection back door
>>> by many widely-used frameworks generally considered to be
>>> powerful and capable).
>>>
>>> If encapsulation as a design principle is the goal, then
>>> simple isolation rules between modules (as between unrelated
>>> class loaders) has already been proven to be highly effective.
>>
>> If all you mean by "encapsulation" is a social construct then
>> sure, none of this would be necessary. That's insufficient,
>> however, in the face of actual security threats. Aside from
>> security considerations, a social contract implies a level of
>> understanding and trust that is difficult, if not impossible, to
>> achieve in a broad community of millions of developers.
>
> I understand that, but consider: of those millions of developers,
> I think it is very safe to say that the majority of them know what
> "private" versus "public" means.
>
>>> In this light, I don't see how these changes cannot be
>>> considered a modification of the security model just because
>>> they ride in on the coattails of a new abstraction.
>>
>> It depends upon what you mean by "security model".
>>
>> If you mean some high-level, abstract view of all the various
>> mechanisms in the language, VM, and libraries that help ensure
>> security then yes, the proposed changes are an extension of that
>> model.
>>
>> When I write "security model", however, I usually mean the
>> subsystem which evolved from the simple (and simplistic)
>> java.lang.SecurityManager API in Java 1.0 to the complex
>> policy/permission-based architecture of the 1.2 release. Many
>> run-time operations (in class loaders, reflection, I/O, etc.) are
>> subject to checks done by the security subsystem, and if just one
>> of those checks is missing or incorrect then it may well be "game
>> over".
>
> What I'm thinking of here is the compiler/VM security model, which
> (in terms of specification at least) I believe is presently limited
> to access level checking on classes and members.
>
>> The proposed enforcement of module boundaries via access
>> restrictions expressed in the language, recorded in class files,
>> and enforced by the compiler and the VM do not in any way depend
>> upon that subsystem, nor do they extend it. The VM will never
>> upcall into the security subsystem in order to determine whether
>> one type is permitted to access another. The implementation of
>> access-control checks in a JVM is typically highly localized and
>> much easier to validate than the comparatively large body of code
>> in the (mostly) Java-level security subsystem.
>
> I do agree that enforcing module boundaries via access restrictions
> in the language and class files should be enforced by the compiler
> and VM. I'm just hoping we can arrive at something that doesn't
> create a new sort of Java puzzler: "when is a public class not
> public?".
>
>>>> ... If encapsulation is to mean anything then it should not
>>>> be possible to break it solely from within the language
>>>> itself. Enabling such powers via an external, second-class
>>>> mechanism such as a command-line option or a debugger is
>>>> fine, but the history of Java has shown that if it's easy to
>>>> break encapsulation then people will do so, increasing
>>>> everyone's maintenance burdens over the long haul.
>>>
>>> I think this may be a somewhat narrow view. People break
>>> encapsulation when they need a capability that cannot be
>>> provided another way. Now the JDK, unfortunately, historically
>>> contains very many "goodies" and bits of useful functionality
>>> that users want access to, so it is a disproportionately
>>> popular target for such breakage, but apart from accessing JDK
>>> internals, I believe that the use cases for breaking in through
>>> the security model are legitimate and should be allowed to
>>> adequately privileged code.
>>
>> How do you identify "adequately privileged code"? (This is an
>> open issue we need to address.)
>
> Good question... today, my understanding is that such code is (a)
> any code running in a JVM with no security manager, or (b) any
> class which has a protection domain which is somehow granted the
> "suppressAccessChecks" RuntimePermission. But I see your point,
> and I think it is reasonable to want to strengthen this somehow.
>
> Specifically I don't like having public classes that aren't
> actually public - this adds another layer of complexity which I
> don't think is necessary. Ideally a public class is *always*
> public. A module with a public class in a non-exported package is
> (intuitively speaking) not saying "this class is not really
> public", it's saying "this class is public, but not to link
> against".
>
> If the goal is to eliminate the need for this back door, then the
> "front door" must suffice for all use cases. This means that
> frameworks that access modules must be able to do so in a way that
> is allowable by module authors. If public classes are always
> public, even when they're hidden, our various EE specs can be
> changed to say "your EJB implementation (or whatever) must be
> public, but it MAY be in a non-exported package". This allows
> anyone who can get access to the Class object free access to its
> public members *without* a special permission, which actually goes
> a long way towards getting rid of the desire for a backdoor in the
> first place. Such classes could be available by name, service
> loading, or annotation lookup, but not via direct linkage, which is
> a nice and logical way of saying "you can access this public class
> indirectly, but it is definitely NOT API".
>
>>> Using an appropriate security model, it is not difficult to
>>> ensure that such powers are not exploited (though while in
>>> practice it is more difficult due to a variety of factors, I do
>>> not believe those factors are directly related to this
>>> mechanism but rather to exceptions, special "holes", and other
>>> technical debt that exists in the JDK itself for historical or
>>> other reasons).
>>
>> I don't think that the future of the platform would be
>> well-served by a model that works well only for code outside of
>> the JDK, if that's what you mean.
>
> Sure, but the reverse is also true. Clearly a solution needs to
> accommodate both, though at the same time it is generally not good
> to bake in rules that only exist to accommodate JDK implementation
> choices, I'm sure you'd agree. At most, you'd want to leave
> certain things unspecified to allow the JDK flexibility, but even
> that might go too far in many cases.
>
- --
PGP Key:
http://keys.gnupg.net/pks/lookup?op=vindex&search=0xCA3BAD2E9CCCD509
Web:
http://codefx.org
a blog about software development
http://do-foss.de
Free and Open Source Software for the City of Dortmund
Twitter:
https://twitter.com/nipafx
Diaspora:
nipa at pod.geraspora.de
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQIcBAEBCAAGBQJWKH+2AAoJEMo7rS6czNUJ6rgQAKYJZRPpWgX92Jb2Xh/CGJZa
tqzAQhQv+wRFDF9ibx4mKcpnLGVCGpVEFRcOW+MBOlbG+1TFWuaf/D1As9fr8xh4
W8oCEnGf4Le7kXHR7Ard2KcIO0/A7GNTC5UNRNMf1hJwOt0QEfiXi9gLIwfMfLBd
9LXme+aus/AaazztAGjEZ13n+oyHNAChiZdoPC4VKgUdGe6ZMWbM0EDXIxMV/OvA
s5C7ULBzEP78OTUhzM5f6wxdgsMBJcUPEYA/grpwfTiNxMSAj6ugMLM9ZZ27Fm1N
s9LdIRE1tin/4X4Xk62XIb1b6MwAaQF3YSChUNbZ7U4zK4+7SlMaLUKSkkMbjkcJ
WGjPS0rrGS4oraG43DjWPa4xjQzX+sXoIzr19OjR15nwdZgTnKANisvftNgttNlk
HTS0oPjzrC80WFeAEJH6dTWpTke2J9LhfA23+BwVcZswn3e/hIprm3u6g22FXbwt
rY/7lmBaTL70nBkhpqwFU8KfDTKGaNAzh3St2x85peo1uI9mEo4dp8r6SFdjI5fU
9JooeeWb9AaQd+SouYa0I63gsEzs+auMgCizkiB1po6/9b1atEq7WYQZ6/LWczU3
HIKxtaJUiB4rCaiq7Gup1qcsNfQsw14JKX1lBdyZJwIplMBFQ+sXTcZTDpS6f8Nk
3803l7gd1wTOynMlxmmv
=welN
-----END PGP SIGNATURE-----
More information about the jpms-spec-observers
mailing list