Skip to content

fix: clean template destination path for pull #12559

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

Merged
merged 9 commits into from
Mar 14, 2024

Conversation

dannykopping
Copy link
Contributor

@dannykopping dannykopping commented Mar 12, 2024

Fixes #10281

Cleaning the path and making it absolute causes the path to not be seen as unsafe by the underlying library.

Note to reviewer: this PR obviates the need for TestTemplatePull_ToImplicit.
It made sense to me to merge them together, but you may want to keep them separate; I'm easy either way.

Side-note: I was testing to see if I could inject problematic template names like --help and ended up finding a CLI bug: #12575

@dannykopping dannykopping marked this pull request as ready for review March 13, 2024 07:52
@dannykopping dannykopping requested review from mafredri and mtojek March 13, 2024 07:53
Copy link
Member

@mtojek mtojek left a comment

Choose a reason for hiding this comment

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

LGTM, but please wait for review from Mathias 👍

}

if dest != clean {
cliui.Warn(inv.Stderr, fmt.Sprintf("cleaning destination path from %s to %s", dest, clean))
Copy link
Member

Choose a reason for hiding this comment

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

nit: I wouldn't warn users here, it the tool can fix the path then we don't need to them

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking this process of cleaning the dir might cause unexpected results, but on reflection I think you're right; I've removed it.

clean, err := filepath.Abs(filepath.Clean(dest))
if err != nil {
cliui.Error(inv.Stderr, fmt.Sprintf("cleaning destination path %s failed: %q", dest, err))
return err
Copy link
Member

Choose a reason for hiding this comment

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

Could this be an xerrors.Errorf("lookup of absolute path failed ...: %w") instead of the manual cliui error call? I'd expect the error to be printed twice this way.

dir := t.TempDir()
wd, err := os.Getwd()
require.NoError(t, err)
err = os.Chdir(dir)
Copy link
Member

Choose a reason for hiding this comment

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

How do these tests actually work with chdir removed? The files will be created inside the repo since we're not in the tmpdir, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It pulls into the givenPath:

inv, root := clitest.New(t, "templates", "pull", template.Name, tc.givenPath)

AFAICS it's functionally equivalent

Copy link
Member

@mafredri mafredri Mar 13, 2024

Choose a reason for hiding this comment

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

If the given path is relative, won't it be relative to the Go process, i.e. the test which is running in coder/cli directory? Thus it'll store files in there instead of tmp.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're correct! I added these two lines to account for that in the last commit:

			newWD := t.TempDir()
			require.NoError(t, os.Chdir(newWD))

Copy link
Member

Choose a reason for hiding this comment

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

You also need to restore the wd after the test has ended, otherwise it could break other tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oooh good point!

Copy link
Contributor Author

@dannykopping dannykopping left a comment

Choose a reason for hiding this comment

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

@mafredri @mtojek responded, thank you for your reviews!

}

if dest != clean {
cliui.Warn(inv.Stderr, fmt.Sprintf("cleaning destination path from %s to %s", dest, clean))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking this process of cleaning the dir might cause unexpected results, but on reflection I think you're right; I've removed it.

dir := t.TempDir()
wd, err := os.Getwd()
require.NoError(t, err)
err = os.Chdir(dir)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It pulls into the givenPath:

inv, root := clitest.New(t, "templates", "pull", template.Name, tc.givenPath)

AFAICS it's functionally equivalent

Copy link
Member

@mafredri mafredri left a comment

Choose a reason for hiding this comment

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

A few more things but once those are fixed I think this is good to go. Thanks for tackling this issue!

@@ -230,118 +230,111 @@ func TestTemplatePull_LatestStdout(t *testing.T) {

// ToDir tests that 'templates pull' pulls down the active template
// and writes it to the correct directory.
//
// nolint: tparallel // The subtests cannot be run in parallel; see the inner loop.
func TestTemplatePull_ToDir(t *testing.T) {
t.Parallel()
Copy link
Member

Choose a reason for hiding this comment

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

We'll need to remove this parallel now that we're doing chdir again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that this is tparallel not paralleltest.

Copy link
Member

@mafredri mafredri Mar 14, 2024

Choose a reason for hiding this comment

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

I wasn't referring to linting. A test that modifies the environment of the process (e.g. setenv or chdir) can't be parallel or have parallel ancestors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OH you're completely right!

templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
t.Cleanup(func() {
_ = os.RemoveAll(tc.givenPath)
_ = os.RemoveAll(expectedDest)
Copy link
Member

Choose a reason for hiding this comment

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

We could perhaps combine these and chdir into a single cleanup? Or perhaps even better would be to implement testutil.Chdir since it's something we do every now and a then.

},
{
name: "directory traversal is acceptable",
givenPath: "../mytmpl",
Copy link
Member

Choose a reason for hiding this comment

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

I suppose this write is outside the test tmpdir? Perhaps we should increase the depth down below (pseudo newWD := filepath.Join(t.TempDir(), "work"); mkdir(newWD))?

@dannykopping
Copy link
Contributor Author

dannykopping commented Mar 14, 2024

@mafredri I took a slightly different approach in 9d035e3 which is a bit cleaner. Please let me know what you think.

Signed-off-by: Danny Kopping <danny@coder.com>
Signed-off-by: Danny Kopping <danny@coder.com>
Signed-off-by: Danny Kopping <danny@coder.com>
Signed-off-by: Danny Kopping <danny@coder.com>
…s broke a test

Signed-off-by: Danny Kopping <danny@coder.com>
Signed-off-by: Danny Kopping <danny@coder.com>
@dannykopping dannykopping force-pushed the dk/template-pull-path branch from cda50fc to 9d035e3 Compare March 14, 2024 08:51
Signed-off-by: Danny Kopping <danny@coder.com>
cleanup; t.Cleanup is ordered by last-added-first-called.

Signed-off-by: Danny Kopping <danny@coder.com>
Copy link
Member

@mafredri mafredri left a comment

Choose a reason for hiding this comment

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

Found one last simplification, but otherwise LGTM! 😄

Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
@dannykopping dannykopping enabled auto-merge (squash) March 14, 2024 12:34
@dannykopping dannykopping merged commit 14130de into coder:main Mar 14, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Mar 14, 2024
@dannykopping dannykopping deleted the dk/template-pull-path branch March 14, 2024 12:59
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The coder template pull command fails with a relative path starting with .
3 participants