@@ -92,7 +92,13 @@ public static LocalPath tar(LocalPath sourceDir) {
9292 paths .forEach (path -> {
9393 LOG .trace ("Visiting path: {}" , path );
9494 try {
95- String entryName = sourceDir .getPath ().relativize (path ).toString ();
95+
96+ Path relativePath = sourceDir .getPath ().relativize (path );
97+ if (relativePath .toString ().isEmpty ()) {
98+ LOG .trace ("Skipping root directory: {}" , path );
99+ return ;
100+ }
101+ String entryName = relativePath .toString ();
96102
97103 TarArchiveEntry entry = null ;
98104 BasicFileAttributes attrs = Files .readAttributes (path , BasicFileAttributes .class );
@@ -142,6 +148,21 @@ public static LocalPath tar(LocalPath sourceDir) {
142148 return LocalPath .of (tarFile , Const .DEFAULT_BLOB_MEDIA_TYPE );
143149 }
144150
151+ /**
152+ * Ensure that the entry is safe to extract
153+ * @param entry The tar entry
154+ * @param target The target directory
155+ * @throws IOException
156+ */
157+ static void ensureSafeEntry (TarArchiveEntry entry , Path target ) throws IOException {
158+ // Prevent path traversal attacks
159+ Path outputPath = target .resolve (entry .getName ()).normalize ();
160+ Path normalizedTarget = target .toAbsolutePath ().normalize ();
161+ if (!outputPath .startsWith (normalizedTarget )) {
162+ throw new IOException ("Entry is outside of the target dir: " + target );
163+ }
164+ }
165+
145166 /**
146167 * Extract a tar file to a target directory
147168 * @param fis The archive stream
@@ -161,6 +182,9 @@ public static void untar(InputStream fis, Path target) {
161182 // Prevent path traversal attacks
162183 Path outputPath = target .resolve (entry .getName ()).normalize ();
163184
185+ // Check if the entry is outside the target directory
186+ ensureSafeEntry (entry , target );
187+
164188 LOG .trace ("Extracting entry: {}" , entry .getName ());
165189
166190 if (entry .isDirectory ()) {
0 commit comments