From a39437ac6ee23a9be1072d56403006028eb9ea3e Mon Sep 17 00:00:00 2001 From: jolavillette Date: Sun, 30 Aug 2026 14:42:12 +0200 Subject: [PATCH] FeedReader: warn when the proxy scheme resolves hostnames locally With a plain socks4:// or socks5:// proxy, libcurl resolves the feed hostname itself through the system resolver before handing the IP to the proxy. Behind Tor this leaks every feed hostname to the clearnet DNS, and Tor logs "giving Tor only an IP address" on each fetch. Only socks4a:// and socks5h:// let the proxy resolve the name. The scheme combo now says which variant resolves where ("SOCKS5 (local DNS)" vs "SOCKS5h (remote DNS, use with Tor)"), and a warning line appears under the proxy field whenever a local-DNS SOCKS scheme is selected. Behaviour of the proxy itself is unchanged. Co-Authored-By: Claude Fable 5 --- plugins/FeedReader/gui/ProxyWidget.cpp | 34 +++++++++++---- plugins/FeedReader/gui/ProxyWidget.h | 1 + plugins/FeedReader/gui/ProxyWidget.ui | 59 +++++++++++++++++++------- 3 files changed, 71 insertions(+), 23 deletions(-) diff --git a/plugins/FeedReader/gui/ProxyWidget.cpp b/plugins/FeedReader/gui/ProxyWidget.cpp index eeb0c5256..d0bb38ef1 100644 --- a/plugins/FeedReader/gui/ProxyWidget.cpp +++ b/plugins/FeedReader/gui/ProxyWidget.cpp @@ -17,14 +17,19 @@ ProxyWidget::ProxyWidget(QWidget *parent) ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("HTTP Proxy."), Qt::ToolTipRole); ui->schemeComboBox->addItem("HTTPS", "https://"); ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("HTTPS Proxy."), Qt::ToolTipRole); - ui->schemeComboBox->addItem("SOCKS4", "socks4://"); - ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("SOCKS4 Proxy."), Qt::ToolTipRole); - ui->schemeComboBox->addItem("SOCKS4a", "socks4a://"); - ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("SOCKS4a Proxy. Proxy resolves URL hostname."), Qt::ToolTipRole); - ui->schemeComboBox->addItem("SOCKS5", "socks5://"); - ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("SOCKS5 Proxy."), Qt::ToolTipRole); - ui->schemeComboBox->addItem("SOCKS5h", "socks5h://"); - ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("SOCKS5 Proxy. Proxy resolves URL hostname."), Qt::ToolTipRole); + ui->schemeComboBox->addItem(tr("SOCKS4 (local DNS)"), "socks4://"); + ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("SOCKS4 Proxy. Hostnames are resolved locally and leak to your DNS resolver."), Qt::ToolTipRole); + ui->schemeComboBox->addItem(tr("SOCKS4a (remote DNS)"), "socks4a://"); + ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("SOCKS4a Proxy. Hostnames are resolved by the proxy."), Qt::ToolTipRole); + ui->schemeComboBox->addItem(tr("SOCKS5 (local DNS)"), "socks5://"); + ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("SOCKS5 Proxy. Hostnames are resolved locally and leak to your DNS resolver."), Qt::ToolTipRole); + ui->schemeComboBox->addItem(tr("SOCKS5h (remote DNS, use with Tor)"), "socks5h://"); + ui->schemeComboBox->setItemData(ui->schemeComboBox->count() - 1, tr("SOCKS5 Proxy. Hostnames are resolved by the proxy. Recommended with Tor."), Qt::ToolTipRole); + + /* The warning only reflects the selected scheme, so it does not need to be + * disconnected while the widget updates itself (unlike the "changed" signal). */ + connect(ui->schemeComboBox, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, &ProxyWidget::updateWarning); + updateWarning(); } ProxyWidget::~ProxyWidget() @@ -93,6 +98,19 @@ void ProxyWidget::setPort(int value) ui->portSpinBox->setValue(value); } +void ProxyWidget::updateWarning() +{ + QString scheme = ui->schemeComboBox->currentData().toString(); + + if (scheme == "socks4://" || scheme == "socks5://") { + ui->warningLabel->setText(tr("Hostnames of the feeds will be resolved locally and leak to your DNS resolver. With Tor, use SOCKS5h (or SOCKS4a) instead.")); + ui->warningLabel->show(); + } else { + ui->warningLabel->clear(); + ui->warningLabel->hide(); + } +} + void ProxyWidget::addressChanged(const QString &value) { int schemeIndex; diff --git a/plugins/FeedReader/gui/ProxyWidget.h b/plugins/FeedReader/gui/ProxyWidget.h index d1fdac315..91842ad43 100644 --- a/plugins/FeedReader/gui/ProxyWidget.h +++ b/plugins/FeedReader/gui/ProxyWidget.h @@ -26,6 +26,7 @@ Q_SIGNALS: private Q_SLOTS: void addressChanged(const QString &value); + void updateWarning(); private: void connectUi(bool doConnect); diff --git a/plugins/FeedReader/gui/ProxyWidget.ui b/plugins/FeedReader/gui/ProxyWidget.ui index 0671cebc3..14730f908 100644 --- a/plugins/FeedReader/gui/ProxyWidget.ui +++ b/plugins/FeedReader/gui/ProxyWidget.ui @@ -7,13 +7,13 @@ 0 0 400 - 22 + 44 - + 0 @@ -27,22 +27,51 @@ 0 - - - - - - - - - : + + + 0 - + + 0 + + + 0 + + + 0 + + + + + + + + + + + : + + + + + + + 65535 + + + + - - - 65535 + + + color: #b35a00; + + + + + + true