Fix high-severity issues: implement SSL and warn on raw-SQL filter
SSL was wired through the UI and ConnectionProfile but never actually
applied in any driver or passed from the connection builder.
- main_window: pass ssl/ssl_ca/ssl_cert/ssl_key from profile into
the driver config dict so drivers can act on them
- MySQL: add ssl={ca,cert,key} to pymysql connect kwargs when enabled
- PostgreSQL: set sslmode=verify-ca (with CA) or require, plus
sslrootcert/sslcert/sslkey when provided
- MSSQL: switch Encrypt=yes + TrustServerCertificate=no when SSL is
on; Encrypt=no + TrustServerCertificate=yes otherwise
- SQLite: no change needed (local file, no network layer)
WHERE filter: add tooltip explicitly labelling the input as raw SQL
so users understand arbitrary expressions are executed directly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -34,12 +34,20 @@ class MSSQLDriver(BaseDriver):
|
|||||||
installed = pyodbc.drivers() if PYODBC_AVAILABLE else []
|
installed = pyodbc.drivers() if PYODBC_AVAILABLE else []
|
||||||
driver = next((d for d in preferred if d in installed), preferred[0])
|
driver = next((d for d in preferred if d in installed), preferred[0])
|
||||||
|
|
||||||
|
if self.config.get("ssl"):
|
||||||
|
encrypt = "yes"
|
||||||
|
trust_cert = "no"
|
||||||
|
else:
|
||||||
|
encrypt = "no"
|
||||||
|
trust_cert = "yes"
|
||||||
|
|
||||||
return (
|
return (
|
||||||
f"DRIVER={{{driver}}};"
|
f"DRIVER={{{driver}}};"
|
||||||
f"SERVER={host},{port};"
|
f"SERVER={host},{port};"
|
||||||
f"DATABASE={db};"
|
f"DATABASE={db};"
|
||||||
f"UID={user};PWD={pwd};"
|
f"UID={user};PWD={pwd};"
|
||||||
f"TrustServerCertificate=yes;"
|
f"Encrypt={encrypt};"
|
||||||
|
f"TrustServerCertificate={trust_cert};"
|
||||||
f"Connection Timeout={self.config.get('connection_timeout', 30)};"
|
f"Connection Timeout={self.config.get('connection_timeout', 30)};"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ class MySQLDriver(BaseDriver):
|
|||||||
db = self.config.get("database", "")
|
db = self.config.get("database", "")
|
||||||
if db:
|
if db:
|
||||||
kw["database"] = db
|
kw["database"] = db
|
||||||
|
if self.config.get("ssl"):
|
||||||
|
ssl_opts = {}
|
||||||
|
if self.config.get("ssl_ca"): ssl_opts["ca"] = self.config["ssl_ca"]
|
||||||
|
if self.config.get("ssl_cert"): ssl_opts["cert"] = self.config["ssl_cert"]
|
||||||
|
if self.config.get("ssl_key"): ssl_opts["key"] = self.config["ssl_key"]
|
||||||
|
kw["ssl"] = ssl_opts
|
||||||
return kw
|
return kw
|
||||||
|
|
||||||
def connect(self) -> None:
|
def connect(self) -> None:
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ class PostgreSQLDriver(BaseDriver):
|
|||||||
db = self.config.get("database", "")
|
db = self.config.get("database", "")
|
||||||
if db:
|
if db:
|
||||||
kw["dbname"] = db
|
kw["dbname"] = db
|
||||||
|
if self.config.get("ssl"):
|
||||||
|
kw["sslmode"] = "verify-ca" if self.config.get("ssl_ca") else "require"
|
||||||
|
if self.config.get("ssl_ca"): kw["sslrootcert"] = self.config["ssl_ca"]
|
||||||
|
if self.config.get("ssl_cert"): kw["sslcert"] = self.config["ssl_cert"]
|
||||||
|
if self.config.get("ssl_key"): kw["sslkey"] = self.config["ssl_key"]
|
||||||
return kw
|
return kw
|
||||||
|
|
||||||
def connect(self) -> None:
|
def connect(self) -> None:
|
||||||
|
|||||||
@@ -246,6 +246,10 @@ class MainWindow(QMainWindow):
|
|||||||
"user": profile.username,
|
"user": profile.username,
|
||||||
"password": profile.password,
|
"password": profile.password,
|
||||||
"connection_timeout": profile.connection_timeout,
|
"connection_timeout": profile.connection_timeout,
|
||||||
|
"ssl": profile.ssl,
|
||||||
|
"ssl_ca": profile.ssl_ca,
|
||||||
|
"ssl_cert": profile.ssl_cert,
|
||||||
|
"ssl_key": profile.ssl_key,
|
||||||
}
|
}
|
||||||
_log.info("Connecting to '%s' type=%s host=%s",
|
_log.info("Connecting to '%s' type=%s host=%s",
|
||||||
profile.name, profile.db_type, profile.host)
|
profile.name, profile.db_type, profile.host)
|
||||||
|
|||||||
@@ -331,9 +331,13 @@ class TableViewer(QWidget):
|
|||||||
self._filter_input = QLineEdit()
|
self._filter_input = QLineEdit()
|
||||||
self._filter_input.setPlaceholderText("WHERE … (e.g. id > 100)")
|
self._filter_input.setPlaceholderText("WHERE … (e.g. id > 100)")
|
||||||
self._filter_input.setFixedWidth(260)
|
self._filter_input.setFixedWidth(260)
|
||||||
|
self._filter_input.setToolTip(
|
||||||
|
"Raw SQL — injected directly into WHERE clause.\n"
|
||||||
|
"Examples: id > 100 name LIKE 'A%' status = 'active'"
|
||||||
|
)
|
||||||
self._filter_btn = QPushButton("🔍")
|
self._filter_btn = QPushButton("🔍")
|
||||||
self._filter_btn.setFixedWidth(34)
|
self._filter_btn.setFixedWidth(34)
|
||||||
self._filter_btn.setToolTip("Apply filter")
|
self._filter_btn.setToolTip("Apply filter (raw SQL WHERE clause)")
|
||||||
self._filter_btn.clicked.connect(self._apply_filter)
|
self._filter_btn.clicked.connect(self._apply_filter)
|
||||||
self._filter_input.returnPressed.connect(self._apply_filter)
|
self._filter_input.returnPressed.connect(self._apply_filter)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user