river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dan Creswell <dan.cresw...@gmail.com>
Subject Re: Implications for Security Checks - SocketPermission, URL and DNS lookups
Date Sat, 24 Dec 2011 08:14:22 GMT

On 23 December 2011 11:32, Peter Firmstone <jini@zeus.net.au> wrote:
> Hmmm, scratches beard, ok, you're right, up for some brainstorming?
>  1. If I reimplement SocketPermission, what sort of behaviour do we need?
>  2. Or a faster DNS provider? www.xbill.org/dnsjava -
>     *sun.net.spi.nameservice.provider.1=dns,dnsjava*

Well, I'm always going to lean towards fixing the root cause of the
problem which IMHO is DNS and its usage/performance in JDK. Which
means that a faster or at least smarter provider will be where I'd
want to go. JDK's default cache approach is kinda busted in any case.

> A Comparator is good for ensuring the Permission object's are sorted into an
> efficient order before creating a PermissionCollection.  The Comparator
> isn't much good for a cache that contains a previously checked Permission,
> since equals will be executed (I don't currently cache SocketPermission for
> this reason).  Collection.contains(Permission p)?

Collection.contains will surely use equals()?

> With a SecurityManager and our own PolicyFile implementation, it is possible
> to replace / substitute SocketPermission, from both ends, but both the
> policy and SM must be in place or it won't work.  PolicyFile must be

Smells like we're heading towards part of a standard platform. A
security manager and policy generally need to be available to support
downloadable code so I don't see this being an issue?

> instantiated early, or we risk having static ProtectionDomain's that still
> contain java.net.SocketPermission.  ConcurrentPermissions, a replacement for
> Permissions that ProtectionDomain's use to hold static Permissions could
> also be used to convert any stray SocketPermission objects.
> One question I've asked myself when creating my own policy implementation
> was CodeSource.implies(CodeSource cs), the implementation seemed like a bad
> idea, it uses DNS, an attacker could use DNS cache poisoning to gain
> elevated permission using an untrusted CodeSource URL, simply because the
> policy thinks the CodeSource is implied.  I changed PolicyFile to
> specifically not use CodeSource.implies().  In reality a signer Certificate
> is required to identify the CodeSource with any level of trust.

Well, I think a more general point here would be that JDK's default
set of behaviours are designed to "protect" against DNS based attacks
(i.e. a successful lookup result is cached forever and so changes
can't leak in). This is bogus, because if the first lookup is
compromised you're dead and buried.

The correct solution (and more practical these days) is to properly
secure your DNS.

Which brings me to a general statement in respect of DNS security - do
it in that system, don't attempt to compensate in the application. Any
firm that generally cares about security will have done this

> Now a IPv4 address can be converted to an IPv6, so IP addresses could be
> converted to IPv6 format and compared.  Host names could be compared using
> string comparison.  But without DNS an IP address couldn't equal a domain
> name and a domain name couldn't be resolved to imply an IP address.
> The intended purpose of SocketPermission is to check if a user and or code
> is allowed to connect, listen, etc to a network address.  How can we trust
> the DNS to give the right information?

See above, DNS can give you the wrong information because it's
mis-configured, this isn't just a security problem.

> How do we know the DNS has resolved a domain name correctly?

You don't unless it's secured and you're confident spoofing options
are eliminated (which means you'd need to be sure physical network
compromise for example is reasonably addressed).

> The most logical way to identify the remote end, would be via a connection
> that requires it to authenticate.  We have that now with secure JERI.

And secure JERI handshakes are horribly slow (to be fair the
underlying protocols produce that performance envelope).

> SocketPermission only makes a decision whether to allow a connection or not,
> that's it.
> Without DNS, the policy admin would have to enter SocketPermission grants
> for domain names and IP addresses (manual duplication), so it seems DNS is
> there for convenience.

DNS is, and always has been, a convenience - admins back in the day
wanted something that would provide the equivalent of /etc/hosts
across large numbers of machines for low effort.

> Using RemotePolicy for a djinn group, we could have an administrator node,
> resolve all current domain names (and reverse lookup IP addresses) in the
> djinn policy file and update all group member nodes with duplicated
> SocketPermission's for IP address and domain name forms.  Then none of the
> nodes would need to perform DNS resolution.  Again that requires our own
> SocketPermission implementation.

Meh, I can't believe that's more performant than having each box doing
direct DNS resolution for itself....

> Cheers,
> Peter.
> Dan Creswell wrote:
>> IMHO, workarounds like this are asking for trouble. You're assuming
>> certain rational actions (a decent toString) on behalf of some other
>> programmer in the presence of evidence that says they aren't rational
>> - i.e. they have a poor equals and/or a poor hashCode implementation.
>> Combine that with putting the mechanism "under the covers" and I feel
>> that's a nasty piece of dark magic brewing that'll give us problems
>> later.
>> An explicit workaround option is supported in typical collections via
>> a Comparator, yes, that means others have to write some code but it
>> also means the troubles they're facing with equals and hashCode are
>> "in your face".
>> Happy Christmas,
>> Dan.
>> On 23 December 2011 02:06, Peter Firmstone <jini@zeus.net.au> wrote:
>>> There's another way around poorly written equals() and hashCode()
>>> implementations.
>>> In my reference collection utilities, I have strong, weak and soft
>>> references, there are variations on these based on identity or equality.
>>> Well, I've just thought of another that might help out when poor equals
>>> implementations exist:
>>> toString()?
>>> first check both objects have the same class, then compare the results of
>>> toString(), and use toString().hashCode() for hashCode's.
>>> I could call this String equality, when toString isn't overridden it
>>> prints
>>> the reference address so this is compatible with identity based equality
>>> also.
>>> This would fix all those nasty equals implementations for use in
>>> collections
>>> without requiring any work on the developers part.
>>> Cheers,
>>> Peter.
>>> Peter wrote:
>>>> SocketPermissionCollection adds SocketPermission at the head of its
>>>> internal list.  This change was made in jdk 1.2.2_005  bug 4301064
>>>> related
>>>> to reverse dns lookup delays for applets.
>>>> This indicates that the tail of the last policy file parsed, is added
>>>> last
>>>> to the policy and hence at the head of that List.
>>>> It's  also worth noting that the standard policy provider included with
>>>> the jvm is in force until the preferred policy provider is completely
>>>> initiated, after reading all policy files.  So it's likely that the
>>>> standard
>>>> java policy is read last by our policy provider implementation.
>>>> In summary a list of SocketPermissions need to be sorted beginning from
>>>> those that cause long dns delays, to wildcard based permissions, so the
>>>> wildcard perms are added last and hence checked first by any implies
>>>> calls.
>>>> I've got two options on how to solve this:
>>>> 1.  Get rid of PermissionCollection based caches altogether and generate
>>>> PermissionCollection's on demand.
>>>> 2  Replace the PermissionCollection cache with a List<Permission>
>>>> cache, generate Permissioncollection's on demand.  Sort the List after
>>>> creation, before publishing, replace the list on write.
>>>> Option 2 could be implemented in ConcurrentPermissions, a replacement
>>>> for
>>>> java.security.Permissions.
>>>> Option 1 would be implemented by the policy.
>>>> In addition, to allow the security manager to cache the results of
>>>> permission checks for SocketPermission, I can create a wrapper class,
>>>> where
>>>> equals and hashcode are based purely on the string representation.  This
>>>> allows very rapid repeated permission checks.
>>>> Looks like I can get around the SocketPermission, CodeSource and URL
>>>> headaches, relatively unscathed.
>>>> N.B. Anyone care to try out, or seriously performance test the new
>>>> PreferredClassProvider?
>>>> Cheers,
>>>> Peter.
>>>> ----- Original message -----
>>>>> Actually, more significantly for me is that the default localhost
>>>>> SocketPermission is checked before a more lenient SocketPermission. In
>>>>> theory,
>>>>> one should be able to introspect SocketPermission instances and
>>>>> determine
>>>>> that
>>>>> one may be automatically implied by the other so can be skipped,
>>>>> possibly
>>>>> saving
>>>>> a lookup. Chris
>>>>> Peter Firmstone wrote:
>>>>>> A big problem with the current implementation is SocketPermission
>>>>>> blocks
>>>>>> other permission checks from proceeding.

View raw message