From 7afad0a9624bb30fd5501c7d33717575c5fb6b7d Mon Sep 17 00:00:00 2001
From: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>
Date: Sat, 19 Nov 2022 02:07:27 +0000
Subject: [PATCH] vuln-fix: Temporary File Information Disclosure

This fixes temporary file information disclosure vulnerability due to the use
of the vulnerable `File.createTempFile()` method. The vulnerability is fixed by
using the `Files.createTempFile()` method which sets the correct posix permissions.

Weakness: CWE-377: Insecure Temporary File
Severity: Medium
CVSSS: 5.5
Detection: CodeQL & OpenRewrite (https://public.moderne.io/recipes/org.openrewrite.java.security.SecureTempFileCreation)

Reported-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>
Signed-off-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>

Bug-tracker: https://github.com/JLLeitschuh/security-research/issues/18


Co-authored-by: Moderne <team@moderne.io>
---
 owner/src/main/java/org/aeonbits/owner/util/Util.java        | 3 ++-
 .../org/aeonbits/owner/interfaces/AccessibleConfigTest.java  | 3 ++-
 .../org/aeonbits/owner/interfaces/MutableConfigTest.java     | 5 +++--
 .../org/aeonbits/owner/serializable/TestSerialization.java   | 3 ++-
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/owner/src/main/java/org/aeonbits/owner/util/Util.java b/owner/src/main/java/org/aeonbits/owner/util/Util.java
index eae024c0..48e67aeb 100644
--- a/owner/src/main/java/org/aeonbits/owner/util/Util.java
+++ b/owner/src/main/java/org/aeonbits/owner/util/Util.java
@@ -22,6 +22,7 @@
 import java.lang.reflect.Method;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -200,7 +201,7 @@ public static void save(File target, Properties p) throws IOException {
         if (isWindows()) {
             store(target, p);
         } else {
-            File tempFile = createTempFile(target.getName(), ".temp", parent);
+            File tempFile = Files.createTempFile(parent.toPath(), target.getName(), ".temp").toFile();
             store(tempFile, p);
             rename(tempFile, target);
         }
diff --git a/owner/src/test/java/org/aeonbits/owner/interfaces/AccessibleConfigTest.java b/owner/src/test/java/org/aeonbits/owner/interfaces/AccessibleConfigTest.java
index 67eb79b0..32576083 100644
--- a/owner/src/test/java/org/aeonbits/owner/interfaces/AccessibleConfigTest.java
+++ b/owner/src/test/java/org/aeonbits/owner/interfaces/AccessibleConfigTest.java
@@ -26,6 +26,7 @@
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.nio.file.Files;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.ScheduledExecutorService;
@@ -88,7 +89,7 @@ public void testListPrintWriter() throws IOException {
     @Test
     public void testStore() throws IOException {
         AccessibleConfig cfg = ConfigFactory.create(AccessibleConfig.class);
-        File tmp = File.createTempFile("owner-", ".tmp");
+        File tmp = Files.createTempFile("owner-", ".tmp").toFile();
         cfg.store(new FileOutputStream(tmp), "no comments");
         assertTrue(tmp.exists());
         assertTrue(tmp.length() > 0);
diff --git a/owner/src/test/java/org/aeonbits/owner/interfaces/MutableConfigTest.java b/owner/src/test/java/org/aeonbits/owner/interfaces/MutableConfigTest.java
index 84eafa80..d729a19b 100644
--- a/owner/src/test/java/org/aeonbits/owner/interfaces/MutableConfigTest.java
+++ b/owner/src/test/java/org/aeonbits/owner/interfaces/MutableConfigTest.java
@@ -19,6 +19,7 @@
 import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.util.Properties;
 
 import static org.junit.Assert.assertEquals;
@@ -83,7 +84,7 @@ public void testClear() {
 
     @Test
     public void testLoadInputStream() throws IOException {
-        File temp = File.createTempFile("MutableConfigTest", ".properties");
+        File temp = Files.createTempFile("MutableConfigTest", ".properties").toFile();
         UtilTest.save(temp, new Properties() {{
             setProperty("minAge", "19");
             setProperty("maxAge", "99");
@@ -97,7 +98,7 @@ public void testLoadInputStream() throws IOException {
 
     @Test
     public void testLoadReader() throws IOException {
-        File temp = File.createTempFile("MutableConfigTest", ".properties");
+        File temp = Files.createTempFile("MutableConfigTest", ".properties").toFile();
         UtilTest.save(temp, new Properties() {{
             setProperty("minAge", "19");
             setProperty("maxAge", "99");
diff --git a/owner/src/test/java/org/aeonbits/owner/serializable/TestSerialization.java b/owner/src/test/java/org/aeonbits/owner/serializable/TestSerialization.java
index c3a19173..fc6817a0 100644
--- a/owner/src/test/java/org/aeonbits/owner/serializable/TestSerialization.java
+++ b/owner/src/test/java/org/aeonbits/owner/serializable/TestSerialization.java
@@ -26,6 +26,7 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.nio.file.Files;
 
 import static java.io.File.createTempFile;
 import static org.aeonbits.owner.util.Collections.map;
@@ -56,7 +57,7 @@ public static interface MyConfig extends Mutable {
     public void before() throws IOException {
         File parent = new File(RESOURCES_DIR);
         parent.mkdirs();
-        target = createTempFile("TestSerialization", ".ser", parent);
+        target = Files.createTempFile(parent.toPath(), "TestSerialization", ".ser").toFile();
     }
 
     @After