Mercurial > jython
changeset 8321:7e917a237b7a
Restrict accessibility of compiled files (fixes #2044 again).
CVE-2013-2027 points out that Jython may be run with umask 0, and then
files cached will be world-writable affecting later sessions. #2044
claimed this fixed by other work, but this change fixes the permissions
explicitly in the compiler and package manager.
author | Jeff Allen <ja.py@farowl.co.uk> |
---|---|
date | Sun, 26 Jan 2020 15:03:50 +0000 |
parents | 44280f7e1854 |
children | ccd1215b3d0e |
files | NEWS src/org/python/core/imp.java src/org/python/core/packagecache/CachedJarsPackageManager.java src/org/python/core/util/FileUtil.java |
diffstat | 4 files changed, 38 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ https://github.com/jythontools/jython Jython 2.7.2b3 Bugs fixed + - [ 2044 ] CVE-2013-2027 Current umask sets privileges of class files and cache - [ 2834 ] Import of Java classes is not thread safe - [ 2820 ] Import fails with UnicodeDecodeError if sys.path contains invalid UTF-8 bytes - [ 2826 ] Unicode hex string decode failure
--- a/src/org/python/core/imp.java +++ b/src/org/python/core/imp.java @@ -480,12 +480,12 @@ public class imp { if (man != null) { man.checkWrite(compiledFilename); } - fop = new FileOutputStream(compiledFilename); + fop = new FileOutputStream(FileUtil.makePrivateRW(compiledFilename)); fop.write(compiledSource); fop.close(); return compiledFilename; } catch (IOException | SecurityException exc) { - // If we can't write the cache file, just logger and continue + // If we can't write the cache file, just log and continue logger.log(Level.FINE, "Unable to write to source cache file ''{0}'' due to {1}", new Object[] {compiledFilename, exc}); return null;
--- a/src/org/python/core/packagecache/CachedJarsPackageManager.java +++ b/src/org/python/core/packagecache/CachedJarsPackageManager.java @@ -5,6 +5,7 @@ package org.python.core.packagecache; import org.python.core.Options; import org.python.core.PyJavaPackage; +import org.python.core.util.FileUtil; import org.python.util.Generic; import java.io.BufferedInputStream; @@ -773,7 +774,7 @@ public abstract class CachedJarsPackageM * overridden. */ protected DataOutputStream outOpenIndex() throws IOException { - File indexFile = new File(this.cachedir, "packages.idx"); + File indexFile = FileUtil.makePrivateRW(new File(this.cachedir, "packages.idx")); FileOutputStream ostream = new FileOutputStream(indexFile); return new DataOutputStream(new BufferedOutputStream(ostream)); } @@ -821,6 +822,7 @@ public abstract class CachedJarsPackageM // That name is in use: make up another one. file = new File(this.cachedir, jarname + "$" + index + ".pkc"); } + file = FileUtil.makePrivateRW(file); entry.cachefile = file.getCanonicalPath(); } else {
--- a/src/org/python/core/util/FileUtil.java +++ b/src/org/python/core/util/FileUtil.java @@ -2,6 +2,7 @@ package org.python.core.util; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -90,4 +91,35 @@ public class FileUtil { } return out.toByteArray(); } + + /** + * Create the named file (if necessary) and give just the owner read-write access. + * + * @param filename to create/control + * @return {@code File} object for subsequent open + * @throws IOException + */ + public static File makePrivateRW(String filename) throws IOException { + return makePrivateRW(new File(filename)); + } + + /** + * Create the identified file (if necessary) and give just the owner read-write access. + * + * @param file to create/control + * @return {@code File} object for subsequent open + * @throws IOException + */ + public static File makePrivateRW(File file) throws IOException { + file.createNewFile(); + // Remove permissions for all + file.setReadable(false, false); + file.setWritable(false, false); + file.setExecutable(false, false); + // Add permissions for owner + file.setReadable(true); + file.setWritable(true); + return file; + } + }