Security hardening: medium-severity fixes#612
Merged
mehmetozguldev merged 8 commits intoathasdev:masterfrom Apr 16, 2026
Merged
Security hardening: medium-severity fixes#612mehmetozguldev merged 8 commits intoathasdev:masterfrom
mehmetozguldev merged 8 commits intoathasdev:masterfrom
Conversation
The previous allowlist used host.ends_with("athas.dev"), which also matched
hostnames like evilathas.dev because the suffix check did not require a
leading dot. An attacker who can register such a domain could serve a
malicious extension bundle that download_extension and
install_extension_from_url would accept.
Tighten the check to host == "athas.dev" || host.ends_with(".athas.dev"),
and add a regression test covering evilathas.dev, bare athas.dev, and
cdn.athas.dev.
extract_tar_gz manually joined each tar entry's relative path onto the target directory without rejecting ".." components, while Path::join does not normalize traversal. A tampered or malicious mirror of nodejs.org could ship a tar entry whose resolved path escapes the runtime install directory, writing arbitrary files including executables during install. Stage the archive in a tempdir, unpack each entry via tar::Entry::unpack_in which rejects unsafe paths, then promote the single wrapper directory into target_dir. This matches the pattern already used by the extensions and tool installers. Add a regression test that constructs a two-step symlink tar-slip and confirms extraction fails before any payload escapes the staging dir.
download_binary previously fetched whatever URL a ToolConfig supplied, with no scheme or host checks and no size limit, then wrote the result into tools_dir/bin and marked it executable. Because ToolConfig flows through the install_language_tools IPC command, this was a frontend-to-RCE primitive if any untrusted input ever reached the tool config path. Require HTTPS URLs, allow http://localhost only in debug builds, cap the download at 100 MB using both the Content-Length hint and a running counter over the streamed body, and surface failures as typed ToolError::DownloadFailed. Add unit tests for the URL validator covering non-HTTPS schemes, localhost in debug, and the happy path.
Capture the full security audit in SECURITY-REVIEW.md: severity rubric, findings table, and details for the three high-severity fixes applied in this branch plus medium and low items tracked for follow-up.
ssh_create_file, ssh_rename_path, and ssh_copy_path built remote commands like `mkdir -p $(dirname 'target')` where the single-quoted argument was safe inside dirname, but the outer command substitution was unquoted. dirname's output does not contain shell metacharacters in normal use, but an unusual remote path (spaces, glob characters) could produce an argv mismatch or unintended word-splitting in the outer mkdir. Wrap each command substitution in double quotes so mkdir always receives a single argument regardless of the resolved directory name.
format_code and lint_code accept a FormatterConfig or LinterConfig over IPC whose command, args, and env values are passed straight through to std::process::Command. The frontend is trusted in the current threat model, but a malicious or mis-configured extension could previously supply an absolute path to a surprise binary, a relative path resolved against the editor's CWD, or an LD_PRELOAD-style environment override that hijacks the child process. Add a shared exec_guard module that rejects commands containing ".." or relative path separators while allowing bare names (looked up via PATH) and explicit absolute paths, and rejects environment variables known to redirect the dynamic linker or library search path on Linux and macOS (LD_PRELOAD, LD_LIBRARY_PATH, LD_AUDIT, LD_DEBUG, DYLD_*, and PATH itself). The check is case-insensitive to cover Windows conventions. Wire the guard into format_with_generic and lint_with_generic so invalid configs fail fast with a typed error before any template substitution or process spawn happens.
open_file_external, get_symlink_info, rename_file, and move_file call std::fs and std::process directly and therefore bypass Tauri's fs:scope capability. That capability is configured as $HOME/** in capabilities/main.json, so any path the frontend hands to these commands could previously operate on system locations (for example /etc/passwd) or, in the case of open_file_external on Linux, be interpreted by xdg-open as a URL and delegated to the system handler. Add a small path_guard module with two helpers. require_path_under_home canonicalizes the input (or its parent for not-yet-existing targets) and rejects anything outside the canonicalized $HOME, so symlinks pointing out of the workspace are caught. require_symlink_container_under_home checks the parent directory only, which keeps get_symlink_info able to report on symlinks inside $HOME whose target is elsewhere. Wire both helpers into fs.rs so every path argument goes through the guard before reaching the filesystem or the platform opener. Include regression tests for acceptance inside $HOME, rejection outside $HOME, and rejection of symlinks that escape $HOME.
mehmetozguldev
approved these changes
Apr 16, 2026
Contributor
Author
|
The power of Opus 4.7 LOL |
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.
This PR implements the remaining medium-severity security hardening tasks (M1, M2, M5) following the high-severity fixes already merged.
Changes
M5 - Quote dirname substitutions in SSH shell helpers
M2 - Sanitize formatter/linter command and environment variables
M1 - Confine custom fs IPC commands to home directory
Verification