Coordinated Disclosure Timeline

Summary

getValidDirectoryPath incorrectly treats sibling of a root directory as a child.

Product

The OWASP Enterprise Security API (ESAPI)

Tested Version

v2.2.3.1 (The latest version of “Legacy” 2.x branch as ESAPI 3.x is in early development and has no releases yet.)

Details

Issue: getValidDirectoryPath bypass (GHSL-2022-008)

parent [1] - the third parameter in getValidDirectoryPath is used to validate that the input [2] path is “inside specified parent” directory [3].

public String getValidDirectoryPath(String context, String input /* [2] */, File parent /* [1] */, boolean allowNull) throws ValidationException, IntrusionException {
...
  // [3]
	if ( !dir.getCanonicalPath().startsWith(parent.getCanonicalPath() ) ) {
		throw new ValidationException( context + ": Invalid directory name", "Invalid directory, not inside specified parent: context=" + context + ", input=" + input + ", parent=" + parent );
	}
...
}

If the result of parent.getCanonicalPath() is not slash terminated it allows for partial path traversal.

Consider "/usr/outnot".startsWith("/usr/out"). The check is bypassed although outnot is not under the out directory. The terminating slash may be removed in various places. On Linux println(new File("/var/")) returns /var, but println(new File("/var", "/")) - /var/, however println(new File("/var", "/").getCanonicalPath()) - /var.

Impact

This issue allows to break out of expected directory.

CVE

Credit

This issue was discovered and reported by GHSL team member @JarLob (Jaroslav Lobačevski).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2022-008 in any communication regarding this issue.