github-advanced-security[bot] commented on code in PR #64105:
URL: https://github.com/apache/airflow/pull/64105#discussion_r3946684132


##########
providers/git/src/airflow/providers/git/hooks/git.py:
##########
@@ -293,22 +293,68 @@
                     self.env["GIT_TERMINAL_PROMPT"] = old_terminal_prompt
                     os.environ["GIT_TERMINAL_PROMPT"] = old_terminal_prompt
 
-    def _process_git_auth_url(self) -> None:
-        if not isinstance(self.repo_url, str):
+    def _extract_repo_host(self) -> str:
+        """Return the ``host[:port]`` of the repo url, as written."""
+        rest = str(self.repo_url).partition("://")[2]
+        return rest.partition("/")[0].rpartition("@")[2]
+
+    @contextlib.contextmanager
+    def _token_askpass_env(self):
+        """Hand the token to git through GIT_ASKPASS so it never reaches the 
repo URL."""
+        # Only http(s) consults GIT_ASKPASS, so writing the token to a temp 
script for an SSH
+        # connection that happens to carry one would put it on disk for 
nothing.
+        if not self.auth_token or not 
str(self.repo_url).startswith(("http://";, "https://";)):
+            yield
             return
-        if self.auth_token and self.repo_url.startswith("https://";):
-            encoded_user = urlquote(self.user_name, safe="")
-            encoded_token = urlquote(self.auth_token, safe="")
-            self.repo_url = self.repo_url.replace("https://";, 
f"https://{encoded_user}:{encoded_token}@";, 1)
-        elif self.auth_token and self.repo_url.startswith("http://";):
-            encoded_user = urlquote(self.user_name, safe="")
-            encoded_token = urlquote(self.auth_token, safe="")
-            self.repo_url = self.repo_url.replace("http://";, 
f"http://{encoded_user}:{encoded_token}@";, 1)
-        elif self.repo_url.startswith("http://";):
-            # if no auth token, use the repo url as is
-            pass
-        elif not self.repo_url.startswith("git@") and not 
self.repo_url.startswith("https://";):
-            self.repo_url = os.path.expanduser(self.repo_url)
+
+        host = self._extract_repo_host()
+        if not host:
+            yield
+            return
+
+        username = shlex.quote(self.user_name)
+        password = shlex.quote(self.auth_token)
+
+        with tempfile.TemporaryDirectory() as askpass_dir:
+            askpass_path = os.path.join(askpass_dir, "askpass.sh")
+            # git passes the target as 
``<scheme>://[user@]<host>[:port][/path]`` in $1. Matching
+            # it means a submodule hosted elsewhere gets nothing instead of 
this connection's
+            # token. Quoting the host keeps an IPv6 address's brackets out of 
glob interpretation.
+            with open(askpass_path, "w") as askpass_script:
+                askpass_script.write(
+                    f"""#!/bin/sh
+case "$1" in
+    *"://{host}'"*|*"://{host}/"*|*"@{host}'"*|*"@{host}/"*) ;;
+    *) exit 1 ;;
+esac
+case "$1" in
+    *Username*) echo {username} ;;
+    *Password*) echo {password} ;;
+    *) exit 1 ;;
+esac
+"""

Review Comment:
   ## CodeQL / Clear-text storage of sensitive information
   
   This expression stores [sensitive data (password)](1) as clear text.
   This expression stores [sensitive data (password)](2) as clear text.
   
   [Show more 
details](https://github.com/apache/airflow/security/code-scanning/638)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to