Skip to content
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 recent security fixes if JENKINS_HOME is a symlink and update tests for compatibility with Windows and Git plugin 4.10.3 #139

Merged
merged 2 commits into from
Feb 17, 2022

Conversation

dwnusbaum
Copy link
Member

@dwnusbaum dwnusbaum commented Feb 16, 2022

The tests for security fixes for https://www.jenkins.io/security/advisory/2022-02-15/ fail against recent version of Git plugin due to jenkinsci/git-plugin#1207, and also fail when running on Windows due to a difference in the behavior.

The fix itself also did not allow JENKINS_HOME to be a symlink, because it compared a canonical path to an absolute path.

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

@dwnusbaum dwnusbaum added the bug label Feb 16, 2022
@@ -256,7 +256,7 @@
for (LibraryRecord library : action.getLibraries()) {
FilePath libResources = libs.child(library.getDirectoryName() + "/resources/");
FilePath f = libResources.child(name);
if (!new File(f.getRemote()).getCanonicalFile().toPath().startsWith(libResources.absolutize().getRemote())) {
if (!new File(f.getRemote()).getCanonicalFile().toPath().startsWith(new File(libResources.getRemote()).getCanonicalPath())) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only intended difference here is that if JENKINS_HOME is a symlink, the code should no longer throw an exception in non-dangerous scenarios.

@dwnusbaum dwnusbaum changed the title Update tests for recent security fixes for compatibility with Windows and Git plugin 4.10.3 Fix recent security fixes if JENKINS_HOME is a symlink and update tests for compatibility with Windows and Git plugin 4.10.3 Feb 16, 2022
@@ -256,7 +256,7 @@
for (LibraryRecord library : action.getLibraries()) {
FilePath libResources = libs.child(library.getDirectoryName() + "/resources/");
FilePath f = libResources.child(name);
if (!new File(f.getRemote()).getCanonicalFile().toPath().startsWith(libResources.absolutize().getRemote())) {
if (!new File(f.getRemote()).getCanonicalFile().toPath().startsWith(new File(libResources.getRemote()).getCanonicalPath())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!new File(f.getRemote()).getCanonicalFile().toPath().startsWith(new File(libResources.getRemote()).getCanonicalPath())) {
if (!new File(f.getRemote()).getCanonicalFile().toPath().startsWith(new File(libResources.getRemote()).getCanonicalFile().toPath())) {

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though even better is to use NIO fully:

Suggested change
if (!new File(f.getRemote()).getCanonicalFile().toPath().startsWith(new File(libResources.getRemote()).getCanonicalPath())) {
if (!Paths.get(f.getRemote()).toRealPath().startsWith(Paths.get(libResources.getRemote()).toRealPath())) {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path.toRealPath throws if the path does not exist on the file system, so we would have to change things a bit more if we wanted to keep attackers from being able to probe the existence of files using symlinks.

Is there a meaningful difference between Path.startsWith(String) and Path.startsWith(Path)? They both return false for things like foo/bar starting with f.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path.toRealPath throws if the path does not exist on the file system

Mm, I see. So there is no NIO equivalent to File.getCanonicalPath?

Is there a meaningful difference

I do not know.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mm, I see. So there is no NIO equivalent to File.getCanonicalPath?

Not directly as far as I know. I did consider using NIO in the original patch and catching NoSuchFileException so that error messages would be the same regardless of file existence, but it seemed simpler to use getCanonicalFile.

I do not know.

Ok, I just wasn't sure if it was a style-related suggestion or if I was missing an important detail. As far as I know the current code with Path.startsWith(f.getCanonicalPath()) and the proposed code with Path.startsWith(f.getCanonicalFile().toPath()) should have the same behavior.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably. The weird corner cases are likely to be on Windows. I think the current code is secure and likely to fix the regression for most if not all users.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks for elaborating. I'll merge the code as-is and will follow up as needed.

@dwnusbaum dwnusbaum merged commit e62a4eb into jenkinsci:master Feb 17, 2022
@dwnusbaum dwnusbaum deleted the security-fix-test-compatibility branch February 17, 2022 15:54
daniel-beck pushed a commit that referenced this pull request Apr 12, 2022
Fix recent security fixes if JENKINS_HOME is a symlink and update tests for compatibility with Windows and Git plugin 4.10.3

(cherry picked from commit e62a4eb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants