On 25/04/2022 10:53 pm, David Lloyd wrote:

Nothing in the proposal is intended to solve the issue of tainted
data; with or without this proposal, this is an unsolved problem.

Well, actually, the statement "this is an unsolved problem" is not entirely 
true, I think we came very close to solving it.  In any case, security is pretty tight:

Perl taint was simple, you parse text data using pattern recognition, the 
results of pattern matching was considered untainted.  Until the data was 
parsed, it was considered tainted, so it couldn't be used for ODBC etc until it 
was parsed, it was marked as tainted, so you could delay parsing it if you 
wanted and Perl would keep track of tainted data.

In JGDMS (evolved from Jini and Apache River) we perform input validation with 
atomic de-serialization, although we don't mark data as tainted, as it is 
expected to be validated prior to object instantiation.  Every Object in the 
stream must implement @AtomicSerial, or be a primitive, String or Enum, no 
circular object graphs are allowed.  It is expected that strings will be 
parsed, or pattern matched, during input validation, unlike Perl taint, it's 
not something that can be enforced, if Java provided a way to mark Strings as 
tainted, then we could ensure that any Strings received created directly from 
stream data are not involved in privileged actions.  We could maintain a 
collection of tainted strings, but then some of them may be identical to 
strings which aren't tainted, so it wouldn't work as expected, the JVM would 
need to avoid caching tainted strings.  The problem is, to make the String 
tainted, it would require a permanently unprivileged domain and this isn't easy 
to do for a final class such as String.

https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/jgdms-platform/src/main/java/org/apache/river/api/io/AtomicSerial.java


However, in our implementation, de-serialization requires permission, these 
de-serialization permissions should be granted to ProtectionDomain's based on their 
(CodeSource || ClassLoader) && Principal's.   So the CodeSource should be 
audited and the Principal trusted (Subject authenticated) before these permissions are 
granted.  The Principal is the source of the data.

https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/jgdms-platform/src/main/java/org/apache/river/api/io/DeSerializationPermission.java

On the server side, the server usually provides the code that will parse data 
it receives from the client, however on the client side, the server also 
provides the code to parse proxy data at the client, so we are heavily 
dependent on authentication, authorization, encryption privacy and encryption 
message digests.

Alone, neither the CodeSource nor the Principal, have permission to 
deserialize, only when both together have permission, only then is 
de-serialization permitted.

Even though the data source Principal is trusted (and authenticated), the Code 
must still be audited and trusted to parse the data provided.

A CodeSource may receive permission by its CodeSigner identity, or if the 
server's authenticated Subject is trusted enough to provide signer 
certificates, or a message digest of the CodeSource, in which case the client 
grants permission dynamically.

A single parameter object class provides access to serial data, for all classes 
in the object inheritance hierarchy.

Every @AtomimcSerial object must check its invariant's, child classes are able 
to create super class instances, prior to creating an instance of themselves, 
to allow super classes to check their invariant's.  Any object that fails an 
invariant check, throws an exception prior to calling a super class 
constructor.  Serial parameters have separate namespaces for each class, so a 
child class cannot see the serial parameters of a superclass, instead it must 
create an instance of the superclass (which checks it's own invariants) first 
and then call it's methods and check it's state, the superclass object is not 
an instance of the child class.  Once the child class is satisfied that the 
superclass instance has been validated, it checks the invariants in its own 
serial data, prior to creating an object instance of itself (although it is 
free to check this first, if it is more efficient to do so, eg fail fast).

Collection instances are not serialized, not using Java serialization, but 
replaced in streams using read only collections backed by arrays.  Collection 
types share the same serial form, such that if Set, List and Map would be equal 
if compared as objects also have equal serial form.   It is the responsibility 
of @AtoimcSerial classes to check invariant's and make defensive copies of 
Collections.   A utility class, Valid, assists with input validation on 
collections.

https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/jgdms-platform/src/main/java/org/apache/river/api/io/Valid.java

Limits are placed on array lengths and stream data, this is a countdown, which 
must be periodically reset, or an exception will be thrown and control returned 
to the caller when the limit is reached.

Invocation constraints also provide a way for callers to communicate their 
intent to underlying communication layers.

https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/jgdms-platform/src/main/java/net/jini/core/constraint/InvocationConstraints.java

Note that there are extensible layers:

1. Invocation layer
2. Object Identification layer.
3. Serialization layer.
4. Transport layer.

https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/jgdms-jeri/src/main/java/net/jini/jeri/package.html

These security precautions will no longer provide protection after SM is 
degraded, hence the need to re-implement an authorization layer.

I had hoped that OpenJDK might assist us by providing hooks we can use to 
control network access, creation of ClassLoader's or access to properties, or 
key stores, but it looks as though we have to instrument the Java api's and we 
are on our own.  It also appears due to finalizers, that there will be versions 
of OpenJDK which we cannot support, eg if SM has been disabled and finalizers 
are still present, we cannot support this JDK version.

Personally I'd like to see SM fully supported until finalizers can be disabled.

--
Regards,
Peter Firmstone

Reply via email to