Gonna go inline... On 28 June 2012 13:32, Peter Firmstone <[email protected]> wrote:
> What follows is relatively hard core security, but it's relevant to anyone > wishing to deploy on untrusted networks. I know some people don't like > discussing security issues for fear of turning off would be developers but > security isn't mandatory, however considering that River/Jini is already > making extremely difficult tasks possible, I think it appropriate to > continue focusing on solving difficult issues, especially considering > recent online coverage and increasing awareness of java security issues. > In the long run this will make life easier for developers. > Will it make their lives easier? Is it the way that lives will be made easier? I'm not sure because the typical behaviour of organisations is to secure the hardware to the point where the software layer is just left as is. The alternative is they do just enough software security at low granularity to make it work with reasonable risk. In such an environment you'll see plenty of firewalling, permissions per process etc. If we want to provide a "new easy" we'll need at least: (1) Something that is that much easier. (2) Something that provides compelling advantages alongside (1). > > Java 2 security infrastructure was originally designed around codebase > trust, but it's also extensible and customisable, JAAS was designed around > the premise of user security concerns, previously lacking from Java 2, code > was assumed to be trusted in most cases, although it's also still possible > to restrict permission to a combination of principals and codesources or > certificates, but in practise, permission is generally granted to > principals. JAAS uses the SubjectDomainCombiner to inject principals into > every protection domain on the call stack (well it replaces them actually, > but that's an implementation detail). > > To ensure that only trusted code is used by authorised principals, policy > file permission grants must be made that includes both the signer of the > code and the principal authorised. Failure to include the code signer in > the permission grant may allow untrusted code to gain elevated permissions > on the call stack by being executed by an authorised principal. > > In a distributed environment it is difficult if not impossible to know in > advance which code signers and principal grant combinations are required, > these interactions and introductions may occur dynamically at runtime. > For this reason, too much permission is often granted, in order to allow > the software to function intuitively or as anticipated by users, leaving > security holes for opportunistic attackers. > > Mmm, I don't feel it's impossible at all to know in advance. Services would need to expose information regarding their dependencies and the permissions they require to run. One you know what 1st order services a service needs, one can construct a tree of dependencies and permissions. I'd also suggest that too much permission is granted because the current Java security infrastructure inevitably works on a highly granular level with long lists of detailed security options for this or that. That brings a lot of overhead and complexity. Unix filesystems essentially reduce the problem to user, group, other that classification whilst sometimes unwieldy also makes for a level of sanity in terms of the number of permissions that need playing with or expressing. It seems to me that we should be looking at similar tactics for grouping/abstracting that take out the need to hit a long list of very granular permissions. A user is bound to a single thread and all child threads inherit its > context. Executors and Thread pools may execute tasks on behalf of users > however user AccessControlContext must be copied from submitting threads. > > SubjectDomainCombiner is extendable, it isn't final, JAAS behaviour can be > subtly modified without having to reinvent the wheel. > > So what changes need to be made to SubjectDomainCombiner functionality to > allow the mixing of Principal grants with codebase or codesigner grants in > the presence of untrusted code without compromising security? > If we're serious about security, why would we allow presence of untrusted code? It's flexible, and in some ways easier but it also introduces a level of complexity to implement. Sometimes the right choice is to enforce consistency so that complexity is manageable and reliable implementation is possible. Simplistically, if an organisation wishes to use some code that is currently untrusted it should surely pick a version, audit it and sign it in absence of anyone else signing it? That then provides the level of consistency we're talking about. This of course can be said to run back to my original point about the tradeoff between easy security and enough security. How much are organisations willing to change to do security "properly" and what is "proper" for them. Usually it is neither definitively "proper" or "properly". I've given the implementation stuff below a cursory review, I see no immediate issues but with security, that doesn't mean much :) In any case I'll leave a deep review for now as I'm much more interested in talking about the security tradeoff and how we might want to tackle it. Yes, I'm questioning assumptions again and that gives me an excuse for a bit of movie cheese (if you don't like swearing, don't click this link): http://www.youtube.com/watch?v=wg4trPZFUwc > Instead of injecting Subject principals into every ProtectionDomain on the > stack, add a new ProtectionDomain, containing the Subject's Principals to > the existing stack. In the presence of untrusted code, priviledge is > reduced to the intersection of commonly held Permissions, instead of being > elevated to those of the principal. ProtectionDomain would also need to be > subclassed, eg SubjectProtectionDomain, so the SubjectDomainCombiner could > identify and replace the SubjectProtectionDomain when running as another > more privileged Subject in a privileged context (equivalent to that > effected by Subject.doAs). This also requires that other > ProtectionDomain's without Principals will require all necessary > permissions granted in policy statements. > > Unfortunately it is much simpler to make all the necessary grants only to > Principals and associate them with Subjects upon login. It takes > considerably more effort to determine all the code sources that require > these permissions, a deployment simulation tool could greatly simplify > determining permission requirements during deployment, so it doesn't become > an impediment to adoption, but has rather the opposite affect. > > According to current policy behaviour, a ProtectionDomain with a null > CodeSource would not be granted any Permission, ever! A ProtectionDomain > containing a CodeSource with null URL can however be granted Permission, > provided no codesource is specified in relevant policy file grant > statements. A Principal only ProtectionDomain would need to have a > CodeSource with null URL, to avoid any unexpected behaviour when combined > in the stack. > > JAAS was designed so permissions are not granted until after a user has > authenticated so trusted code cannot perform privileged tasks such as > connecting to a network until after a user is logged in, however a system > where trusted code is granted permission it already has sufficient > permission. Authentication in this case would inject a ProtectionDomain on > the stack that reduces privileges. Log-in represents a lessening of > permission. This will work if the only way for the user to access the > functionality the code provides is by logging in. > > The question is, which is easier to control, untrusted code that may be > able to gain privilege by running on a user thread (a trojan) or trusted > code logging in users? The former is indeterminate in an environment > where untrusted or semi trusted third party code exists. > > The beauty of SPKI/SDSI is it can be used as glue between separate domains > of authority, allowing each to use disparate systems and be responsible for > delegating authority granted by external entities within their own domain. > > In SPKI/SDSI, a subject is represented by a public key, a user can have > associated authorisation certificates, these certificates can be delegated > to authorise a user to perform tasks in another administration domain > belonging to another company. Using the DynamicPolicyProvider and > PermissionGrant interface, an authority certificate having an expiry date, > could be verified and dynamically granted. > > SPKI/SDSI allows the security framework to determine authorisation, > without concerning itself with authentication, simply by the association of > authority certificates with a public key (Subject), authority certificates > only have value to the Subject that originally granted them (typically an > admin), so the authority that granted these certificates will be the > administrator of the domain where the certificates are presented as > evidence of authorisation by some remote client. Since there may be a > combination of different codebase signers in use at the same time, it isn't > practical to combine this grant with a signer, the code has to be assumed > trusted, however the reality is that not all code is trusted. Instead a > jar file could contain an address where authorisation certificates can be > retrieved. > > The new security manager lends itself to the creation of a runtime > security tool that can create policy files based on least privilege > principles under controlled conditions simulating the deployment > environment. The policy file produced will need some editing for > portability, since all environment variables are expanded, it will be > useful to enable developers to determine security policy requirements for > each ProtectionDomain and User role. > > Adopting least privilege principles for tasks eliminates unidentified and > existing security bugs, such as deserialisation attacks, similar to > CVE-2010-0094 RMIConnectionImpl and CVE-2008-5353 ZoneInfo object > deserialization demonstrated by deserializing Calendar objects. This > happens because ClassLoader.defineClass needs to load the class file before > it can define the ProtectionDomain so the deserialising class's > ProtectionDomain is not on the stack, readObject() is called with > reflection, it isn't part of an inheritance hierarchy. Sun's bug fix > limited the permissions to those that were required by the Calendar class. > DownloadPermission cannot prevent this BTW because readObject() is executed > in a privileged context, a custom ClassLoader can be created bypassing > PreferredClassLoader. > > Least privilege limits permissions to those required to perform intended > tasks, even so called trusted jvm library code can have limited privileges. > If you need to deseralize Calendar objects, don't grant any unnecessary > privileges, this fixes bugs without changing code. Least privileged > principles limit privileged code blocks ability to do anything other than > what's absolutely necessary. > > Even though the java 2 security architecture was designed to support least > privilege, it is seldom implemented that way in practise, increasing the > opportunity for crackers to find exploits. > > Although none of this will make it into the upcoming release, it may make > the following and I'd like to finish security prior to implementing UDT > sockets to enable internet based services and DNS SRV based discovery and > codebases. > > Peter.
