Compare commits

...

10 Commits

Author SHA1 Message Date
Ilia Ross
463fcea730 Fix to require trusted proxies for SSL client cert headers
This PR tightens handling of proxied SSL client certificate headers so they are only honored when Webmin is configured to trust SSL headers and the direct TCP peer matches an explicit `trusted_proxies` entry.

The change preserves legacy forwarded-IP behavior for `trust_real_ip`, but prevents ambiguous legacy configs with no trusted proxy from accepting spoofable `X-SSL-Client-*` headers as authentication identity. During postinstall, such legacy configs now default to `no_trust_ssl=1`.
2026-06-30 14:23:01 +02:00
Jamie Cameron
a94ff2c49a Merge branch 'master' of github.com:webmin/webmin
Some checks failed
Tests / prove (push) Has been cancelled
Package and upload artifacts / build (push) Has been cancelled
Close inactive / close-inactive (push) Has been cancelled
2026-06-29 20:18:06 -07:00
Jamie Cameron
ec78452e7b Add missing icons 2026-06-29 20:17:23 -07:00
Ilia Ross
a7325b9087 Update changelog for 2.652 2026-06-30 01:47:25 +02:00
Ilia Ross
cc4bb35dee Update tests to recognize hex numeric HTML entities
Some checks failed
Tests / prove (push) Has been cancelled
Package and upload artifacts / build (push) Has been cancelled
2026-06-29 23:28:48 +02:00
Ilia Ross
aa2282778e Fix to recognize hex numeric HTML entities
https://forum.virtualmin.com/t/char-redered-as-x25e6/137494/6?u=ilia
2026-06-29 23:28:28 +02:00
Jamie Cameron
1c9d57f5dd Safe mode in the custom commands module just allows execution of commands
Some checks failed
Tests / prove (push) Has been cancelled
Package and upload artifacts / build (push) Has been cancelled
Close inactive / close-inactive (push) Has been cancelled
2026-06-28 17:17:21 -07:00
Jamie Cameron
4ffa02d636 New version bump 2026-06-28 15:39:34 -07:00
Ilia Ross
57ad5fa535 Update labels
Some checks failed
Tests / prove (push) Has been cancelled
Package and upload artifacts / build (push) Has been cancelled
2026-06-28 23:02:39 +02:00
Ilia Ross
a3f5ea3381 Update changelog
Some checks failed
Tests / prove (push) Has been cancelled
Package and upload artifacts / build (push) Has been cancelled
Close inactive / close-inactive (push) Has been cancelled
2026-06-28 02:40:46 +02:00
16 changed files with 54 additions and 28 deletions

View File

@@ -1,7 +1,15 @@
## Changelog ## Changelog
#### 2.652 (July, 2026)
* Fix to recognize hex numeric HTML entities to work in various elements
#### 2.651 (June 28, 2026) #### 2.651 (June 28, 2026)
* Fix Certbot-backed certificate requests and renewals to correctly parse PEM paths after issuance * Fix Certbot-backed certificate requests and renewals to correctly parse PEM paths after issuance
* Fix live activation of Linux bond interfaces [#2777](https://github.com/webmin/webmin/pull/2777)
* Update the Authentic theme to the latest version with various improvements and fixes:
- Fix search-result all-items delete in File Manager
- Fix search-result delete ordering in File Manager
- Fix to speed up search-result deletion cleanup in File Manager
#### 2.650 (June 25, 2026) #### 2.650 (June 25, 2026)
* Add new Systemd Services and Units module * Add new Systemd Services and Units module

2
custom/safeacl Normal file
View File

@@ -0,0 +1,2 @@
edit=0
cmds=*

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
grub2/images/icon.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
kea-dhcp/images/icon.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

View File

@@ -1542,16 +1542,25 @@ if ($headerhost) {
$headerhost = undef if (!&check_ipaddress($headerhost) && $headerhost = undef if (!&check_ipaddress($headerhost) &&
!&check_ip6address($headerhost)); !&check_ip6address($headerhost));
} }
# If trusted_proxies is configured, header-supplied client IP and SSL # If trusted_proxies is configured, header-supplied client IP is only
# client info are only honored when the direct TCP peer is in that list. # honored when the direct TCP peer is in that list. Proxied SSL client
# Otherwise drop them so an attacker reaching miniserv directly cannot # cert headers carry authentication identity, so only honor those from
# spoof X-Forwarded-For or X-SSL-Client-* to bypass auth. # an explicitly trusted proxy.
if ($config{'trust_real_ip'} && $config{'trusted_proxies'} ne '' && my @trusted_proxies = split(/\s+/, $config{'trusted_proxies'} || "");
!&ip_match($acptip, $localip, my $trusted_proxy = @trusted_proxies &&
split(/\s+/, $config{'trusted_proxies'}))) { &ip_match($acptip, $localip, @trusted_proxies);
my $trust_ssl_client_headers = $config{'trust_real_ip'} &&
!$config{'no_trust_ssl'} && $trusted_proxy;
if ($config{'trust_real_ip'} && @trusted_proxies && !$trusted_proxy) {
print DEBUG "handle_request: peer $acptip not in trusted_proxies; ". print DEBUG "handle_request: peer $acptip not in trusted_proxies; ".
"ignoring forwarding and SSL client headers\n"; "ignoring forwarding headers\n";
$headerhost = undef; $headerhost = undef;
}
if (!$trust_ssl_client_headers) {
print DEBUG "handle_request: ignoring SSL client headers from ".
"peer $acptip\n"
if ($header{'x-ssl-client-dn'} ||
$header{'x-ssl-client-verify'});
delete $header{'x-ssl-client-dn'}; delete $header{'x-ssl-client-dn'};
delete $header{'x-ssl-client-verify'}; delete $header{'x-ssl-client-verify'};
} }

View File

@@ -38,6 +38,9 @@ subtest 'html_escape' => sub {
is(main::html_escape('&'), '&', 'default mode double-escapes &'); is(main::html_escape('&'), '&', 'default mode double-escapes &');
is(main::html_escape('&', 1), '&', 'nodblamp preserves existing &'); is(main::html_escape('&', 1), '&', 'nodblamp preserves existing &');
is(main::html_escape('A', 1), 'A', 'nodblamp preserves numeric entity'); is(main::html_escape('A', 1), 'A', 'nodblamp preserves numeric entity');
is(main::html_escape('◦', 1), '◦', 'nodblamp preserves hex numeric entity');
is(main::html_escape('◦', 1), '◦', 'nodblamp preserves uppercase hex numeric entity');
is(main::html_escape('&#xZZ;', 1), '&#xZZ;', 'nodblamp escapes invalid hex numeric entity');
# Note: nodblamp's lookahead matches any &<letters>; as an entity, so # Note: nodblamp's lookahead matches any &<letters>; as an entity, so
# made-up names like &x; are treated as entities and not re-escaped. # made-up names like &x; are treated as entities and not re-escaped.
is(main::html_escape('&x;', 1), '&x;', 'nodblamp preserves arbitrary &word; shape'); is(main::html_escape('&x;', 1), '&x;', 'nodblamp preserves arbitrary &word; shape');

View File

@@ -1 +1 @@
2.650 2.651

View File

@@ -302,7 +302,7 @@ if (!defined $tmp) {
}; };
# Before escaping ampersand use negative lookahead to see if occurrence # Before escaping ampersand use negative lookahead to see if occurrence
# is not an HTML entity already to prevent double escaping (optionally) # is not an HTML entity already to prevent double escaping (optionally)
$tmp =~ s/&(?!(([a-zA-Z]+)|(#|#x)\d+);)/&amp;/g if ($nodblamp); $tmp =~ s/&(?!([a-zA-Z]+|#\d+|#[xX][0-9A-Fa-f]+);)/&amp;/g if ($nodblamp);
# Always escape all ampersands by default # Always escape all ampersands by default
# to make sure they are displayed per se # to make sure they are displayed per se
$tmp =~ s/&/&amp;/g if (!$nodblamp); $tmp =~ s/&/&amp;/g if (!$nodblamp);

View File

@@ -3,13 +3,13 @@ standard_url=URL of standard modules list,3,On webmin.com
third_url=URL of third party modules list,3,On webmin.com third_url=URL of third party modules list,3,On webmin.com
cron_mode=Show update times as,1,0-Simple interface,1-Cron time selector cron_mode=Show update times as,1,0-Simple interface,1-Cron time selector
warn_days=Days before password expiry to warn users,0,5 warn_days=Days before password expiry to warn users,0,5
line2=Let's Encrypt configuration,11 line2=ACME provider configuration,11
letsencrypt_cmd=Full path to Let's Encrypt client command,3,Find automatically letsencrypt_cmd=Full path to ACME client command,3,Find automatically
letsencrypt_directory_url=Custom ACME directory URL,3,Use Let's Encrypt production letsencrypt_directory_url=Custom ACME directory URL,3,Use default production server
letsencrypt_eab_kid=External Account Binding key ID,3,None letsencrypt_eab_kid=External Account Binding key ID,3,None
letsencrypt_eab_hmac=External Account Binding HMAC key,12 letsencrypt_eab_hmac=External Account Binding HMAC key,12
letsencrypt_algo=Encryption algorithm for Let's Encrypt private key,1,rsa-RSA,ecdsa-ECC letsencrypt_algo=Encryption algorithm for certificate private key,1,rsa-RSA,ecdsa-ECC
letsencrypt_dns_wait=Seconds to wait for Let's Encrypt DNS propagation,0,5 letsencrypt_dns_wait=Seconds to wait for ACME DNS propagation,0,5
letsencrypt_before=Command to run before Let's Encrypt request,0,60 letsencrypt_before=Command to run before ACME certificate request,0,60
letsencrypt_after=Command to run after Let's Encrypt request,0,60 letsencrypt_after=Command to run after ACME certificate request,0,60
letsencrypt_reuse=Re-use existing Let's Encrypt keys?,1,1-Yes,0-No letsencrypt_reuse=Re-use existing certificate keys?,1,1-Yes,0-No

View File

@@ -2,4 +2,4 @@ standard_url=URL de la llista de mòduls estàndard,3,A webmin.com
third_url=URL de la llista de mòduls de tercers,3,A webmin.com third_url=URL de la llista de mòduls de tercers,3,A webmin.com
cron_mode=Mostra els temps d'actualització com,1,0-Interfície simple,1-Selector de temps cron cron_mode=Mostra els temps d'actualització com,1,0-Interfície simple,1-Selector de temps cron
warn_days=Dies abans de l'expiració de la contrasenya per avisar els usuaris,0,5 warn_days=Dies abans de l'expiració de la contrasenya per avisar els usuaris,0,5
letsencrypt_cmd=Camí complet de l'ordre client de Let's Encrypt,3,Troba'l automàticament letsencrypt_cmd=Camí complet de l'ordre client ACME,3,Troba'l automàticament

View File

@@ -2,4 +2,4 @@ standard_url=URL der Standardmodul&#45;Liste,3,Von webmin.com
third_url=URL der Drittanbieter&#45;Webmin&#45;Modulliste,3,Von webmin.com third_url=URL der Drittanbieter&#45;Webmin&#45;Modulliste,3,Von webmin.com
cron_mode=Zeige Aktualisierungszeiten als,1,0-Einfache Anzeige,1-Cron&#45;Zeit&#45;Auswahl cron_mode=Zeige Aktualisierungszeiten als,1,0-Einfache Anzeige,1-Cron&#45;Zeit&#45;Auswahl
warn_days=Tage vor Ablauf des Passworts zu warnen an Benutzer,0,5 warn_days=Tage vor Ablauf des Passworts zu warnen an Benutzer,0,5
letsencrypt_cmd=Voller Pfad zum Let's Encrypt Client&#45;Befehl,0 letsencrypt_cmd=Voller Pfad zum ACME-Client&#45;Befehl,0

View File

@@ -3,6 +3,6 @@ standard_url=URL de la liste des modules standard,3,webmin.com
third_url=URL de la liste des modules non-standard,3,webmin.com third_url=URL de la liste des modules non-standard,3,webmin.com
cron_mode=Afficher les heures de mise à jour comme,1,0-Interface simple,1-Sélecteur de temps Cron cron_mode=Afficher les heures de mise à jour comme,1,0-Interface simple,1-Sélecteur de temps Cron
warn_days=Jours avant l'expiration du mot de passe pour avertir les utilisateurs,0,5 warn_days=Jours avant l'expiration du mot de passe pour avertir les utilisateurs,0,5
line2=Let's Encrypt configuration,11 line2=Configuration du fournisseur ACME,11
letsencrypt_cmd=Chemin complet de la commande client Let's Encrypt,3,Trouver automatiquement letsencrypt_cmd=Chemin complet de la commande client ACME,3,Trouver automatiquement
letsencrypt_dns_wait=Quelques secondes à attendre pour la propagation DNS de Let's Encrypt,0,5 letsencrypt_dns_wait=Quelques secondes à attendre pour la propagation DNS ACME,0,5

View File

@@ -3,6 +3,6 @@ standard_url=標準モジュールリストに使用する URL,3,webmin.com
third_url=サードパーティ製モジュールリストに使用する URL,3,webmin.com third_url=サードパーティ製モジュールリストに使用する URL,3,webmin.com
cron_mode=アップデート時刻の表示方法,1,0-シンプル,1-Cron 選択方式 cron_mode=アップデート時刻の表示方法,1,0-シンプル,1-Cron 選択方式
warn_days=ユーザのパスワード期限切れの通知(日前),0,5 warn_days=ユーザのパスワード期限切れの通知(日前),0,5
line2=Let's Encrypt の設定,11 line2=ACME プロバイダーの設定,11
letsencrypt_cmd=Let's Encrypt クライアントのパス,3,自動設定 letsencrypt_cmd=ACME クライアントのパス,3,自動設定
letsencrypt_dns_wait=Let's Encrypt DNS の更新待機時間(秒),0,5 letsencrypt_dns_wait=ACME DNS の更新待機時間(秒),0,5

View File

@@ -60,8 +60,12 @@ if (!-r $first_install_file || $miniserv{'login_script'} eq $record_login_cmd) {
$miniserv{'failed_script'} = $record_failed_cmd; $miniserv{'failed_script'} = $record_failed_cmd;
} }
# Disable trusting SSL certs unless already enabled # Disable trusting SSL certs unless already enabled. Legacy configs with
if (!$miniserv{'trust_real_ip'} && !defined($miniserv{'no_trust_ssl'})) { # trust_real_ip but no trusted proxy cannot safely authenticate from
# proxied SSL client cert headers.
my @trusted_proxies = split(/\s+/, $miniserv{'trusted_proxies'} || "");
if ((!$miniserv{'trust_real_ip'} || !@trusted_proxies) &&
!defined($miniserv{'no_trust_ssl'})) {
$miniserv{'no_trust_ssl'} = 1; $miniserv{'no_trust_ssl'} = 1;
} }