Repository: urllib3/urllib3

Issue:
https_proxy to http_host leads to `is_verfied==True`
(followup to #3130)

### Subject

@illia-v , the test you provided within https://github.com/urllib3/urllib3/pull/3149#pullrequestreview-1683158046

```py
     def test_https_proxy(self) -> None:                                                                                                                                                                                                                                                                                                                                                                            
         with proxy_from_url(self.https_proxy_url, ca_certs=DEFAULT_CA) as https:                                                                                                                                                                                                                                                                                                                                   
[...]                                                                                                                                                                                                                                                                                                                                                                                                     
             r = https.request("GET", f"{self.http_url}/")                                                                                                                                                                                                                                                                                                                                                          
             assert r.status == 200                                                                                                                                                                                                                                                                                                                                                                                 
+            pool = list(https.pools._container.values())[-1]                                                                                                                                                                                                                                                                                                                                                       
+            connection = pool.pool.queue[-1]                                                                                                                                                                                                                                                                                                                                                                       
+            assert connection.is_verified is False                                                                                                                                                                                                                                                                                                                                                                 
+            assert connection.proxy_is_verified is True                                                                                                                                                                                                                                                                                                                                                          
                                                             
```

Thus, the 

* `proxy_is_verifed is True`, `is_verified is False`

I tend to agree with this logic, but the current code does

* `proxy_is_verifed is True`, `is_verified is True`.

This seems like an additional (besides #3130) bug (or at least flaw).

You can review the behavior within 

- https://github.com/urllib3/urllib3/pull/3266

the relevant test is `test_is_verified_https_proxy_to_http_target`






Discussion:
Since we already have a test case for this issue I'm assigning a $100 bounty for the fix. Thanks for reporting!

Resolving patch:
diff --git a/src/urllib3/connection.py b/src/urllib3/connection.py
--- a/src/urllib3/connection.py
+++ b/src/urllib3/connection.py
@@ -265,6 +265,13 @@ def is_connected(self) -> bool:
     def has_connected_to_proxy(self) -> bool:
         return self._has_connected_to_proxy
 
+    @property
+    def proxy_is_forwarding(self) -> bool:
+        """
+        Return True if a forwarding proxy is configured, else return False
+        """
+        return bool(self.proxy) and self._tunnel_host is None
+
     def close(self) -> None:
         try:
             super().close()
@@ -663,11 +670,14 @@ def connect(self) -> None:
         )
         self.sock = sock_and_verified.socket
 
-        # TODO: Set correct `self.is_verified` in case of HTTPS proxy +
-        #       HTTP destination, see
-        #       `test_is_verified_https_proxy_to_http_target` and
-        #       https://github.com/urllib3/urllib3/issues/3267.
-        self.is_verified = sock_and_verified.is_verified
+        # Forwarding proxies can never have a verified target since
+        # the proxy is the one doing the verification. Should instead
+        # use a CONNECT tunnel in order to verify the target.
+        # See: https://github.com/urllib3/urllib3/issues/3267.
+        if self.proxy_is_forwarding:
+            self.is_verified = False
+        else:
+            self.is_verified = sock_and_verified.is_verified
 
         # If there's a proxy to be connected to we are fully connected.
         # This is set twice (once above and here) due to forwarding proxies
diff --git a/src/urllib3/connectionpool.py b/src/urllib3/connectionpool.py
--- a/src/urllib3/connectionpool.py
+++ b/src/urllib3/connectionpool.py
@@ -1098,7 +1098,8 @@ def _validate_conn(self, conn: BaseHTTPConnection) -> None:
         if conn.is_closed:
             conn.connect()
 
-        if not conn.is_verified:
+        # TODO revise this, see https://github.com/urllib3/urllib3/issues/2791
+        if not conn.is_verified and not conn.proxy_is_verified:
             warnings.warn(
                 (
                     f"Unverified HTTPS request is being made to host '{conn.host}'. "


Test patch:
diff --git a/test/with_dummyserver/test_proxy_poolmanager.py b/test/with_dummyserver/test_proxy_poolmanager.py
--- a/test/with_dummyserver/test_proxy_poolmanager.py
+++ b/test/with_dummyserver/test_proxy_poolmanager.py
@@ -105,7 +105,6 @@ def test_is_verified_http_proxy_to_https_target(self) -> None:
             assert r.status == 200
             assert_is_verified(http, proxy=False, target=True)
 
-    @pytest.mark.xfail(reason="see https://github.com/urllib3/urllib3/issues/3267")
     def test_is_verified_https_proxy_to_http_target(self) -> None:
         with proxy_from_url(self.https_proxy_url, ca_certs=DEFAULT_CA) as https:
             r = https.request("GET", f"{self.http_url}/")