Coordinated Disclosure Timeline
- 2022-01-07: Report sent to security at apache.org.
- 2022-01-09: Receipt acknowledged.
- 2022-01-09: Issue fixed in the main branch.
- 2022-01-14: v4.3.6 and v4.2.15 with the fix were released.
Summary
Partial path traversal allows to break out of expected folder.
Product
Apache Karaf
Tested Version
Latest revision dc8617af34b64b0dac52d7e337bd22dd6e21b60f on Linux
Details
Issue 1: Partial path traversal in FileUtil.java (GHSL-2022-005
)
unjar
in FileUtil.java
validates [1] if the target file path starts with the expected dir
[2].
public static void unjar(JarInputStream jis, File dir) //<----------- [2]
throws IOException
{
...
File target = new File(dir, je.getName());
if (!target.getCanonicalPath().startsWith(dir.getCanonicalPath())) { //<----------- [1]
throw new IOException("JAR resource cannot contain paths with .. characters");
}
...
getCanonicalPath
transforms the path into a canonical form preventing such attack types as ..
in path segments. If the result of dir.getCanonicalPath()
is not slash terminated it allows for partial path traversal.
Consider "/usr/outnot".startsWith("/usr/out")
. The check is bypassed although it is not 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 folder.
Issue 2: Partial path traversal in maven plugin (GHSL-2022-006
)
extract
in RunMojo.java
validates [1] if the file path starts with the expected targetDir
[2].
private static void extract(ArchiveInputStream is, File targetDir) throws IOException { //<----------- [2]
...
String name = entry.getName();
name = name.substring(name.indexOf("/") + 1);
File file = new File(targetDir, name);
if (!file.getCanonicalPath().startsWith(targetDir.getCanonicalPath())) { //<----------- [1]
throw new IOException("Archive cannot contain paths with .. characters");
}
...
getCanonicalPath
transforms the path into a canonical form preventing such attack types as ..
in path segments. If the result of targetDir.getCanonicalPath()
is not slash terminated it allows for partial path traversal.
Consider "/usr/outnot".startsWith("/usr/out")
. The check is bypassed although it is not 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 folder.
CVE
- CVE-2022-22932
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-005
or GHSL-2022-006
in any communication regarding this issue.