[cap-talk] Java coding rules for capability discipline
david.nospam.hopwood at blueyonder.co.uk
Wed Nov 3 21:11:20 EST 2004
Ian Grigg wrote:
> Mark wrote:
>>Okay, I will indulge you with a simple set of rules that don't really
>>enforce capability discipline, but which at least get you into the
>>target area [...]
>>-- No static mutables (no class variables)
> How do you then guaruntee that there is only one
> user of a single-access resource? For example, a
> manager of something like a database resource would
> often use a static variable to enforce its one-ness.
I answered this in another post.
>>-- No in-line imports: all imports must be explicitly listed at the top
>>of the file for easy review. If you import java.io.File into many
>>classes, expect your security review team to hand you your head after
>>playing basketball with it for a while.
> We've recently gone away from this, not quite as
> you describe, but more over to import thing.*;
> rather than importing explicit classes, one by
> one. The reason is simply the cost of maintaining
> all these lists.
Here's another reason, besides making security reviews more difficult,
why *-imports are broken in Java (and all other languages I know of with
a similar facility). Suppose that a file uses
and mentions class "Baz" which is intended to be "bar.Baz". Someone
now adds a class foo.Baz. The program breaks when recompiled. Fortunately,
it breaks by reporting an unambiguous import rather than silently choosing
foo.Baz (tested with javac 1.5.0, although the language spec is not clear
on this point). Nevertheless, it is still annoying that what should be a
compatible change breaks recompilation for no good reason. This is why I
avoid *-imports in released Java code (unfortunately the auto-import of
java.lang.* cannot be avoided).
OTOH, suppose that a *-import did not automatically import classes,
but instead acted as a hint: when an identifier is unrecognized and
exists in a *-imported package, the IDE should prompt to add an explicit
import. That would avoid most of the cost of maintaining the import
lists, and also eliminate both the forward compatibility and the security
>>-- Never pass a description (especially a string description) of what
>>should be used: rather, send a reference to what should be used
>>-- Don't pass a larger authority when a smaller authority will do
>>(facetize early and often; in Java, learn how to use anonymous inner
>>-- Do not trick a smaller authority into giving you a larger authority:
>>for example, do not cast down a ReadStream into a FileReadStream that
>>you then use GetFile on so you can do a getParent to get the directory
>>(is this rule too hard to understand to follow? One of the issues with
> So, would you say that a caps language should not have
> a cast feature? Or, one should only be able to cast
> more narrowly, not more expansively?
The problem in the above example is that the API does not follow POLA,
not the ability to cast. (The getFile and getParent methods should not
exist.) Avoiding authority-expanding casts is one way to compensate for
an API that does not follow capability discipline. IMHO, given properly
designed POLA-following libraries, casts (or dynamic typing, which avoids
the need for casts) do not present any particular problem.
>>-- Use immutable objects whenever possible. In Java, use ConstLists and
>>ConstMaps from ELib instead of hashtables and arrays when possible. If
>>not in Java, create a ConstList data type and a ConstMap data type, and
>>-- Always mark everything "final", then remove the "final" mark if it
>>turns out you really do need to modify it.
>>-- Avoid normal integers. Use floating point or BigInteger if possible.
>>For classes that are identified as security-critical, normal integers
>>are not allowed, period.
> Wow, that's a big one. In practice, in financial
> cryptography, we tend to ban floating point.
I ban floating point in most of my embedded programs as well. The
point is not that fp should be used, but that fixed-precision integer
arithmetic should not, because it fails silently in ways that can
often cause security failures.
> I can't see what one gains by going to BigInteger
> except a potential avoidance in overflow, but in
> practice, I would have thought the confusion of
> working with BigIntegers made it less likely to
> deal with bugs of other natures, and therefore a
> false economy.
Cap-secure languages need optimized bignum arithmetic that is as easy
to use as Java 'int'. This is an example of a case where just subsetting
Java doesn't cut it. AFAICS Java 1.5 doesn't help because it only
boxes/unboxes between int and Integer, not BigInteger.
>>-- In Java, communicate via Elib, not via sockets or RMI.
> I agree in not using RMI because it is hard to
> tie down what gets sent and whether it gets there.
> But with sockets, they are relatively well defined,
> if clumsy in some lights. At least the relate in
> defined ways to the OS underlying so they are close
> to the metal.
> So I don't see the objection yet.
No, I don't see the objection to sockets either. Obviously if you
need to send authorities or complex objects then you should use an
Elib (or whatever) stream, but if you only need to send byte-oriented
data, what's the problem with sockets? (Concurrency model differences
between the E and Java APIs aside.)
>>-- In Java, to look at the javadoc for the API, look at the javadoc at
>>erights, not the javadoc at javasoft. This way you'll be lured into
>>using the API in a capability style.
> Hmmm ok. This is http://www.erights.org/javadoc/
> I presume. Looking at that, it seems more oriented
> to the E programmer than the Java programmer.
The majority of classes there seem to be untamed. Why are the untamed
classes considered part of the E API? Just because it's too difficult
to tame things at the moment?
David Hopwood <david.nospam.hopwood at blueyonder.co.uk>
More information about the cap-talk