fix: Implement path validation, rate limiting and Input safety across core modules #2587
+110
−21
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary of Changes
This pull request addresses several security vulnerabilities in the
linode/apl-core
project, focusing on improving path safety, rate limiting, and input validation to prevent denial-of-service (DoS) and path traversal attacks.The changes enhance the reliability and security of multiple modules, particularly
server.ts
,crypt.ts
,utils.ts
, andrepo.ts
, by ensuring that all file system and input operations are properly constrained and validated.Rate Limiting for
/prepare
Route (src/server.ts)The
/prepare
route performs potentially expensive file operations without limiting the number of incoming requests. This allows attackers to flood the endpoint and cause resource exhaustion (DoS).Fix:
/prepare
route.app.get('/prepare', limiter, ...)
.This ensures that excessive or abusive request patterns are throttled effectively.
Validation of Untrusted
.length
Property (src/common/crypt.ts)Using
.length
on untrusted input (filesArgs
) could lead to unbounded iteration if a malicious object defines an excessively large or invalid.length
value.Fix:
filesArgs
is a genuine array..length
is a finite, non-negative integer and below a defined safe threshold (e.g.,MAX_FILES = 1000
).getAllSecretFiles()
results are also validated to prevent massive file enumeration.This prevents potential denial-of-service attacks through loop-bound injection.
Path Traversal Protection (src/server.ts, src/common/utils.ts, src/common/repo.ts, src/common/crypt.ts)
Multiple functions construct or access file paths based on user-supplied input (
envDir
, directory paths, etc.) without ensuring they remain inside a safe root directory. This can allow path traversal and unauthorized access to sensitive files.Fixes Implemented Across Files:
a. server.ts
path.resolve
.copyFile
).403 Forbidden
response when invalid paths are detected.b. common/utils.ts
readdirRecurse
to verify that the target directory remains withinrootDir
or another predefined sandbox.c. common/repo.ts
Added a secure root constant (e.g.,
const ROOT = path.resolve('/var/data')
).Updated all functions using
envDir
(unsetValuesFile
,setValuesFile
,unsetValuesFileSync
) to:ROOT
before accessing the file system.Prevented traversal beyond the designated directory hierarchy.
d. common/crypt.ts
path.resolve()
andfs.realpathSync()
to prevent both directory traversal and symbolic link manipulation.These combined fixes ensure that all filesystem interactions are constrained within trusted boundaries, effectively eliminating path traversal risks.
.length
properties.Technical References
🧹 Checklist