Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Quote URLs in Repo.clone_from()#1516

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

s-t-e-v-e-n-k
Copy link
Contributor

Since the URL is passed directly to git clone, and the remote-ext helper will happily execute shell commands, so by default qoute URLs unless a (undocumented, on purpose) kwarg is passed. (CVE-2022-24439)

Fixes#1515

sagarvora reacted with thumbs up emojiayush-shah reacted with heart emoji
Copy link
Member

@ByronByron left a comment

Choose a reason for hiding this comment

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

Thanks a lot, much appreciated. I don't know why quoting the URL prevents it from being effective when theext protocol is allowed. There seem to be no internal quotes in the 'ext:…' url that would be quoted then.

In any case, I think it would be useful to have a test for theunsafe_protocols feature. My intuition here is also to document it to allow folks to bypass the quoting in case they relied on using theext protocol.

Regrading CI, I have a feeling that the python action doesn't support older versions anymore - please feel free to remove them from the test suite so there is a chance for the tests to succeed.

@s-t-e-v-e-n-k
Copy link
ContributorAuthor

Quoting removes URL unsafe characters, such as spaces, so we end up with:

>>> import tempfile>>> import urllib.parse>>> import uuid>>> bad_filename = f'{tempfile.gettempdir()}/{uuid.uuid4()}'>>> bad_url = f'ext::sh -c touch% {bad_filename}'>>> urllib.parse.quote(bad_url)'ext%3A%3Ash%20-c%20touch%25%20/tmp/280b1b72-b764-424e-aaf9-f1496b5e253d'

which will not execute. Successfully, anyway -- and should also leave most of the usual suspects https:// and git:// alone, but I will confirm when I fix up GitHub Actions.

@s-t-e-v-e-n-k
Copy link
ContributorAuthor

I may have to parse it and then quote the host portion, depending on if it's overzealous, but I have it in hand. I will also add a test forunsafe_protocols.

Byron reacted with thumbs up emoji

@s-t-e-v-e-n-ks-t-e-v-e-n-kforce-pushed thequote-clone-urls-by-default branch 2 times, most recently froma3bc689 to0cd4e4dCompareDecember 15, 2022 04:59
@s-t-e-v-e-n-k
Copy link
ContributorAuthor

@Byron Sadly, I've had to change this around to not quote, but this is ready for another look.

@stsewd
Copy link
Contributor

stsewd commentedDec 15, 2022
edited
Loading

In#1515 (comment) there is this case that should be fixed too

fromgitimportRepor=Repo.init('',bare=True)r.clone('foo','/tmp/foo',multi_options=['--upload-pack="touch /tmp/pwn"'])

Here the URL can be anything. We could check/ban the unsafe options (--upload-pack/-c protocol.*) instead of (or in addition of) checking the protocol.

EDIT: This also works

r.clone('--upload-pack=touch /tmp/pwn')

@s-t-e-v-e-n-k
Copy link
ContributorAuthor

This is sort of the problem -- git isdesigned to run arbitrary commands. However, I'll see if I can refactor the checks out to a function.

Copy link
Member

@ByronByron left a comment

Choose a reason for hiding this comment

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

Thanks a lot for your help with CI!

I have a few comments and questions that I hope we can sort out quickly so we can get this PR merged and cut a new release right after that.

Thank you for your continued help.

:param kwargs: see the ``clone`` method
:return: Repo instance pointing to the cloned directory"""
git = cls.GitCommandWrapperType(os.getcwd())
if env is not None:
git.update_environment(**env)
if not unsafe_protocols and "::" in url:
Copy link
Member

Choose a reason for hiding this comment

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

Could we factor"::" in url out into its own publicly available and documented function to allow it to be used before trying to clone as well? Furthermore, this would allow to run unit-tests against it which I'd love to see. Particularly, are there ways to get false positives for legitimate cases, or false negatives in case the url is obfuscated somehow? My intuition here is thaturl.startswith('ext::') might reduce false positives, but specific tests should help find the sweet spot.

It would be interesting to find out if a url like ext::… (note the leading whitespace) also works. I'd guess it won't work as the command invocation doesn't use a shell by default. If that's indeed the case, one could make the url check more specific.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Indeed, and we probably should -- if other cases come up, we can add them there.

Byron reacted with thumbs up emoji
:param kwargs: see the ``clone`` method
:return: Repo instance pointing to the cloned directory"""
git = cls.GitCommandWrapperType(os.getcwd())
if env is not None:
git.update_environment(**env)
if not unsafe_protocols and "::" in url:
raise ValueError(f"{url} requires unsafe_protocols flag")
Copy link
Member

Choose a reason for hiding this comment

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

Is there a more specific error type that could be used to better classify the issue? MaybeValueError is already specific enough compared to the errors that are usually thrown from this function (but I don't know).

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I'm happy to add a UnsafeOptionsException or something similar, but ValueError is described as when a function receives an argument that has the right type but an inappropriate value, which feels right too?

Copy link
Member

Choose a reason for hiding this comment

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

In this particular case, having something uniquely identifiable as this particular error is probably helpful for folks who would use it to learn about the kind of URLs thrown at them. ValueError might be unique enough, but it's hard to prove it can't be raised elsewhere either.

Choose a reason for hiding this comment

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

random 2 cents from a random guy: If I was using a library and it found some dangerous input, I would prefer to have an exception that clearly says so

While ValueError fits the description, adding the "this is can be dangerous" bit would help I think

@s-t-e-v-e-n-ks-t-e-v-e-n-kforce-pushed thequote-clone-urls-by-default branch from0cd4e4d toe526cbbCompareDecember 20, 2022 06:14
Since the URL is passed directly to git clone, and the remote-ext helperwill happily execute shell commands, so by default disallow URLs thatcontain a "::" unless a new unsafe_protocols kwarg is passed.(CVE-2022-24439)Fixesgitpython-developers#1515
With a large number of the versions of Python specified not beingsupported with GitHub Actions, trim it down to the major versions, andadd in 3.11 for good measure.
@s-t-e-v-e-n-ks-t-e-v-e-n-kforce-pushed thequote-clone-urls-by-default branch frome526cbb toce529b9CompareDecember 20, 2022 06:42
Copy link
Member

@ByronByron left a comment

Choose a reason for hiding this comment

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

Thanks a lot for taking it to the next level, I love the additional tests for what constitutes unsafe options.

I thinkthe CI failure is legit as the sanity check is done in a way that assumes a string even thoughPosixPath isn't particularly string like.

Something I am not so sure about is if this PR should try to address#1517, and I'd clearly prefer that to happen in another PR. Probably@stsewd could provide valuable feedback here as well.

Thanks for taking another look.

stsewd added a commit to stsewd/GitPython that referenced this pull requestDec 21, 2022
Add `--` in some commands that receive user inputand if interpreted as options could lead to remotecode execution (RCE).There may be more commands that could benefit from `--`so the input is never interpreted as an option,but most of those aren't dangerous.For anyone using GitPython and exposing any of the GitPython methods to users,make sure to always validate the input (like if starts with `--`).And for anyone allowing users to pass arbitrary options, be awarethat some options may lead fo RCE, like `--exc`, `--upload-pack`,`--receive-pack`, `--config` (gitpython-developers#1516).Refgitpython-developers#1517
stsewd added a commit to stsewd/GitPython that referenced this pull requestDec 21, 2022
Add `--` in some commands that receive user inputand if interpreted as options could lead to remotecode execution (RCE).There may be more commands that could benefit from `--`so the input is never interpreted as an option,but most of those aren't dangerous.Fixed commands:- push- pull- fetch- clone/clone_from and friends- archive (not sure if this one can be exploited, but it doesn't hurt  adding `--` :))For anyone using GitPython and exposing any of the GitPython methods to users,make sure to always validate the input (like if starts with `--`).And for anyone allowing users to pass arbitrary options, be awarethat some options may lead fo RCE, like `--exc`, `--upload-pack`,`--receive-pack`, `--config` (gitpython-developers#1516).Refgitpython-developers#1517
@stsewdstsewd mentioned this pull requestDec 21, 2022
stsewd added a commit to stsewd/GitPython that referenced this pull requestDec 21, 2022
Copy link
Contributor

@stsewdstsewd left a comment

Choose a reason for hiding this comment

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

Taking a look at this, if gitpython is going to disallow passing the--upload-pack/--receive-pack and friends as options, the check should probably be in all other commands where those options are allowed (and should also check for their short form-u).

And reading fromhttps://git-scm.com/docs/gitremote-helpers

A URL of the form<transport>::<address> explicitly instructs Git to invokegit remote-<transport> with<address> as the second argument. If such a URL is encountered directly on the command line, the first argument is<address>, and if it is encountered in a configured remote, the first argument is the name of that remote.

Maybe is safer to disallowfoo::bar like URLs,

Byron reacted with heart emoji
Comment on lines +1302 to +1303
if not unsafe_protocols and cls.unsafe_options(url, multi_options):
raise UnsafeOptionsUsedError(f"{url} requires unsafe_protocols flag")
Copy link
Contributor

Choose a reason for hiding this comment

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

these checks could probably be moved to the_clone() method, so you don't need to add them everywhere where that is called.

@Byron
Copy link
Member

Thanks for your help!

Due to the time-sensitive nature,#1521 was merged first and includes the changes from this PR.

@ByronByron closed thisDec 29, 2022
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@stsewdstsewdstsewd left review comments

@h3nnn4nh3nnn4nh3nnn4n left review comments

@ByronByronByron requested changes

Assignees
No one assigned
Labels
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

CVE-2022-24439:<gitpython::clone> 'ext::sh -c touch% /tmp/pwned' for remote code execution
4 participants
@s-t-e-v-e-n-k@stsewd@Byron@h3nnn4n

[8]ページ先頭

©2009-2025 Movatter.jp