diff --git a/src/parser/PhutilURI.php b/src/parser/PhutilURI.php
--- a/src/parser/PhutilURI.php
+++ b/src/parser/PhutilURI.php
@@ -76,10 +76,10 @@
 
       $auth = '';
       if (strlen($this->user) && strlen($this->pass)) {
-        $auth = phutil_escape_uri($this->user).':'.
-                phutil_escape_uri($this->pass).'@';
+        $auth = rawurlencode($this->user).':'.
+                rawurlencode($this->pass).'@';
       } else if (strlen($this->user)) {
-        $auth = phutil_escape_uri($this->user).'@';
+        $auth = rawurlencode($this->user).'@';
       }
 
       $prefix = $protocol.'://'.$auth.$this->domain;
diff --git a/src/parser/__tests__/PhutilURITestCase.php b/src/parser/__tests__/PhutilURITestCase.php
--- a/src/parser/__tests__/PhutilURITestCase.php
+++ b/src/parser/__tests__/PhutilURITestCase.php
@@ -65,6 +65,11 @@
     $this->assertEqual('@', $uri->getPass());
     $this->assertEqual('http://%40:%40@domain.com/', (string)$uri);
 
+    $uri = new PhutilURI('http://%2F:%2F@domain.com/');
+    $this->assertEqual('/', $uri->getUser());
+    $this->assertEqual('/', $uri->getPass());
+    $this->assertEqual('http://%2F:%2F@domain.com/', (string)$uri);
+
     // These tests are covering cases where cURL and parse_url() behavior
     // may differ in potentially dangerous ways. See T6755 for discussion.