Contain enable_profiling path to model directory (path traversal hardening)#2273
Open
jiafatom wants to merge 2 commits into
Open
Contain enable_profiling path to model directory (path traversal hardening)#2273jiafatom wants to merge 2 commits into
jiafatom wants to merge 2 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens handling of the enable_profiling value sourced from genai_config.json to mitigate path traversal (CWE-22) by rejecting absolute paths / .. components and resolving the profiling prefix relative to the model’s config directory.
Changes:
- Added
ResolveContainedConfigPath()and applied it to the config-sourcedenable_profilingsink before callingOrt::SessionOptions::EnableProfiling(). - Added C++ regression tests ensuring traversing and absolute
enable_profilingvalues are rejected during model load.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/models/model.cpp | Adds lexical containment validation for config-sourced profiling prefix and resolves it relative to the model directory. |
| test/model_tests.cpp | Adds regression tests for rejecting traversing and absolute profiling paths from config overlays. |
The 'enable_profiling' field from genai_config.json was passed verbatim to
OnnxRuntime's EnableProfiling(), so a malicious model package could use path
traversal (e.g. '../../../etc/cron.d/ort' or a Windows Startup path) to write
ORT profiling output to arbitrary filesystem locations when the session closes.
Add defense-in-depth path containment: reject absolute paths and any
parent-directory ('..') component, and resolve the profiling prefix relative to
the model directory. The separate host-controlled runtime option
(SetRuntimeOption 'enable_profiling') is unaffected.
Add regression tests covering traversal and absolute enable_profiling paths.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
e701924 to
aed4486
Compare
…t/space Windows trims trailing dots and spaces from path components, so values like '.. ' or '...' could be interpreted as a parent/current directory and bypass the lexical '..' check. Reject any component that collapses to only dots/spaces. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
|
||
| // Validates that a path-like string from the (untrusted) model config stays | ||
| // within the model directory, then resolves it relative to that directory. | ||
| // Rejects absolute paths and any current/parent-directory (".", "..") component |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
Hardens the
enable_profilingfield ofgenai_config.jsonagainst path traversal (CWE-22).The field was read from the (untrusted) model config and passed verbatim to OnnxRuntime's
EnableProfiling():ORT writes a
<prefix>_<timestamp>.jsonprofiling file when the session closes. A malicious model package could set e.g."enable_profiling": "../../../../etc/cron.d/ort"(Linux) or a...\Startup\evilpath (Windows) to write to arbitrary locations.Fix
src/models/model.cpp: addResolveContainedConfigPath, which rejects absolute paths and any parent-directory (..) component, then resolves the profiling prefix relative to the model directory (config_->config_path). Applied at theenable_profilingsink.test/model_tests.cpp: addEnableProfilingRejectsPathTraversalandEnableProfilingRejectsAbsolutePath.The custom
fs::pathin this repo has no canonicalization primitives, so containment is enforced lexically (reject absolute +..), which is sufficient to keep the resolved path within the model directory subtree.Notes / scope
SetRuntimeOption("enable_profiling", ...),model.cpp/State::SetRunOption) is intentionally left unchanged — that path is not attacker-controlled.custom_ops_library) resolve and is the contained/expected default.custom_ops_libraryfield is a higher-value target but reflects the documented model-package trust boundary; this PR scopes to theenable_profilinghardening.Testing
New regression tests use the existing
OgaConfig::Overlaypattern ontiny-random-gpt2-fp32. Local build isn't available in my environment (root-owned build dir / jiafa-dev container needed); relying on CI to build and run the C++ unit tests.