@@ -183,7 +183,11 @@ public final PageSet<? extends StorageMetadata> list(String container,
183183 } else {
184184 prefix = "" ;
185185 }
186- var pathPrefix = root .resolve (container ).resolve (prefix );
186+ var pathPrefix = root .resolve (container ).resolve (prefix ).normalize ();
187+ if (!pathPrefix .startsWith (container )) {
188+ throw new IllegalArgumentException ("Invalid key name: path traversal attempt detected." );
189+ }
190+ logger .debug ("Listing blobs at: {}" , pathPrefix );
187191 var set = ImmutableSortedSet .<StorageMetadata >naturalOrder ();
188192 try {
189193 listHelper (set , container , dirPrefix , pathPrefix , delimiter );
@@ -344,7 +348,10 @@ public final Blob getBlob(String container, String key, GetOptions options) {
344348 throw new ContainerNotFoundException (container , "" );
345349 }
346350
347- var path = root .resolve (container ).resolve (key );
351+ var path = root .resolve (container ).resolve (key ).normalize ();
352+ if (!path .startsWith (container )) {
353+ throw new IllegalArgumentException ("Invalid key name: path traversal attempt detected." );
354+ }
348355 logger .debug ("Getting blob at: {}" , path );
349356
350357 try {
@@ -528,7 +535,10 @@ public final String putBlob(String container, Blob blob, PutOptions options) {
528535 throw new ContainerNotFoundException (container , "" );
529536 }
530537
531- var path = root .resolve (container ).resolve (blob .getMetadata ().getName ());
538+ var path = root .resolve (container ).resolve (blob .getMetadata ().getName ()).normalize ();
539+ if (!path .startsWith (container )) {
540+ throw new IllegalArgumentException ("Invalid key name: path traversal attempt detected." );
541+ }
532542 // TODO: should we use a known suffix to filter these out during list?
533543 var tmpPath = root .resolve (container ).resolve (blob .getMetadata ().getName () + "-" + UUID .randomUUID ());
534544 logger .debug ("Creating blob at: {}" , path );
@@ -693,7 +703,11 @@ public final String copyBlob(String fromContainer, String fromName,
693703 public final void removeBlob (String container , String key ) {
694704 try {
695705 var containerPath = root .resolve (container );
696- var path = containerPath .resolve (key );
706+ var path = containerPath .resolve (key ).normalize ();
707+ if (!path .startsWith (container )) {
708+ throw new IllegalArgumentException ("Invalid key name: path traversal attempt detected." );
709+ }
710+ logger .debug ("Deleting blob at: {}" , path );
697711 Files .delete (path );
698712 removeEmptyParentDirectories (containerPath , path .getParent ());
699713 } catch (NoSuchFileException nsfe ) {
@@ -771,7 +785,11 @@ public final BlobAccess getBlobAccess(String container, String key) {
771785 throw new KeyNotFoundException (container , key , "" );
772786 }
773787
774- var path = root .resolve (container ).resolve (key );
788+ var path = root .resolve (container ).resolve (key ).normalize ();
789+ if (!path .startsWith (container )) {
790+ throw new IllegalArgumentException ("Invalid key name: path traversal attempt detected." );
791+ }
792+
775793 Set <PosixFilePermission > permissions ;
776794 try {
777795 permissions = Files .getPosixFilePermissions (path );
@@ -791,7 +809,11 @@ public final void setBlobAccess(String container, String key, BlobAccess access)
791809 throw new KeyNotFoundException (container , key , "" );
792810 }
793811
794- var path = root .resolve (container ).resolve (key );
812+ var path = root .resolve (container ).resolve (key ).normalize ();
813+ if (!path .startsWith (container )) {
814+ throw new IllegalArgumentException ("Invalid key name: path traversal attempt detected." );
815+ }
816+
795817 Set <PosixFilePermission > permissions ;
796818 try {
797819 permissions = new HashSet <>(Files .getPosixFilePermissions (path ));
0 commit comments