aminghadersohi commented on code in PR #44723:
URL: https://github.com/apache/superset/pull/44723#discussion_r4120023216


##########
superset/db_engine_specs/mysql.py:
##########
@@ -78,6 +80,78 @@
 )
 
 
+def _require_mysql_verified_tls(
+    driver: str, query: dict[str, Any], args: dict[str, Any]
+) -> None:
+    """Use required verification on drivers without an encryption-only mode."""
+    options = {**query, **args}
+    # Connector/Python has no REQUIRED mode: certificate verification is
+    # necessary to prevent its opportunistic fallback to cleartext.
+    if options.get("ssl_disabled"):
+        raise ValueError("MySQL SSL request conflicts with ssl_disabled")

Review Comment:
   Not applicable: SQLAlchemy does not coerce URL `ssl_disabled`, and both 
mysql-connector (`if self._ssl_disabled:`) and PyMySQL test the raw value for 
truthiness, so the string `"false"`/`"0"` actually disables TLS in the driver — 
rejecting it is the correct fail-closed behavior.



##########
superset/db_engine_specs/mysql.py:
##########
@@ -445,6 +519,8 @@ def adjust_engine_params(
         if schema:
             uri = uri.set(database=parse.quote(schema, safe=""))
 
+        if cls.engine == "mysql":
+            return require_mysql_tls(uri, new_connect_args)

Review Comment:
   Not a regression: the pinned `preset-aurora-data-api` `connect()` has no 
`ssl` parameter, so `ssl=1` already failed with a TypeError before this PR (the 
Data API is HTTPS-only), and an explicit unsupported-driver error is clearer.



##########
superset/db_engine_specs/mysql.py:
##########
@@ -78,6 +80,84 @@
 )
 
 
+def _require_mysql_verified_tls(
+    driver: str, query: dict[str, Any], args: dict[str, Any]
+) -> None:
+    """Use required verification on drivers without an encryption-only mode."""
+    options = {**query, **args}
+    # Connector/Python has no REQUIRED mode: certificate verification is
+    # necessary to prevent its opportunistic fallback to cleartext.
+    if options.get("ssl_disabled"):
+        raise ValueError("MySQL SSL request conflicts with ssl_disabled")
+    if "ssl_verify_cert" in options and not asbool(options["ssl_verify_cert"]):
+        raise ValueError("MySQL SSL request requires ssl_verify_cert")
+    if driver == "pymysql":
+        pymysql = import_module("pymysql")
+
+        # Older releases silently fall back even with explicit SSL options.
+        if pymysql.VERSION[:2] < (1, 2):
+            raise ValueError("The MySQL SSL toggle requires PyMySQL >= 1.2")
+        # SQLAlchemy folds URL ssl_ca/cert/key into an ssl dictionary,
+        # but PyMySQL ignores that dictionary when ssl_verify_cert is set.
+        # Keep these as native connect_args so the CA is not discarded.
+        for key in ("ssl_ca", "ssl_cert", "ssl_key"):
+            if key in query:
+                args.setdefault(key, query.pop(key))
+        if "ssl_check_hostname" in query:
+            args.setdefault(
+                "ssl_verify_identity", asbool(query.pop("ssl_check_hostname"))
+            )

Review Comment:
   Not applicable: SQLAlchemy 2.0 URL parsing drops valueless/empty query 
params (`make_url("mysql+pymysql://h/db?ssl_check_hostname").query == {}`), so 
`asbool("")` is unreachable here; and an explicit `ssl_verify_identity=False` 
connect_arg only relaxes hostname matching while TLS stays required with 
`ssl_verify_cert=True`, matching SQLAlchemy's normal connect_args-over-URL 
precedence.



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to