You are viewing a plain text version of this content. The canonical link for it is here.
Posted to repository@apache.org by Brett Porter <br...@gmail.com> on 2006/08/01 11:25:34 UTC

Maven repository security

Hi,

I'd be interested to get feedback on this early draft of possible ways
to improve the verification of downloaded artifacts from Maven
repositories to complete the implementation in the next couple of
months.

http://docs.codehaus.org/display/MAVEN/Repository+Security+Improvements

Some of it still needs to be thought through some more... I've posted
it to dev@maven.apache.org too so feel free to reply there or here
(and I'll integrate any feedback into the document either way).

Thanks,
Brett

Re: Re[4]: Maven repository security

Posted by antonio lain <an...@hplb.hpl.hp.com>.
We also had a couple of issues with jar signing in SmartFrog: 
one is that if you do remote class loading you need to cache "locally"
(or in memory) the jar file before checking it in order to avoid someone
modifying the jar file after you checked it. 
The other is that even if java 2 security gives no privileges to classes
in a jar file still loads them! So if these classes do things that do
not require a permission check (like modifying public static variables)
they are difficult to control. 
We found easier to sub-class a URLClassloader (and then use
getResource() to load resources) to do all that...

I agree on the trust model being the sticky point. Not sure whether it
would help in your context but in SmartFrog we used a delegation model
embedded in X.509 certificates that allows you to represent 
non-hierarchical relationships using linked local names (somewhat like a
subset of SDSI). So you could create a local link with label "antBoss"
to a public key you choose and then talk about "antBoss:committers"
where the ant "boss" is assumed to tag all the valid comitters with the
label "committers" (by issuing  X.509 certificates...). Then, you just
qualify in the SmartFrog description that a component can only load
things from (SELF:antBoss:committers) and the class loaders do the
rest... 

It is still not great but at least you do not trust "apacheBoss" for
everything...

Antonio
 


On Wed, 2006-08-02 at 15:19, Peter Kriens wrote:
> There are a number of verifications. Jarsigner verifies that the
> hashes are ok and the signer file is correctly signed. This is the
> technical integrity that matches traditional checksumming. There is no
> API. You can easily check this by using a JarInputStream/JarFile and getting
> each entry. If the file is signed, the the input stream will do all
> the nasty work for you; it throws an exception when it runs into
> differences.
> 
> This obviously only tells you that the hashes are ok and the file has
> not been tampered with. As a policy, require that the manifest is
> signed and all resources are listed in the manifest. This is not
> mandatory but there are exploits if you don't.
> 
> Next is getting the certificate that was used to sign the jar (which
> can contain a chain). This is trivial, do getCertificates on each Jar
> Entry. Again, I would ensure that ALL entries return the same
> certificates indicating ALL files are signed by All signers.
> 
> Take a look at http://java.sun.com/products/jce/doc/guide/HowToImplAProvider.html#MutualAuth
> 
> It is really not as hard as it sounds. The REAL hard part is the
> Apache trust model.
> 
> Kind regards,
> 
>      Peter Kriens
> 
> 
> 
> 
> 
> Trust is based
> SL> On 02/08/06, Peter Kriens <Pe...@aqute.biz> wrote:
> >>
> >> 2a. JAR file verification
> >>    Verifying a JAR file is not that hard as it sounds. Jarsigner can
> >>    do it, and it is not that hard to code up. However, why do you need to
> >>    do this? The class loader will do this properly during class loading
> >>    which gives you end-to-end security. Notice that a signed JAR does
> >>    not tell you it is trustworthy, it just tells you who signed it.
> >>    You need to decide how much you trust the signer (or the signer of
> >>    the signer certificate if you use certificate chains).
> 
> 
> SL> I dont think jarsigner does work. This is why ant doesnt have a
> SL> <verifysigned> task; I backed it out once we became aware of all the
> SL> deficiencies of the code. It looks like it works, but it doesnt check
> SL> that a JAR is signed by anyone you trust, and it doesnt change its
> SL> return code depending on whether the thing was validated or not. All
> SL> you can do is look at the output string and hope it doesnt change from
> SL> version to version.
> 
> SL> Maybe java1.4 or 1.5 has the API calls to validate the CA chain of the
> SL> signatures.
> 
> SL> -steve
> SL> -steve


Re[4]: Maven repository security

Posted by Peter Kriens <Pe...@aQute.biz>.
There are a number of verifications. Jarsigner verifies that the
hashes are ok and the signer file is correctly signed. This is the
technical integrity that matches traditional checksumming. There is no
API. You can easily check this by using a JarInputStream/JarFile and getting
each entry. If the file is signed, the the input stream will do all
the nasty work for you; it throws an exception when it runs into
differences.

This obviously only tells you that the hashes are ok and the file has
not been tampered with. As a policy, require that the manifest is
signed and all resources are listed in the manifest. This is not
mandatory but there are exploits if you don't.

Next is getting the certificate that was used to sign the jar (which
can contain a chain). This is trivial, do getCertificates on each Jar
Entry. Again, I would ensure that ALL entries return the same
certificates indicating ALL files are signed by All signers.

Take a look at http://java.sun.com/products/jce/doc/guide/HowToImplAProvider.html#MutualAuth

It is really not as hard as it sounds. The REAL hard part is the
Apache trust model.

Kind regards,

     Peter Kriens





Trust is based
SL> On 02/08/06, Peter Kriens <Pe...@aqute.biz> wrote:
>>
>> 2a. JAR file verification
>>    Verifying a JAR file is not that hard as it sounds. Jarsigner can
>>    do it, and it is not that hard to code up. However, why do you need to
>>    do this? The class loader will do this properly during class loading
>>    which gives you end-to-end security. Notice that a signed JAR does
>>    not tell you it is trustworthy, it just tells you who signed it.
>>    You need to decide how much you trust the signer (or the signer of
>>    the signer certificate if you use certificate chains).


SL> I dont think jarsigner does work. This is why ant doesnt have a
SL> <verifysigned> task; I backed it out once we became aware of all the
SL> deficiencies of the code. It looks like it works, but it doesnt check
SL> that a JAR is signed by anyone you trust, and it doesnt change its
SL> return code depending on whether the thing was validated or not. All
SL> you can do is look at the output string and hope it doesnt change from
SL> version to version.

SL> Maybe java1.4 or 1.5 has the API calls to validate the CA chain of the
SL> signatures.

SL> -steve
SL> -steve

-- 
Peter Kriens                              Tel +33467542167
9C, Avenue St. Drézéry                    AOL,Yahoo: pkriens
34160 Beaulieu, France                    ICQ 255570717
Skype pkriens                             Fax +1 8153772599


Re: Re[2]: Maven repository security

Posted by Steve Loughran <st...@gmail.com>.
On 02/08/06, Peter Kriens <Pe...@aqute.biz> wrote:
>
> 2a. JAR file verification
>    Verifying a JAR file is not that hard as it sounds. Jarsigner can
>    do it, and it is not that hard to code up. However, why do you need to
>    do this? The class loader will do this properly during class loading
>    which gives you end-to-end security. Notice that a signed JAR does
>    not tell you it is trustworthy, it just tells you who signed it.
>    You need to decide how much you trust the signer (or the signer of
>    the signer certificate if you use certificate chains).


I dont think jarsigner does work. This is why ant doesnt have a
<verifysigned> task; I backed it out once we became aware of all the
deficiencies of the code. It looks like it works, but it doesnt check
that a JAR is signed by anyone you trust, and it doesnt change its
return code depending on whether the thing was validated or not. All
you can do is look at the output string and hope it doesnt change from
version to version.

Maybe java1.4 or 1.5 has the API calls to validate the CA chain of the
signatures.

-steve
-steve

Re[2]: Maven repository security

Posted by Peter Kriens <Pe...@aQute.biz>.
0. A single bug breaks security, no work arounds
   I think this is the hallmark of a good security system?

2. A CA would be really good, but note that there is a horrible
   authorization problem. How can a central person/group be
   responsible for all Apache code? You might want to think if a
   delegated CA. Each project lead would own a certificate that is
   signed by an Apache certificate. However, if you want to be trusted
   by root certificates, you would need a special Apache certificate
   that can be used to sign other signing certificates. Maybe in this
   case you can set a standard and use a self signed certificate.
   Anyway, the hardest problem is the trust problem. Which works both
   ways. Can users trust the certificate, and can the signer trust
   the code he signs? Before you do anything else, work out the trust
   model. Who will do what and trust what and when. The rest is mechanics

2a. JAR file verification
   Verifying a JAR file is not that hard as it sounds. Jarsigner can
   do it, and it is not that hard to code up. However, why do you need to
   do this? The class loader will do this properly during class loading
   which gives you end-to-end security. Notice that a signed JAR does
   not tell you it is trustworthy, it just tells you who signed it.
   You need to decide how much you trust the signer (or the signer of
   the signer certificate if you use certificate chains).

   If you do not use JARs (e.g. remote classloading) you obviously do not
   get the advantages of signing because it is a JAR mechanism.

2b. Not signing the manifest
   The manifest is nowadays signed. The way signing works is that each
   signer creates a manifest like file that contains hashes of
   relevant parts of the manifest. This file is then digitally signed
   using one of the signing algorithms. This manifest like file can
   also hold a hash of the global section (where you have your
   Class-Path or Sealed attributes).

2c. Checksumming JARs
This has lots of complications because you get multiple files. JAR
signing is really very powerful when you get the hang of it. And it
has the GREAT advantage you only have a single file to worry about.
And it is built into all VMs.

3. Signing the JAR checksums
The power of signing is that you create a delegated trust model which
does not require a bottleneck. The problem is that signing was only
partially intended to check the integrity of the JAR. The key part is
that it allows you to verify that the the signer can be trusted
without having to know all signers a priori. Using Java security, you
can even place each class in its own sandbox depending on the
certificate (if you want to go ballistic).

The idea is that anybody can fool with your caches, transport or
whatever because the VM checks the signature and puts the classes in
the pre-assigned sandbox (which can be an empty sandbox). This
end-to-end security over an untrusted network works usually better
than trying to secure the whole chain.

Using signing without Java permissions is not very useful btw.

---
There are also some other issues. One thing we found in the OSGi
Alliance is that if you do not sign EACH resource in the JAR there are
some corner cases that can be used to exploit. Another thing we found
is that for a trust model to work you need something finer that
sandboxes; we added a permission file to a bundle. If you are
interested, there is a section about these issues in the OSGi R4 spec.

Security is really hard, maybe the current Java security model is not
really matching your needs. However, shortcuts because you need all of
it is often causing regrets later down the line. I am not a big fan of
the Java 2 security model (of which signing is a part). However,
whenever I use a Java VM, a big part of that thing is spending doing
Java security things. Trying to devise alternatives is wasting those
CPU cycles which I really do not want to worsen by adding my own
mechanisms. And getting it right is really, really hard.

Kind regards,

     Peter Kriens





SL> I had a look this morning; I can't do it again as docs.codehaus.org is
SL> unreachable, so here is stome stuff from memory.

SL> 0. Its really hard to get things secure, because a single bug breaks
SL> the security. Its not like normal code where bugs can be worked
SL> around. You suddenly have to think about how to securely distribute
SL> the initial app, the one with basic trust and auth built in, as that
SL> becomes an attack point.

SL> 1. make sure that Ben Laurie overviews the spec too, as he is
SL> effectively the apache security expert. I've also CC'd Antonio Laim,
SL> who is the SmartFrog security police.

SL> 2. JAR signing -

SL> We may want to add an apache CA in the distributions somehow, so that
SL> we can trust apache signed JARs.

SL> 2a.
SL> It's almost impossible to verify that a JAR is signed, because what is
SL> really happening is every file entry in the archive is individually
SL> signed. You need to pull apart the zip file and validate every
SL> resource separately, and that is not built in to the Sun API (or
SL> Ant's, BTW). You also need to pull down the JAR before doing the
SL> validation; anything that does remote classloading is vulnerable to
SL> post-validation attacks.

SL> 2b.
SL> What is interesting about JARs is that multiple people can sign them,
SL> and the signing doesnt affect the other signings, because nobody signs
SL> the manifest. Actually, that's a possible attack point. I could edit
SL> the Class-Path, Sealed: or Main: entries in a JAR and nobody would
SL> notice until the thing ran.

SL> 2c.
SL> What aftermarket signing JARs does do is break the SHA1 and MD5
SL> checksums of the JAR itself. So I cannot sign JARs in my local maven
SL> cache without their checksums changing, even though, as far is java is
SL> concerned, they are still valid and signed.


SL> 3. post-installation attacks. There's an implicit attack point in the
SL> maven local cache, as all files have known locations. If I gain access
SL> to your filesystem I could insert a custom JAR in there. That may give
SL> me privilege escalation if I know that, say, ehcache.jar gets copied
SL> into JBoss/default/lib and then runs as root. We need something to
SL> audit the JARs. I can't do that by signing all the JARs because of 2c,
SL> and because of things like hibernate/cglib failing
SL> [http://opensource.atlassian.com/projects/hibernate/browse/HHH-1365]

SL> What might be interesting would be for a way for me to checksum all
SL> artifacts in my own repo and sign the checksums, so that I can say
SL> that yes, I trust them. Then the runtime could detect if something
SL> different from my signing and bail out. This would let the ops teams
SL> restrict artifact retrieval/loading to only approved artifacts, while
SL> still using the common repository.

SL> In this world I need a signature file for every artifact, one that
SL> contains a list of signings of the checksum, and which can have extra
SL> signatures appended to it without contaminating the artifact.

SL> I might also need a way of publishing signatures from different repositories.

SL> 4. we need a way of revoking artifact authentications. it will happen,
SL> let's plan for it.
SL> -steve

SL> On 01/08/06, Brett Porter <br...@gmail.com> wrote:
>> Hi,
>>
>> I'd be interested to get feedback on this early draft of possible ways
>> to improve the verification of downloaded artifacts from Maven
>> repositories to complete the implementation in the next couple of
>> months.
>>
>> http://docs.codehaus.org/display/MAVEN/Repository+Security+Improvements
>>
>> Some of it still needs to be thought through some more... I've posted
>> it to dev@maven.apache.org too so feel free to reply there or here
>> (and I'll integrate any feedback into the document either way).
>>
>> Thanks,
>> Brett
>>

-- 
Peter Kriens                              Tel +33467542167
9C, Avenue St. Drézéry                    AOL,Yahoo: pkriens
34160 Beaulieu, France                    ICQ 255570717
Skype pkriens                             Fax +1 8153772599


Re: Maven repository security

Posted by Steve Loughran <st...@gmail.com>.
I had a look this morning; I can't do it again as docs.codehaus.org is
unreachable, so here is stome stuff from memory.

0. Its really hard to get things secure, because a single bug breaks
the security. Its not like normal code where bugs can be worked
around. You suddenly have to think about how to securely distribute
the initial app, the one with basic trust and auth built in, as that
becomes an attack point.

1. make sure that Ben Laurie overviews the spec too, as he is
effectively the apache security expert. I've also CC'd Antonio Laim,
who is the SmartFrog security police.

2. JAR signing -

We may want to add an apache CA in the distributions somehow, so that
we can trust apache signed JARs.

2a.
It's almost impossible to verify that a JAR is signed, because what is
really happening is every file entry in the archive is individually
signed. You need to pull apart the zip file and validate every
resource separately, and that is not built in to the Sun API (or
Ant's, BTW). You also need to pull down the JAR before doing the
validation; anything that does remote classloading is vulnerable to
post-validation attacks.

2b.
What is interesting about JARs is that multiple people can sign them,
and the signing doesnt affect the other signings, because nobody signs
the manifest. Actually, that's a possible attack point. I could edit
the Class-Path, Sealed: or Main: entries in a JAR and nobody would
notice until the thing ran.

2c.
What aftermarket signing JARs does do is break the SHA1 and MD5
checksums of the JAR itself. So I cannot sign JARs in my local maven
cache without their checksums changing, even though, as far is java is
concerned, they are still valid and signed.


3. post-installation attacks. There's an implicit attack point in the
maven local cache, as all files have known locations. If I gain access
to your filesystem I could insert a custom JAR in there. That may give
me privilege escalation if I know that, say, ehcache.jar gets copied
into JBoss/default/lib and then runs as root. We need something to
audit the JARs. I can't do that by signing all the JARs because of 2c,
and because of things like hibernate/cglib failing
[http://opensource.atlassian.com/projects/hibernate/browse/HHH-1365]

What might be interesting would be for a way for me to checksum all
artifacts in my own repo and sign the checksums, so that I can say
that yes, I trust them. Then the runtime could detect if something
different from my signing and bail out. This would let the ops teams
restrict artifact retrieval/loading to only approved artifacts, while
still using the common repository.

In this world I need a signature file for every artifact, one that
contains a list of signings of the checksum, and which can have extra
signatures appended to it without contaminating the artifact.

I might also need a way of publishing signatures from different repositories.

4. we need a way of revoking artifact authentications. it will happen,
let's plan for it.
-steve

On 01/08/06, Brett Porter <br...@gmail.com> wrote:
> Hi,
>
> I'd be interested to get feedback on this early draft of possible ways
> to improve the verification of downloaded artifacts from Maven
> repositories to complete the implementation in the next couple of
> months.
>
> http://docs.codehaus.org/display/MAVEN/Repository+Security+Improvements
>
> Some of it still needs to be thought through some more... I've posted
> it to dev@maven.apache.org too so feel free to reply there or here
> (and I'll integrate any feedback into the document either way).
>
> Thanks,
> Brett
>

Re: Maven repository security

Posted by Steve Loughran <st...@gmail.com>.
On 01/08/06, Brett Porter <br...@gmail.com> wrote:
> Hi,
>
> I'd be interested to get feedback on this early draft of possible ways
> to improve the verification of downloaded artifacts from Maven
> repositories to complete the implementation in the next couple of
> months.
>
> http://docs.codehaus.org/display/MAVEN/Repository+Security+Improvements
>
> Some of it still needs to be thought through some more... I've posted
> it to dev@maven.apache.org too so feel free to reply there or here
> (and I'll integrate any feedback into the document either way).
>

Reading it one more time, the trick of using SHA1 or MD5 checksums in
a dependency element is exactly what we do in smartfrog descriptors:


InstallHibernate extends Compound {

    destDir TBD;

    repo extends Maven2Library {
    }

    ehcache.jar extends JarArtifact {
        library LAZY PARENT:repo;
        project "ehcache";
        version "1.1";
        sha1 "c781c87c2eb4e062a473822486cca46cd785b24a";
    }

    copy.ehcache.jar extends CopyFile {
      source LAZY ehcache.jar;
      destination LAZY destDir ;
      copyOnDeploy false;
      overwrite false;
    }


    commons-collections.jar extends JarArtifact {
        library LAZY PARENT:repo;
        project "commons-collections";
        version "2.1.1";
        sha1 "017c599cfcc98d31ce2d2688b4f8826bbeb9aa98";
    }


    copy.commons-collections.jar extends copy.ehcache.jar {
        source LAZY commons-collections.jar;
    }

Provided you have the descriptor signed, you are immune to tampered
artifacts, at least until MD5 and SHA1 falls, at which point you have
more serious problems such as the fact that things like RPM are
compromised.

-steve