security: harden PAGER execution by switching from shell invocation to execvp#653
Open
Devansh-567 wants to merge 1 commit into
Open
security: harden PAGER execution by switching from shell invocation to execvp#653Devansh-567 wants to merge 1 commit into
Devansh-567 wants to merge 1 commit into
Conversation
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.
The Problem
The existing implementation in
src/utils/pager.ccevaluates the user-definedPAGERenvironment variable by constructing a shell command string and invoking it via standard shell execution:Invoking an arbitrary command through
sh -cintroduces serious security risks, specifically command injection vulnerabilities, if thePAGERvariable contains malicious shell metacharacters.Furthermore, the existing codebase lacked robust handling for completely valid, whitespace-containing
PAGERenvironment configurations (e.g., passing flags likePAGER="less -R"). This configuration would break or evaluate incorrectly. Finally, edge cases in string matching resulted in a potential boundary crash onpager.substr()and false-positive hits for user UI hints if an absolute binary path contained the substringlessaccidentally (e.g.,/usr/bin/headless-viewer).The Solution
This patch systematically modernizes and hardens the application's process execution mechanism:
- Swapped Shell Invocations for `execvp`: Bypassed the shell interpreter (`sh -c`) entirely. Arguments are now cleanly isolated and treated strictly as data arrays via an explicit vector of string pointers (`argv`).
- Safe Input Tokenization: Integrated `std::istringstream` parsing to split user runtime variables into clean tokens. This gracefully supports arbitrary user-defined operational flags (like `less -X -R`) without opening arbitrary evaluation holes.
- Isolated UI Hint Logic: Refactored `show_text_in_pager` and `show_file_in_pager` to parse and extract the primary executable binary name before matching layout hints. This mitigates substring collisions on flags and paths.
- Resiliency Bug Fixes: Added defensive checks ensuring `pager.size() >= 4` before calling `substr()` to completely avoid out-of-bounds execution termination, and fixed a minor typo in the codebase (`navigaion -> navigation`).
---How the Problem Was Found
The issue was identified during a static code analysis pass focusing on system safety boundaries and unsafe process invocations within the utility wrappers (
src/utils/pager.cc). Reviewing the string construction line:revealed that reliance on string interpolation directly tied to user environment blocks bypassed programmatic sanitization boundaries, exposing downstream system environments to arbitrary variable expansion or argument manipulation.
Change Scope Summary