Skip to content

Path Validation Fails on Non-Existent Files #219

@sfloess

Description

@sfloess

Bug Description

The validatePathTraversal method in FileUtil.java calls path.toRealPath() which throws NoSuchFileException if the path doesn't exist. This breaks legitimate use cases where path validation is needed before file creation.

Severity

High - This affects a security-critical method for path traversal protection.

Location

File: src/main/java/org/flossware/commons/util/FileUtil.java:78

Current Behavior

final Path realPath = path.toRealPath();
final Path realBase = baseDirectory.toRealPath();

The toRealPath() method requires the file to exist on the filesystem. If it doesn't exist, it throws a NoSuchFileException, which is caught and wrapped in a FileException.

Problem

This design prevents the method from being used in scenarios where:

  • A path needs to be validated before creating a new file
  • The path doesn't exist yet but needs to be checked for traversal attacks
  • Callers want to ensure a future file creation would be safe

Impact

Severity: High

This is a security-critical method for preventing path traversal attacks (CWE-22), but its current implementation limits its usefulness in common use cases.

Suggested Fix

Consider one of the following approaches:

  1. Use normalize() for non-existent paths:

    final Path realPath = Files.exists(path) ? path.toRealPath() : path.normalize().toAbsolutePath();
    final Path realBase = baseDirectory.toRealPath();
  2. Document the requirement:
    Add clear JavaDoc stating that the path must exist, and provide a separate method for validating non-existent paths.

  3. Handle non-existent paths gracefully:
    Use a hybrid approach that validates what exists and normalizes what doesn't.

Related

  • Security feature: Path traversal protection (CWE-22)
  • See CLAUDE.md security requirements

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions