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 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.

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...

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.

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