govind-gupta-tfs commented on PR #553:
URL: https://github.com/apache/commons-io/pull/553#issuecomment-3380782150

   `package com.thermofisher.gsd.archive;
   
   import org.apache.commons.lang3.Validate;
   import java.net.URLDecoder;
   import java.nio.charset.StandardCharsets;
   import java.nio.file.InvalidPathException;
   import java.nio.file.Path;
   import java.util.Locale;
   import java.util.Set;
   
   public class PathValidator {
   
       private static final Set<String> RESERVED_NAMES = Set.of(
               "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", 
"COM5", "COM6",
               "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", 
"LPT6",
               "LPT7", "LPT8", "LPT9"
       );
   
       public static void validateSafePathComponent(String component) {
           // --- 1. Basic Checks (Using Apache Commons Lang) ---
           Validate.notBlank(component, "Path component must not be blank");
           Validate.isTrue(component.length() <= 255, "Path component too 
long");
   
           // Pre-decode raw dangerous percent encodings
           String lower = component.toLowerCase(Locale.ROOT);
           if (lower.contains("%2f") || lower.contains("%5c") || 
lower.contains("%00")) {
               throw new IllegalArgumentException("Encoded separator/null not 
allowed: " + component);
           }
   
           // --- 2. Decoding ---
           String decoded;
           try {
               decoded = URLDecoder.decode(component, StandardCharsets.UTF_8);
           } catch (IllegalArgumentException ex) {
               throw new IllegalArgumentException("Invalid percent encoding: " 
+ component);
           }
   
           // --- 3. Path Traversal/Normalization Check (Using Path API) ---
           Path p;
           try {
               p = Path.of(decoded);
           } catch (InvalidPathException e) {
               throw new IllegalArgumentException("Invalid path syntax: " + 
component);
           }
   
           // Critical Path Traversal check: must be a single name and not 
contain '..' or '.'
           if (p.isAbsolute() || p.getNameCount() != 1 || 
!p.normalize().equals(p)) {
               throw new IllegalArgumentException("Traversal/dot segments or 
absolute path not allowed: " + component);
           }
   
           String name = p.getFileName().toString();
   
           // --- 4. Final Name/Custom Policy Checks ---
   
           // Basic character / separator checks
           if (name.contains("/") || name.contains("\\") || name.indexOf('\0') 
>= 0 || name.contains("+")) {
               throw new IllegalArgumentException("Unsafe characters 
(separators/null/plus): " + component);
           }
   
           // Control chars
           for (int i = 0; i < name.length(); i++) {
               char c = name.charAt(i);
               if (c < 0x20 || c == 0x7F) {
                   throw new IllegalArgumentException("Control character 
present: " + component);
               }
           }
   
           // Dot-only or reserved dot forms & Trailing space/dot
           if (name.equals(".") || name.equals("..") || name.matches("\\.{2,}") 
||
                   name.endsWith(" ") || name.endsWith(".")) {
               throw new IllegalArgumentException("Invalid dot sequence or 
trailing space/dot: " + component);
           }
   
           // Allowlist
           if (!name.matches("[A-Za-z0-9._-]+")) {
               throw new IllegalArgumentException("Disallowed characters: " + 
component);
           }
   
           // Windows reserved device names
           if (RESERVED_NAMES.contains(name.toUpperCase(Locale.ROOT))) {
               throw new IllegalArgumentException("Reserved device name: " + 
component);
           }
       }
   }`
   
   
   @garydgregory  can we use the above code to avoid path injection in user 
provided paths in windows machine. 
   It can further be optimized for other OS


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to