On 24 December 2011 11:04, Peter Firmstone <j...@zeus.net.au> wrote:
> Dan Creswell wrote:
>>
>> So...
>>
>> On 23 December 2011 11:32, Peter Firmstone <j...@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 faster provider will help, and we can bundle dnsjava if we want,
> unfortunately though DNS lookup is oversubscribed in Sun's jdk, so we need
> to eliminate the sources of overuse also.

I don't think that holds necessarily if DNS lookup is good enough.

>
> I was able to successfully replace URL with URI in PreferredClassProvider
> and in CodeSource.implies(CodeSource cs) with URLGrant.implies(URI grant,
> URI implied), this avoids DNS lookup completely.
>
> With regard to a SocketPermissionCollection, if you have a number of domain
> name granted SocketPermission's, that aren't wildcards, each one will cause
> an unnecessary DNS lookup, until a suitable match is found.  Even domain
> names that are obviously different are resolved, in case they share an
> identical ip address.  Even identical domain addresses are resolved, to see
> if their IP addresses match.  If one has a IP address and the other a domain
> name, SocketPermission.implies will perform a dns lookup to get the missing
> IP address and then a  reverse dns lookup to obtain the other domain name,
> if the IP addresses don't match.
>
> A reimplementation of SocketPermission would allow the
> SocketPermissionCollection to take responsibility for DNS lookup after it
> checks every SocketPermission for a direct match without DNS: wildcards, IP
> address etc.  Make the domain name implies a separate check that's performed
> after all wildcards and IP addresses.
>
>
>
>>> 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()?
>>
>
>
> In externally sorted Collections, yes, but not in TreeSet, so that's an
> option, thanks ;)  Pays to read the docs properly.
>
>
>>
>>>
>>> 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?
>>
>
>
> Yep, got that smell about it.
>
>>
>>>
>>> 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
>> already....
>>
>
>
> Then there's the internet, where DNS can't be trusted.  The current root key
> certificate system in DNS-SEC could also be compromised at some point in the
> future.  Certificate authorities are proving that they can't be trusted.
>

Then you run your own DNS, and detach it from external factors....

> The only system that appears to be resistant is OpenPGP's model, a web of
> trust, with certificate revocation.
>
>
>>
>>>
>>> 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).
>>
>
>
> Hmm, sounds like a future opportunity, I wonder if elliptical curve
> cryptography could help.
>
>
>>
>>>
>>> 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....
>>
>
>
> If you only need to update your RemotePolicy occasionally and you can
> resolve all addresses off line prior to performing a policy update, then DNS
> isn't required in the middle of a SecurityCheck in progress...

That's just a hosts file and DNS disabled....

And you'd rsync it around or similar.

You'd of course be messed around by JDK's default caching policy but...

>
> Background pre-processed, rather than on demand, so to speak.
>
> RemotePolicy doesn't make policy decisions, it's a method of transferring
> Policy Permission grant's.  So while a policy update is in progress,
> security checks may continue unheeded, the switch is made at the last
> moment, once all information has been transferred and cached locally.
>  Perhaps I should rename it?  DjinnGroupPolicy?  You limit the Permission's
> the Djinn Group administrator can grant using GrantPermission.  Although
> there is a one is to one relationship between RemotePolicy and Group.
> RemotePolicy isn't completely implemented.
>
> If DNS is reduced to the absolute minimum, perhaps it could be preprocessed
> locally too.  Once we start performing security checks, we need to be
> decisive.

Still a hosts file....

>
> I'd welcome a helping hand ;)
>
> Merry Christmas & Cheers,
>
> Peter.
>
>>
>>>
>>> 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 <j...@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>
>>>>>> based
>>>>>> 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.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>>
>
>

Reply via email to