-
Notifications
You must be signed in to change notification settings - Fork 492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: protect read file from path traversal #4943
base: master
Are you sure you want to change the base?
Conversation
…oject's root path
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
366a8ac
to
a4c89ba
Compare
@mtsgrd some small rust question:
|
a4c89ba
to
25dcaac
Compare
9339384
to
a344d6a
Compare
Features are predefined in the crate and they usually only provide features if it grates off other dependencies, not just code. When I see the example above, it reminds me of typescript imports :). |
e921c44
to
e0c6118
Compare
fn read_file_from_workspace(&self, relative_path: &Path) -> Result<String> { | ||
let ctx = CommandContext::open(self)?; | ||
let base_path = ctx | ||
.repository() | ||
.path() | ||
.parent() | ||
.ok_or(anyhow::anyhow!("Could not find repository base path"))?; | ||
|
||
let canonicalized_file_path = base_path.join(relative_path).canonicalize()?; | ||
|
||
if canonicalized_file_path.as_path().starts_with(base_path) { | ||
let tree = ctx.repository().head()?.peel_to_tree()?; | ||
let entry = tree.get_path(relative_path)?; | ||
let blob = ctx.repository().find_blob(entry.id())?; | ||
let content = std::str::from_utf8(blob.content())?; | ||
|
||
Ok(content.to_string()) | ||
} else { | ||
anyhow::bail!("Invalid workspace file"); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nit, the path()
function may return the repository path rather than the .git
folder if the repository is bare. If we had a repository that was bare, that would mean that it could access files outside the repository.
fn read_file_from_workspace(&self, relative_path: &Path) -> Result<String> { | |
let ctx = CommandContext::open(self)?; | |
let base_path = ctx | |
.repository() | |
.path() | |
.parent() | |
.ok_or(anyhow::anyhow!("Could not find repository base path"))?; | |
let canonicalized_file_path = base_path.join(relative_path).canonicalize()?; | |
if canonicalized_file_path.as_path().starts_with(base_path) { | |
let tree = ctx.repository().head()?.peel_to_tree()?; | |
let entry = tree.get_path(relative_path)?; | |
let blob = ctx.repository().find_blob(entry.id())?; | |
let content = std::str::from_utf8(blob.content())?; | |
Ok(content.to_string()) | |
} else { | |
anyhow::bail!("Invalid workspace file"); | |
} | |
} | |
fn read_file_from_workspace(&self, relative_path: &Path) -> Result<String> { | |
let ctx = CommandContext::open(self)?; | |
let repository = ctx.repository(); | |
// If a repostiory is bare, repository.path will return the repository | |
// directory rather than the `.git` repository. | |
// Ref: https://docs.rs/git2/latest/git2/struct.Repository.html#method.path | |
let base_path = if repository.is_bare() { | |
repository.path() | |
} else { | |
repository | |
.path() | |
.parent() | |
.ok_or(anyhow::anyhow!("Could not find repository base path"))? | |
}; | |
let canonicalized_file_path = base_path.join(relative_path).canonicalize()?; | |
if canonicalized_file_path.as_path().starts_with(base_path) { | |
let tree = repository.head()?.peel_to_tree()?; | |
let entry = tree.get_path(relative_path)?; | |
let blob = repository.find_blob(entry.id())?; | |
let content = std::str::from_utf8(blob.content())?; | |
Ok(content.to_string()) | |
} else { | |
anyhow::bail!("Invalid workspace file"); | |
} | |
} |
I wonder if we should name the function something like read_commited_file
or something like that, to make it clear that its not going to look at uncommitted changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I've overcomplicating it, we have the project, so we should be able to just use self.path
with no faffing about 😆
☕️ Reasoning
get_pr_template_contents
fn can't read anything outside of the project's root directory🧢 Changes