Overview
Several security and stability issues have been identified in the current
downloadSelectedArtifactsAsZip.groovy plugin. A hardened version of the
file is available and ready to replace it.
Issues found
🔴 Path Traversal / ZIP Slip (High)
The sanitize() function uses simple string replacement (replace('../', ''))
which can be bypassed with sequences like ....//. An attacker could craft
malicious paths to write files outside the intended ZIP structure.
Suggested fix: Use Paths.get(name).normalize() (Java NIO) before any
further checks.
🔴 Unbounded Memory Usage / DoS (High)
The entire ZIP is built in a ByteArrayOutputStream held in memory before
being sent to the client. A request with many or large files could exhaust
heap memory on the Artifactory server.
Suggested fix: Stream the ZIP directly to the response output stream.
🟡 No Input Limits (Medium)
- No cap on the number of files per request.
- No limit on individual file size or total bundle size.
- No limit on request body size.
Suggested fix: Enforce limits such as max files, max single file size,
max total bundle size, and max request body size.
🟡 Folder Download Not Prevented (Medium)
The plugin does not verify whether a resolved path is a file or a directory.
Suggested fix: Check fileInfo.folder and skip directories.
🟢 Duplicate ZIP Entries (Low / Correctness)
Two patterns resolving to the same ZIP entry name produce a corrupt archive.
Suggested fix: Deduplicate entry names by appending a numeric suffix.
🟢 Internal Error Message Leaked to Client (Low)
e.message is returned verbatim to the caller on parse errors, potentially
leaking internal server details.
Suggested fix: Return a generic error message and log the detail
server-side only.
Proposed resolution
A corrected version of the plugin has been developed and is attached
to this issue (downloadSelectedArtifactsAsZip.txt).
It addresses all the issues described above and is ready to be reviewed
and merged.
downloadSelectedArtifactsAsZip.txt
Overview
Several security and stability issues have been identified in the current
downloadSelectedArtifactsAsZip.groovyplugin. A hardened version of thefile is available and ready to replace it.
Issues found
🔴 Path Traversal / ZIP Slip (High)
The
sanitize()function uses simple string replacement (replace('../', ''))which can be bypassed with sequences like
....//. An attacker could craftmalicious paths to write files outside the intended ZIP structure.
Suggested fix: Use
Paths.get(name).normalize()(Java NIO) before anyfurther checks.
🔴 Unbounded Memory Usage / DoS (High)
The entire ZIP is built in a
ByteArrayOutputStreamheld in memory beforebeing sent to the client. A request with many or large files could exhaust
heap memory on the Artifactory server.
Suggested fix: Stream the ZIP directly to the response output stream.
🟡 No Input Limits (Medium)
Suggested fix: Enforce limits such as max files, max single file size,
max total bundle size, and max request body size.
🟡 Folder Download Not Prevented (Medium)
The plugin does not verify whether a resolved path is a file or a directory.
Suggested fix: Check
fileInfo.folderand skip directories.🟢 Duplicate ZIP Entries (Low / Correctness)
Two patterns resolving to the same ZIP entry name produce a corrupt archive.
Suggested fix: Deduplicate entry names by appending a numeric suffix.
🟢 Internal Error Message Leaked to Client (Low)
e.messageis returned verbatim to the caller on parse errors, potentiallyleaking internal server details.
Suggested fix: Return a generic error message and log the detail
server-side only.
Proposed resolution
A corrected version of the plugin has been developed and is attached
to this issue (
downloadSelectedArtifactsAsZip.txt).It addresses all the issues described above and is ready to be reviewed
and merged.
downloadSelectedArtifactsAsZip.txt