-
Notifications
You must be signed in to change notification settings - Fork 259
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
Timeout,proxy and rce fix #43
Changes from 3 commits
470e229
8293c00
7807a8c
cc420b3
5b6ea35
e9d5dfe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -398,6 +398,21 @@ def do_task(self, obj, url, directory, retry, timeout, http_headers, client_cert | |||||
return get_referenced_sha1(obj_file) | ||||||
|
||||||
|
||||||
def sanitize_file(filepath): | ||||||
""" Inplace comment out possibly unsafe lines based on regex """ | ||||||
assert os.path.isfile(filepath), "%s is not a file" % filepath | ||||||
|
||||||
UNSAFE=r"^\s*fsmonitor|sshcommand|askpass|editor|pager" | ||||||
|
||||||
with open(filepath, 'r+') as f: | ||||||
content = f.read() | ||||||
modified_content = re.sub(UNSAFE, '# \g<0>', content, flags=re.IGNORECASE) | ||||||
if content != modified_content: | ||||||
printf("Warning: '%s' file was altered\n" % filepath) | ||||||
f.seek(0) | ||||||
f.write(modified_content) | ||||||
|
||||||
|
||||||
def fetch_git(url, directory, jobs, retry, timeout, http_headers, client_cert_p12=None, client_cert_p12_password=None): | ||||||
""" Dump a git repository into the output directory """ | ||||||
|
||||||
|
@@ -427,7 +442,11 @@ def fetch_git(url, directory, jobs, retry, timeout, http_headers, client_cert_p1 | |||||
|
||||||
# check for /.git/HEAD | ||||||
printf("[-] Testing %s/.git/HEAD ", url) | ||||||
response = session.get("%s/.git/HEAD" % url, allow_redirects=False) | ||||||
response = session.get( | ||||||
"%s/.git/HEAD" % url, | ||||||
timeout=timeout, | ||||||
allow_redirects=False | ||||||
) | ||||||
printf("[%d]\n", response.status_code) | ||||||
|
||||||
valid, error_message = verify_response(response) | ||||||
|
@@ -459,10 +478,18 @@ def fetch_git(url, directory, jobs, retry, timeout, http_headers, client_cert_p1 | |||||
jobs, | ||||||
args=(url, directory, retry, timeout, http_headers), | ||||||
) | ||||||
|
||||||
os.chdir(directory) | ||||||
|
||||||
printf("[-] Sanitizing .git/config\n") | ||||||
sanitize_file(".git/config") | ||||||
|
||||||
printf("[-] Running git checkout .\n") | ||||||
os.chdir(directory) | ||||||
subprocess.check_call(["git", "checkout", "."]) | ||||||
ENV = os.environ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we shouldn't modify the current environment in case someone uses git-dumper as a library (although unlikely). We can simply make a copy.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if so, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I think there is a misunderstanding. |
||||||
configured_proxy = socks.getdefaultproxy() | ||||||
if configured_proxy[0] > 0: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if there are no proxy configured? It looks like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, it's indeed a None type, so changing 490 line to: if configured_proxy != None: should not raise exception in case of no proxy is set. I thought I tested a no proxy usage but looks like I didn't. |
||||||
ENV["ALL_PROXY"] = f"http.proxy={["http", "socks4h", "socks5h"][configured_proxy[0]]}" + f"://{configured_proxy[1]}:{configured_proxy[2]}" | ||||||
subprocess.check_call(["git", "checkout", "."], env=ENV) | ||||||
return 0 | ||||||
|
||||||
# no directory listing | ||||||
|
@@ -644,7 +671,11 @@ def fetch_git(url, directory, jobs, retry, timeout, http_headers, client_cert_p1 | |||||
os.chdir(directory) | ||||||
|
||||||
# ignore errors | ||||||
subprocess.call(["git", "checkout", "."], stderr=open(os.devnull, "wb")) | ||||||
subprocess.call( | ||||||
["git", "checkout", "."], | ||||||
stderr=open(os.devnull, "wb"), | ||||||
env=ENV | ||||||
) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment wasn't addressed.
|
||||||
|
||||||
return 0 | ||||||
|
||||||
|
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.
Hey @srozb, thanks for taking the time to fix this. However there is a few issues with your current patch.
This line lacks a
| re.MULTILINE
. In the current state it only works if the payload is the first line (which never happens).One can bypass the regex with this syntax:
As stated by the owner in the issue I opened, it would be much simpler and safer to (re)move
.git/config
, since we don't need it to rungit checkout .
IIRC.That is because it's possible to use many other git features to leverage RCE, for example one could
[include]
another file from the$GIT_DIR
. This would defeat your patch.