You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by Bear Giles <bg...@coyotesong.com> on 2003/06/12 03:15:52 UTC
several security issues with maven
I've been struggling for the better part of the day to get maven
to work... and have identified several critical security issues in
the process. N.B., these are so critical that many sysadmins will
not only allow maven, they'll disallow anything built with it!
(Standard stuff: maven 1.0.b9, binary release, standard
configuration since I've been unable to find any configuration files.)
...
The first issue is the practice of physically unpacking plugin jar
files in the $MAVEN_HOME/plugins directly. This requires the
directory to be writable by the least privileged user who will run
maven - in practice this directory will almost always be
world-writable, perhaps with the sticky bit set.
Worse in this situation, maven simply loads every jar file in the
directory. It does not read an externally defined (and protected)
list.
This is an extremely critical error - it means that maven will
normally be configured so any user can toss any jar file into that
directory and maven will unpack it and do whatever it does with
plugins. If the directory is world-writable but doesn't have the
sticky bit set, any user could replace a standard jar file with
their own malicious one.
If you haven't turned ash white, hit the library and pick up the
issue of the Comm. of the ACM where (Kerrigan & Plauger?) discuss
their experiments with malicious compilers that insert their own
code. The damage is far worse with java, since java.net is a
standard component and it is trivial for even an inexperienced
java programmer to write net-aware exploits.
Solution: $MAVEN_HOME/plugins must be treated like any other
system library directory - it must work with 0555 permissions.
In this case, the fix should actually be straightforward since the
nonsense about unpacking the file to read its content with a
FileInputStream should be replaced with a java.util.jar.Jarile and
a call to java.util.jar.JarEntry.getInputStream().
The caching is another issue... but at first glance I don't
understand why this would even be an issue - I'm not aware of any
other application that physically unpacks jar files like that.
It's not hard to open each jar file and cache the entries at
startup -- and hides it all behind a specialized classloader.
...
The second issue is more subtle. When packages are downloaded,
they are put into the global $MAVEN_HOME/repository.
The GLOBAL repository.
The same issues crop up - the repository will need to be
world-writable, malicious jarfiles can be added (complete with
matching MD5 checksums), etc.
There's a standard solution to this - maven should cache files in
a per-user repository, not the global repository. Or maven can
attempt to write to the global repository first, then quietly
fallover to the per-user repository if access is denied.
...
Other fixes.
For the sake of completeness, there is a workaround available...
but it's considered unacceptable by most sysadmins. The solution
is to set the group of the $MAVEN_HOME/plugins and
$MAVEN_HOME/repository directories to some unique group, e.g.,
"maven", then set the "maven" script setgid "maven." This would
allow maven to update these directories, while denying write
access to the average user.
(Another variant would set the "user" to "maven" and make the
script setuid).
This is unacceptable since it requires making a script setgid (or
setuid) - a big no-no in many circles. We can't make the java
executable setgid without making the directories effectively
world-writable again.
...
Some code may follow, to illustrate possible solutions.
Bear
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org
Re: several security issues with maven
Posted by Bear Giles <bg...@coyotesong.com>.
Answering one of my own questions (for the archive), the files are
unpacked because MavenUtils.getProject() expects a java.io.File
argument for a Betwixt parser. I haven't used Betwixt, but I
would expect there to be another method that takes an InputStream.
This suggests that the classloader object I included earlier could
either provide special hooks for the project.xml and similar
top-level files, returning InptuStreams that can be used by
parsers, or the classloader can simply maintain some beanjars in
the same package. This would add something like
}
else if (name.equals("project.xml")) {
BeanReader pbr = getProjectBeanReader();
Project project =
(Project) pbr.parse(jf.getInputStream(ze));
ProjectBeans.add(project);
}
There is also some information encoded into the directory
structure, but it's not clear to me if that's an issue with the
plugin jars. If it is, the information can be easily cached
somewhere.
Also, a bit of clarification on the motivations I was discussing
last night. The question I keep coming back to is "how do I know
this?" The more you know, the more you want to lock down
everything. :-)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org
Re: several security issues with maven
Posted by Bear Giles <bg...@coyotesong.com>.
Florin Vancea wrote:
> Hello Bear, hello all,
>
> IMHO, the final continuous build machine should be anyway a root-only
> machine (OK, root and the-same-root-person-as-a-common-user). The developer
> machine is also pretty much a developer-only machine, so there is little
> concern about some other user fiddling with the files.
To be honest, my concern isn't another user fiddling with the
files. That type of stuff is best handled administratively.
My concern is everyone you don't know about. As maven is used by
more projects, it becomes a more attractive target. And that
means you have to start worrying about more sophsticated
attackers. Forcing them to get root access to do any damage
raises the barrier a bit, and keeping everything in the original
jar files (vs. unpacking them) helps a bit more.
> If so, the problem is common to many
> other packages than only Maven.
Very few support plugin libraries to this extent. Plugins are
always problematic - system libraries have presumably had some
amount of testing, etc. But "plugins" are often lightweight,
poorly tested code which is still run with high privilege. That's
scary - it's not as bad as Outlook's willingness to run arbitrary
code from anyone who bothers to send some its way, but it's still
pretty scary.
Anyway... the attached file is a ClassLoader that scans the ToC of
all of the jar files in a subdirectory, then loads the content on
demand. The "main" routine shows how to use the standard
interface to load a class, a ResourceBundle, or an arbitrary
resource (e.g., a .png image).
Something it doesn't yet support, but easily could, is a separate
SecurityManager for plugin classes. E.g., maybe the maven classes
have net access, but the plugins don't. (Or only specific ones
do.) Another possible idea is restricting the classes that can be
loaded by the plugins, e.g., allowing them to load standard java.*
and javax.* libraries, but not others.
The same thing applies to all downloaded code - to me it makes a
lot of sense to be able to set up rules in the build environment
that say an automatically downloaded package can't download
another package, it can't access the net at all, perhaps can't
read or write any files outside of a sandbox, etc. If you really
need some of these packages, they should be deliberately bundled
and installed in the regular classpath.
After this security manager is installed, you have some measure of
protection even if somebody manages to corrupt an upstream
package. Your production environment may still get hosed, but
your development environment should be protected from a rogue
jarfile scribbling into others.
Re: several security issues with maven
Posted by Florin Vancea <fv...@maxiq.ro>.
Hello Bear, hello all,
IMHO, the final continuous build machine should be anyway a root-only
machine (OK, root and the-same-root-person-as-a-common-user). The developer
machine is also pretty much a developer-only machine, so there is little
concern about some other user fiddling with the files.
Are you thinking about some academic-like environment? (shared machines or
many accounts on the same machine) If so, the problem is common to many
other packages than only Maven. I guess there are a lot of development tools
that require in a form or other rights higher than the average admin would
be happy to grant (I've had my share with MS tools).
The new features like split and read-only installation can be however
helpful, and a little thought on security won't hurt, but the nature of the
development environment is different than the nature of a production one, at
least from the security point of view.
Florin
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org
Re: several security issues with maven
Posted by Bear Giles <bg...@coyotesong.com>.
Attached is a quickie implementation of a class loader, if it will
help. I didn't touch resource URLs, but an approach I've used
with a lot of success in the past is to use a form like
jar:/path/to/jarfile?file/within/jarfile
That's easy to construct, easy to parse, unique, and not easily
confused with standard URLs.
Something occured to me a few minutes ago - conceptually the
entire retrieval subsection is another classloader. In fact, it
should be a SecureClassLoader - the SecurityManager could be use
to restrict access to some upstream sites (e.g., you could disable
access to a site you believe to have been compromised), local
write access to the repository, etc.
In this case the classloader I mentioned above would disappear.
Somewhere near the top of the program the new classloader would be
specified, then everyone would just load files as usual. The
classloader (and security manager) would decide whether to
download files, where to cache them, etc. Everyone else would
either see requests succeed or a ClassNotFoundException.
Brett Porter wrote:
> Already fixed in CVS for b10 - the whole maven installation can now be
> read only and the plugins are expanded to ~/.maven/plugins
I guess I'm still confused why they're expanded at all. Writing
files is hard - how good is Java at guarding against symlink
attacks, race conditions, etc.?
>> The second issue is more subtle. When packages are downloaded,
>> they are put into the global $MAVEN_HOME/repository.
>
> Define maven.repo.local in ~/build.properties and it will store it
> wherever you choose. In b10, the default is ~/.maven/repository
What if you want that split behavior? Or prohibiting downloading
any file by an untrusted user - they need to ask a trusted user to
retrieve upstream packages for them.
I guess I should cut to the chase - where's the formal security
policy? That would identify roles, rights, etc.
> I've found current CVS to be at least as stable as b9 if not more so,
> and its easy to build with the bootstrap, so I'd recommend giving it a go.
I've been unable to get any snapshot to compile yet. I didn't try
to compile the current CVS head because I'm trying to rebuild and
package other Apache packages and need to provide a provenance of
all tools - whatever I use has to be recreatable by others, so a
tagged CVS snapshot is okay, the "current contents" are not.
Running the binary package was a stopgap measure - self-compiling
a tool from its own binary is very risky (see the CACM article for
the gruesome details why), but it would allow me to proceed
provisionally.
> Don't panic ;)
I wasn't panicked. Pissed at having wasted hours, but not
panicked. :-)
Re: several security issues with maven
Posted by Brett Porter <bp...@f2network.com.au>.
> The first issue is the practice of physically unpacking plugin jar
> files in the $MAVEN_HOME/plugins directly. This requires the
> directory to be writable by the least privileged user who will run
> maven - in practice this directory will almost always be
> world-writable, perhaps with the sticky bit set.
Already fixed in CVS for b10 - the whole maven installation can now be
read only and the plugins are expanded to ~/.maven/plugins
> The second issue is more subtle. When packages are downloaded,
> they are put into the global $MAVEN_HOME/repository.
Define maven.repo.local in ~/build.properties and it will store it
wherever you choose. In b10, the default is ~/.maven/repository
I've found current CVS to be at least as stable as b9 if not more so,
and its easy to build with the bootstrap, so I'd recommend giving it a go.
Don't panic ;)
Cheers,
Brett
--
Web Developer
f2 network ~ everything essential
02 8596 4437
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org