wg/scrypt

Security issue: exec of world-readable jar entry in world-writable directory

anonimal opened this issue · 0 comments

This was brought to my attention after a TPE enabled grsecurity system gave the notice:

grsec: denied untrusted exec (due to file in world-writable directory) of /tmp/scrypt199390770223188475lib

The java process extracting the jar entry is included in the tpe group with the following sysctl options:

kernel.grsecurity.tpe = 1
kernel.grsecurity.tpe_invert = 1
kernel.grsecurity.tpe_restrict_all = 1

Which means the problem is almost certainly not server-side.

A closer look at

/**
* Extract a jar entry to a temp file.
*
* @param name Name prefix for temp file.
* @param is Jar entry input stream.
*
* @return A temporary file.
*
* @throws IOException when an IO error occurs.
*/
private static File extract(String name, InputStream is) throws IOException {
byte[] buf = new byte[4096];
int len;
File lib = File.createTempFile(name, "lib");
FileOutputStream os = new FileOutputStream(lib);
try {
while ((len = is.read(buf)) > 0) {
os.write(buf, 0, len);
}
} catch (IOException e) {
lib.delete();
throw e;
} finally {
os.close();
is.close();
}
return lib;
}
reveals that the location of the extracted jar entry is not specified, so I assume (and I assume the underlying API assumes) that scrypt*lib will write to /tmp on UNIX-like systems.

I don't java much or else I'd submit a PR but I suspect that a trivial solution would be to File.createTempDirectory() before File.createTempFile() and apply the appropriate changes to File.createTempFile() so that the file is written into something like /tmp/scrypt instead of /tmp.

Example (suggested umasks):

umask: 0750
/tmp/scrypt/

umask: 0640
/tmp/scrypt/scrypt199390770223188475lib

This particularly effects https://github.com/i2p/i2p.i2p-bote

Nonetheless, thanks for the great implementation!