mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-01-12 18:24:58 +08:00
WebUI: Implement "Secure" flag for session cookie
Closes #11724. Option is enabled by default for users using qBittorrent's built-in HTTPS capabilities. This flag will never be set if qBittorrent is using plain HTTP. Users using HTTPS reverse proxies, like "qbt <-> (http) <-> proxy <-> (https) <-> user" should override the flag in the proxy in order to set it, if they wish to do so.
This commit is contained in:
parent
18de63f743
commit
691d5e5d89
@ -653,6 +653,16 @@ void Preferences::setWebUiCSRFProtectionEnabled(const bool enabled)
|
|||||||
setValue("Preferences/WebUI/CSRFProtection", enabled);
|
setValue("Preferences/WebUI/CSRFProtection", enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Preferences::isWebUiSecureCookieEnabled() const
|
||||||
|
{
|
||||||
|
return value("Preferences/WebUI/SecureCookie", true).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Preferences::setWebUiSecureCookieEnabled(const bool enabled)
|
||||||
|
{
|
||||||
|
setValue("Preferences/WebUI/SecureCookie", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
bool Preferences::isWebUIHostHeaderValidationEnabled() const
|
bool Preferences::isWebUIHostHeaderValidationEnabled() const
|
||||||
{
|
{
|
||||||
return value("Preferences/WebUI/HostHeaderValidation", true).toBool();
|
return value("Preferences/WebUI/HostHeaderValidation", true).toBool();
|
||||||
|
@ -202,6 +202,8 @@ public:
|
|||||||
void setWebUiClickjackingProtectionEnabled(bool enabled);
|
void setWebUiClickjackingProtectionEnabled(bool enabled);
|
||||||
bool isWebUiCSRFProtectionEnabled() const;
|
bool isWebUiCSRFProtectionEnabled() const;
|
||||||
void setWebUiCSRFProtectionEnabled(bool enabled);
|
void setWebUiCSRFProtectionEnabled(bool enabled);
|
||||||
|
bool isWebUiSecureCookieEnabled () const;
|
||||||
|
void setWebUiSecureCookieEnabled(bool enabled);
|
||||||
bool isWebUIHostHeaderValidationEnabled() const;
|
bool isWebUIHostHeaderValidationEnabled() const;
|
||||||
void setWebUIHostHeaderValidationEnabled(bool enabled);
|
void setWebUIHostHeaderValidationEnabled(bool enabled);
|
||||||
|
|
||||||
|
@ -409,6 +409,8 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
|||||||
connect(m_ui->spinSessionTimeout, qSpinBoxValueChanged, this, &ThisType::enableApplyButton);
|
connect(m_ui->spinSessionTimeout, qSpinBoxValueChanged, this, &ThisType::enableApplyButton);
|
||||||
connect(m_ui->checkClickjacking, &QCheckBox::toggled, this, &ThisType::enableApplyButton);
|
connect(m_ui->checkClickjacking, &QCheckBox::toggled, this, &ThisType::enableApplyButton);
|
||||||
connect(m_ui->checkCSRFProtection, &QCheckBox::toggled, this, &ThisType::enableApplyButton);
|
connect(m_ui->checkCSRFProtection, &QCheckBox::toggled, this, &ThisType::enableApplyButton);
|
||||||
|
connect(m_ui->checkWebUiHttps, &QGroupBox::toggled, m_ui->checkSecureCookie, &QWidget::setEnabled);
|
||||||
|
connect(m_ui->checkSecureCookie, &QCheckBox::toggled, this, &ThisType::enableApplyButton);
|
||||||
connect(m_ui->groupHostHeaderValidation, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
|
connect(m_ui->groupHostHeaderValidation, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
|
||||||
connect(m_ui->checkDynDNS, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
|
connect(m_ui->checkDynDNS, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
|
||||||
connect(m_ui->comboDNSService, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
connect(m_ui->comboDNSService, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
||||||
@ -793,6 +795,7 @@ void OptionsDialog::saveOptions()
|
|||||||
// Security
|
// Security
|
||||||
pref->setWebUiClickjackingProtectionEnabled(m_ui->checkClickjacking->isChecked());
|
pref->setWebUiClickjackingProtectionEnabled(m_ui->checkClickjacking->isChecked());
|
||||||
pref->setWebUiCSRFProtectionEnabled(m_ui->checkCSRFProtection->isChecked());
|
pref->setWebUiCSRFProtectionEnabled(m_ui->checkCSRFProtection->isChecked());
|
||||||
|
pref->setWebUiSecureCookieEnabled(m_ui->checkSecureCookie->isChecked());
|
||||||
pref->setWebUIHostHeaderValidationEnabled(m_ui->groupHostHeaderValidation->isChecked());
|
pref->setWebUIHostHeaderValidationEnabled(m_ui->groupHostHeaderValidation->isChecked());
|
||||||
// DynDNS
|
// DynDNS
|
||||||
pref->setDynDNSEnabled(m_ui->checkDynDNS->isChecked());
|
pref->setDynDNSEnabled(m_ui->checkDynDNS->isChecked());
|
||||||
@ -1165,6 +1168,8 @@ void OptionsDialog::loadOptions()
|
|||||||
// Security
|
// Security
|
||||||
m_ui->checkClickjacking->setChecked(pref->isWebUiClickjackingProtectionEnabled());
|
m_ui->checkClickjacking->setChecked(pref->isWebUiClickjackingProtectionEnabled());
|
||||||
m_ui->checkCSRFProtection->setChecked(pref->isWebUiCSRFProtectionEnabled());
|
m_ui->checkCSRFProtection->setChecked(pref->isWebUiCSRFProtectionEnabled());
|
||||||
|
m_ui->checkSecureCookie->setEnabled(pref->isWebUiHttpsEnabled());
|
||||||
|
m_ui->checkSecureCookie->setChecked(pref->isWebUiSecureCookieEnabled());
|
||||||
m_ui->groupHostHeaderValidation->setChecked(pref->isWebUIHostHeaderValidationEnabled());
|
m_ui->groupHostHeaderValidation->setChecked(pref->isWebUIHostHeaderValidationEnabled());
|
||||||
|
|
||||||
m_ui->checkDynDNS->setChecked(pref->isDynDNSEnabled());
|
m_ui->checkDynDNS->setChecked(pref->isDynDNSEnabled());
|
||||||
|
@ -3054,6 +3054,13 @@ Specify an IPv4 or IPv6 address. You can specify "0.0.0.0" for any IPv
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkSecureCookie">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable cookie Secure flag (requires HTTPS)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupHostHeaderValidation">
|
<widget class="QGroupBox" name="groupHostHeaderValidation">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -239,6 +239,7 @@ void AppController::preferencesAction()
|
|||||||
// Security
|
// Security
|
||||||
data["web_ui_clickjacking_protection_enabled"] = pref->isWebUiClickjackingProtectionEnabled();
|
data["web_ui_clickjacking_protection_enabled"] = pref->isWebUiClickjackingProtectionEnabled();
|
||||||
data["web_ui_csrf_protection_enabled"] = pref->isWebUiCSRFProtectionEnabled();
|
data["web_ui_csrf_protection_enabled"] = pref->isWebUiCSRFProtectionEnabled();
|
||||||
|
data["web_ui_secure_cookie_enabled"] = pref->isWebUiSecureCookieEnabled();
|
||||||
data["web_ui_host_header_validation_enabled"] = pref->isWebUIHostHeaderValidationEnabled();
|
data["web_ui_host_header_validation_enabled"] = pref->isWebUIHostHeaderValidationEnabled();
|
||||||
// Update my dynamic domain name
|
// Update my dynamic domain name
|
||||||
data["dyndns_enabled"] = pref->isDynDNSEnabled();
|
data["dyndns_enabled"] = pref->isDynDNSEnabled();
|
||||||
@ -608,6 +609,8 @@ void AppController::setPreferencesAction()
|
|||||||
pref->setWebUiClickjackingProtectionEnabled(it.value().toBool());
|
pref->setWebUiClickjackingProtectionEnabled(it.value().toBool());
|
||||||
if (hasKey("web_ui_csrf_protection_enabled"))
|
if (hasKey("web_ui_csrf_protection_enabled"))
|
||||||
pref->setWebUiCSRFProtectionEnabled(it.value().toBool());
|
pref->setWebUiCSRFProtectionEnabled(it.value().toBool());
|
||||||
|
if (hasKey("web_ui_secure_cookie_enabled"))
|
||||||
|
pref->setWebUiSecureCookieEnabled(it.value().toBool());
|
||||||
if (hasKey("web_ui_host_header_validation_enabled"))
|
if (hasKey("web_ui_host_header_validation_enabled"))
|
||||||
pref->setWebUIHostHeaderValidationEnabled(it.value().toBool());
|
pref->setWebUIHostHeaderValidationEnabled(it.value().toBool());
|
||||||
// Update my dynamic domain name
|
// Update my dynamic domain name
|
||||||
|
@ -337,6 +337,7 @@ void WebApplication::configure()
|
|||||||
|
|
||||||
m_isClickjackingProtectionEnabled = pref->isWebUiClickjackingProtectionEnabled();
|
m_isClickjackingProtectionEnabled = pref->isWebUiClickjackingProtectionEnabled();
|
||||||
m_isCSRFProtectionEnabled = pref->isWebUiCSRFProtectionEnabled();
|
m_isCSRFProtectionEnabled = pref->isWebUiCSRFProtectionEnabled();
|
||||||
|
m_isSecureCookieEnabled = pref->isWebUiSecureCookieEnabled();
|
||||||
m_isHostHeaderValidationEnabled = pref->isWebUIHostHeaderValidationEnabled();
|
m_isHostHeaderValidationEnabled = pref->isWebUIHostHeaderValidationEnabled();
|
||||||
m_isHttpsEnabled = pref->isWebUiHttpsEnabled();
|
m_isHttpsEnabled = pref->isWebUiHttpsEnabled();
|
||||||
|
|
||||||
@ -535,6 +536,7 @@ void WebApplication::sessionStart()
|
|||||||
|
|
||||||
QNetworkCookie cookie(C_SID, m_currentSession->id().toUtf8());
|
QNetworkCookie cookie(C_SID, m_currentSession->id().toUtf8());
|
||||||
cookie.setHttpOnly(true);
|
cookie.setHttpOnly(true);
|
||||||
|
cookie.setSecure(m_isSecureCookieEnabled && m_isHttpsEnabled);
|
||||||
cookie.setPath(QLatin1String("/"));
|
cookie.setPath(QLatin1String("/"));
|
||||||
QByteArray cookieRawForm = cookie.toRawForm();
|
QByteArray cookieRawForm = cookie.toRawForm();
|
||||||
if (m_isCSRFProtectionEnabled)
|
if (m_isCSRFProtectionEnabled)
|
||||||
|
@ -153,6 +153,7 @@ private:
|
|||||||
QStringList m_domainList;
|
QStringList m_domainList;
|
||||||
bool m_isClickjackingProtectionEnabled;
|
bool m_isClickjackingProtectionEnabled;
|
||||||
bool m_isCSRFProtectionEnabled;
|
bool m_isCSRFProtectionEnabled;
|
||||||
|
bool m_isSecureCookieEnabled;
|
||||||
bool m_isHostHeaderValidationEnabled;
|
bool m_isHostHeaderValidationEnabled;
|
||||||
bool m_isHttpsEnabled;
|
bool m_isHttpsEnabled;
|
||||||
QString m_contentSecurityPolicy;
|
QString m_contentSecurityPolicy;
|
||||||
|
@ -756,6 +756,10 @@
|
|||||||
<input type="checkbox" id="csrf_protection_checkbox" />
|
<input type="checkbox" id="csrf_protection_checkbox" />
|
||||||
<label for="csrf_protection_checkbox">QBT_TR(Enable Cross-Site Request Forgery (CSRF) protection)QBT_TR[CONTEXT=OptionsDialog]</label>
|
<label for="csrf_protection_checkbox">QBT_TR(Enable Cross-Site Request Forgery (CSRF) protection)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="formRow">
|
||||||
|
<input type="checkbox" id="secureCookieCheckbox" />
|
||||||
|
<label for="secureCookieCheckbox">QBT_TR(Enable cookie Secure flag (requires HTTPS))QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<fieldset class="settings">
|
<fieldset class="settings">
|
||||||
<legend>
|
<legend>
|
||||||
@ -1350,6 +1354,7 @@
|
|||||||
const isUseHttpsEnabled = $('use_https_checkbox').getProperty('checked');
|
const isUseHttpsEnabled = $('use_https_checkbox').getProperty('checked');
|
||||||
$('ssl_cert_text').setProperty('disabled', !isUseHttpsEnabled);
|
$('ssl_cert_text').setProperty('disabled', !isUseHttpsEnabled);
|
||||||
$('ssl_key_text').setProperty('disabled', !isUseHttpsEnabled);
|
$('ssl_key_text').setProperty('disabled', !isUseHttpsEnabled);
|
||||||
|
$('secureCookieCheckbox').setProperty('disabled', !isUseHttpsEnabled);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateBypasssAuthSettings = function() {
|
const updateBypasssAuthSettings = function() {
|
||||||
@ -1717,6 +1722,7 @@
|
|||||||
// Security
|
// Security
|
||||||
$('clickjacking_protection_checkbox').setProperty('checked', pref.web_ui_clickjacking_protection_enabled);
|
$('clickjacking_protection_checkbox').setProperty('checked', pref.web_ui_clickjacking_protection_enabled);
|
||||||
$('csrf_protection_checkbox').setProperty('checked', pref.web_ui_csrf_protection_enabled);
|
$('csrf_protection_checkbox').setProperty('checked', pref.web_ui_csrf_protection_enabled);
|
||||||
|
$('secureCookieCheckbox').setProperty('checked', pref.web_ui_secure_cookie_enabled);
|
||||||
$('host_header_validation_checkbox').setProperty('checked', pref.web_ui_host_header_validation_enabled);
|
$('host_header_validation_checkbox').setProperty('checked', pref.web_ui_host_header_validation_enabled);
|
||||||
updateHostHeaderValidationSettings();
|
updateHostHeaderValidationSettings();
|
||||||
|
|
||||||
@ -2082,6 +2088,7 @@
|
|||||||
|
|
||||||
settings.set('web_ui_clickjacking_protection_enabled', $('clickjacking_protection_checkbox').getProperty('checked'));
|
settings.set('web_ui_clickjacking_protection_enabled', $('clickjacking_protection_checkbox').getProperty('checked'));
|
||||||
settings.set('web_ui_csrf_protection_enabled', $('csrf_protection_checkbox').getProperty('checked'));
|
settings.set('web_ui_csrf_protection_enabled', $('csrf_protection_checkbox').getProperty('checked'));
|
||||||
|
settings.set('web_ui_secure_cookie_enabled', $('secureCookieCheckbox').getProperty('checked'));
|
||||||
settings.set('web_ui_host_header_validation_enabled', $('host_header_validation_checkbox').getProperty('checked'));
|
settings.set('web_ui_host_header_validation_enabled', $('host_header_validation_checkbox').getProperty('checked'));
|
||||||
|
|
||||||
// Update my dynamic domain name
|
// Update my dynamic domain name
|
||||||
|
Loading…
Reference in New Issue
Block a user