Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/git-credentials-url-encode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@e2b/python-sdk": patch
---

Percent-encode the username and password when embedding HTTP(S) Git credentials into a clone URL. Previously they were inserted raw, so a username or token containing URL-significant characters (`@`, `/`, `:`, spaces, etc.) produced a malformed URL that git could not use. This now matches the JS SDK, which already encodes the credentials.
7 changes: 5 additions & 2 deletions packages/python-sdk/e2b/sandbox/_git/auth.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Optional
from urllib.parse import urlparse, urlunparse
from urllib.parse import quote, urlparse, urlunparse

from e2b.exceptions import InvalidArgumentException
from e2b.sandbox.commands.command_handle import CommandExitException
Expand Down Expand Up @@ -27,7 +27,10 @@ def with_credentials(url: str, username: Optional[str], password: Optional[str])
"Only http(s) Git URLs support username/password credentials."
)

netloc = f"{username}:{password}@{parsed.netloc}"
# Percent-encode credentials so URL-significant characters (e.g. "@", "/",
# ":") in a username/token don't corrupt the URL. Matches the JS SDK, which
# encodes via the URL username/password setters.
netloc = f"{quote(username, safe='')}:{quote(password, safe='')}@{parsed.netloc}"
return urlunparse(parsed._replace(netloc=netloc))


Expand Down
26 changes: 26 additions & 0 deletions packages/python-sdk/tests/shared/git/test_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from e2b.sandbox._git.auth import strip_credentials, with_credentials


def test_with_credentials_percent_encodes_special_characters():
# URL-significant characters in the username/token must be percent-encoded
# so they don't corrupt the URL (git would otherwise mis-parse the host).
assert (
with_credentials("https://github.com/o/r.git", "user", "p@ss")
== "https://user:p%40ss@github.com/o/r.git"
)
assert (
with_credentials("https://github.com/o/r.git", "us er", "a/b:c")
== "https://us%20er:a%2Fb%3Ac@github.com/o/r.git"
)


def test_with_credentials_round_trips_through_strip():
url = with_credentials("https://github.com/o/r.git", "user", "p@ss")
assert strip_credentials(url) == "https://github.com/o/r.git"


def test_with_credentials_without_credentials_returns_url_unchanged():
assert (
with_credentials("https://github.com/o/r.git", None, None)
== "https://github.com/o/r.git"
)