Changeset 3465101
- Timestamp:
- 02/19/2026 12:56:55 PM (3 months ago)
- Location:
- mailarchiver
- Files:
-
- 12 edited
- 1 copied
-
tags/4.5.0 (copied) (copied from mailarchiver/trunk)
-
tags/4.5.0/CHANGELOG.md (modified) (1 diff)
-
tags/4.5.0/admin/class-mailarchiver-admin.php (modified) (4 diffs)
-
tags/4.5.0/includes/system/class-form.php (modified) (2 diffs)
-
tags/4.5.0/init.php (modified) (1 diff)
-
tags/4.5.0/mailarchiver.php (modified) (1 diff)
-
tags/4.5.0/readme.txt (modified) (1 diff)
-
trunk/CHANGELOG.md (modified) (1 diff)
-
trunk/admin/class-mailarchiver-admin.php (modified) (4 diffs)
-
trunk/includes/system/class-form.php (modified) (2 diffs)
-
trunk/init.php (modified) (1 diff)
-
trunk/mailarchiver.php (modified) (1 diff)
-
trunk/readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
mailarchiver/tags/4.5.0/CHANGELOG.md
r3439734 r3465101 3 3 4 4 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and **MailArchiver** adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 5 6 ## [4.5.0] - 2026-02-19 7 8 ### Changed 9 - Once an encryption key has been defined for an archiver, it can no longer be modified. 10 11 ### Fixed 12 - [SEC006] Authenticated (Administrator+) Stored XSS vulnerability in the key encryption field / [CVE-2026-2721](https://www.cve.org/CVERecord?id=CVE-2026-2721) (thanks to Ronnachai Chaipha (rxnr) via [Wordfence](https://www.wordfence.com)). 5 13 6 14 ## [4.4.0] - 2026-01-14 -
mailarchiver/tags/4.5.0/admin/class-mailarchiver-admin.php
r2937545 r3465101 70 70 */ 71 71 protected $current_view = null; 72 73 /** 74 * Password already set "flag". 75 * 76 * @since 4.5.0 77 * @var string $password_set The "flag". 78 */ 79 private $password_set = 'password already set'; 72 80 73 81 /** … … 576 584 $this->current_archiver['privacy']['mailanonymization'] = ( array_key_exists( 'mailarchiver_archiver_privacy_mail', $_POST ) ? true : false ); 577 585 $this->current_archiver['security']['xss'] = ( array_key_exists( 'mailarchiver_archiver_security_xss', $_POST ) ? true : false ); 578 $this->current_archiver['privacy']['encryption'] = ( array_key_exists( 'mailarchiver_archiver_privacy_encryption', $_POST ) ? Secret::set( filter_input( INPUT_POST, 'mailarchiver_archiver_privacy_encryption', FILTER_UNSAFE_RAW ) ) : '' ); 579 $this->current_archiver['processors'] = []; 586 if ( array_key_exists( 'mailarchiver_archiver_privacy_encryption', $_POST ) ) { 587 $key = filter_input( INPUT_POST, 'mailarchiver_archiver_privacy_encryption', FILTER_UNSAFE_RAW ); 588 if ( $key !== $this->password_set) { 589 $this->current_archiver['privacy']['encryption'] = Secret::set( $key ); 590 } 591 } else { 592 $this->current_archiver['privacy']['encryption'] = ''; 593 } 594 $this->current_archiver['processors'] = []; 580 595 $proc = new ProcessorTypes(); 581 596 foreach ( array_reverse( $proc->get_all() ) as $processor ) { … … 1104 1119 ); 1105 1120 register_setting( 'mailarchiver_archiver_privacy_section', 'mailarchiver_archiver_privacy_mail' ); 1106 if ( PwdProtect::is_available() ) { 1107 $description = esc_html__( 'Note: this is NOT a strong security feature; it\'s just a simple way to protect privacy in case of data leaks from external services. Think about it as a simple "password protection", with the password stored in plain text in your WordPress database.', 'mailarchiver' ); 1108 $description .= '<br/>' . esc_html__( 'Encryption used:', 'mailarchiver' ) . ' ' . PwdProtect::get_encryption_details(); 1121 1122 1123 if ( '' === $this->current_archiver['privacy']['encryption'] ) { 1124 if ( PwdProtect::is_available() ) { 1125 $description = esc_html__( 'Note: this is NOT a strong security feature; it\'s just a simple way to protect privacy in case of data leaks from external services. Think about it as a simple "password protection", with the password stored in plain text in your WordPress database.', 'mailarchiver' ); 1126 $description .= '<br/>' . esc_html__( 'Encryption used:', 'mailarchiver' ) . ' ' . PwdProtect::get_encryption_details(); 1127 } else { 1128 $description = esc_html__( 'Your server does not have OpenSSL installed. Mail body encryption is unavailable.', 'mailarchiver' ); 1129 } 1130 $description = esc_html__( 'Key used to encrypt mail body: once set, you can\'t change it. Let blank to not encrypt it.', 'mailarchiver' ) . '<br/>' . $description; 1131 $enabled = PwdProtect::is_available(); 1132 $value = PwdProtect::is_available() ? Secret::get( $this->current_archiver['privacy']['encryption'] ) : ''; 1133 $readonly = false; 1109 1134 } else { 1110 $description = esc_html__( 'Your server does not have OpenSSL installed. Mail body encryption is unavailable.', 'mailarchiver' ); 1135 $description = esc_html__( 'The key is already set. You can\'t change it.', 'mailarchiver' ); 1136 $enabled = true; 1137 $readonly = true; 1138 $value = $this->password_set; 1111 1139 } 1112 1140 add_settings_field( … … 1118 1146 [ 1119 1147 'id' => 'mailarchiver_archiver_privacy_encryption', 1120 'value' => PwdProtect::is_available() ? Secret::get( $this->current_archiver['privacy']['encryption'] ) : '', 1121 'description' => esc_html__( 'Key used to encrypt mail body. Let blank to not encrypt it.', 'mailarchiver' ) . '<br/>' . $description, 1122 'full_width' => false, 1123 'enabled' => PwdProtect::is_available(), 1148 'value' => $value, 1149 'description' => $description, 1150 'full_width' => false, 1151 'enabled' => $enabled, 1152 'readonly' => $readonly, 1124 1153 ] 1125 1154 ); -
mailarchiver/tags/4.5.0/includes/system/class-form.php
r2606924 r3465101 114 114 * @param string $description Optional. A description to display. 115 115 * @param boolean $full_width Optional. Is the control full width? 116 * @param boolean $enabled Optional. Is the control enabled? 116 * @param boolean $enabled Optional. Is the control enabled? 117 * @param boolean $readonly Optional. Is the control readonly? 117 118 * @return string The HTML string ready to print. 118 119 * @since 1.0.0 119 120 */ 120 public function field_input_password( $id, $value = '', $description = null, $full_width = true, $enabled = true ) {121 if ( $full_width ) { 122 $width = ' style="width:100%;"'; 123 } else { 124 $width = ''; 125 } 126 $html = '<input' . ( $enabled ? '' : ' disabled' ) . ' name="' . $id . '" type="password" id="' . $id . '" value="' . $value . '"' . $width . ' />';121 public function field_input_password( $id, $value = '', $description = null, $full_width = true, $enabled = true, $readonly = false ) { 122 if ( $full_width ) { 123 $width = ' style="width:100%;"'; 124 } else { 125 $width = ''; 126 } 127 $html = '<input' . ( $enabled ? '' : ' disabled' ) . ' name="' . $id . '" type="password" id="' . $id . '" value="' . $value . '"' . $width . ' ' . ( $readonly ? 'readonly' : '' ) . '/>'; 127 128 if ( isset( $description ) ) { 128 129 $html .= '<p class="description">' . $description . '</p>'; … … 138 139 */ 139 140 public function echo_field_input_password( $args ) { 140 echo $this->field_input_password( $args['id'], $args['value'], $args['description'], $args['full_width'], $args['enabled'] );141 echo $this->field_input_password( $args['id'], $args['value'], $args['description'], $args['full_width'], $args['enabled'], $args['readonly'] ?? false ); 141 142 } 142 143 -
mailarchiver/tags/4.5.0/init.php
r3439734 r3465101 13 13 define( 'MAILARCHIVER_PRODUCT_ABBREVIATION', 'mailarchiver' ); 14 14 define( 'MAILARCHIVER_SLUG', 'mailarchiver' ); 15 define( 'MAILARCHIVER_VERSION', '4. 4.0' );15 define( 'MAILARCHIVER_VERSION', '4.5.0' ); 16 16 define( 'MAILARCHIVER_MONOLOG_VERSION', '2.9.3' ); 17 17 define( 'MAILARCHIVER_CODENAME', '"-"' ); -
mailarchiver/tags/4.5.0/mailarchiver.php
r3439734 r3465101 11 11 * Plugin URI: https://perfops.one/mailarchiver 12 12 * Description: Automatically archive and store all emails sent from your site. 13 * Version: 4. 4.013 * Version: 4.5.0 14 14 * Requires at least: 6.2 15 15 * Requires PHP: 8.1 -
mailarchiver/tags/4.5.0/readme.txt
r3439734 r3465101 5 5 Requires PHP: 8.1 6 6 Tested up to: 6.9 7 Stable tag: 4. 4.07 Stable tag: 4.5.0 8 8 License: GPLv3 9 9 License URI: https://www.gnu.org/licenses/gpl-3.0.html -
mailarchiver/trunk/CHANGELOG.md
r3439734 r3465101 3 3 4 4 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and **MailArchiver** adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 5 6 ## [4.5.0] - 2026-02-19 7 8 ### Changed 9 - Once an encryption key has been defined for an archiver, it can no longer be modified. 10 11 ### Fixed 12 - [SEC006] Authenticated (Administrator+) Stored XSS vulnerability in the key encryption field / [CVE-2026-2721](https://www.cve.org/CVERecord?id=CVE-2026-2721) (thanks to Ronnachai Chaipha (rxnr) via [Wordfence](https://www.wordfence.com)). 5 13 6 14 ## [4.4.0] - 2026-01-14 -
mailarchiver/trunk/admin/class-mailarchiver-admin.php
r2937545 r3465101 70 70 */ 71 71 protected $current_view = null; 72 73 /** 74 * Password already set "flag". 75 * 76 * @since 4.5.0 77 * @var string $password_set The "flag". 78 */ 79 private $password_set = 'password already set'; 72 80 73 81 /** … … 576 584 $this->current_archiver['privacy']['mailanonymization'] = ( array_key_exists( 'mailarchiver_archiver_privacy_mail', $_POST ) ? true : false ); 577 585 $this->current_archiver['security']['xss'] = ( array_key_exists( 'mailarchiver_archiver_security_xss', $_POST ) ? true : false ); 578 $this->current_archiver['privacy']['encryption'] = ( array_key_exists( 'mailarchiver_archiver_privacy_encryption', $_POST ) ? Secret::set( filter_input( INPUT_POST, 'mailarchiver_archiver_privacy_encryption', FILTER_UNSAFE_RAW ) ) : '' ); 579 $this->current_archiver['processors'] = []; 586 if ( array_key_exists( 'mailarchiver_archiver_privacy_encryption', $_POST ) ) { 587 $key = filter_input( INPUT_POST, 'mailarchiver_archiver_privacy_encryption', FILTER_UNSAFE_RAW ); 588 if ( $key !== $this->password_set) { 589 $this->current_archiver['privacy']['encryption'] = Secret::set( $key ); 590 } 591 } else { 592 $this->current_archiver['privacy']['encryption'] = ''; 593 } 594 $this->current_archiver['processors'] = []; 580 595 $proc = new ProcessorTypes(); 581 596 foreach ( array_reverse( $proc->get_all() ) as $processor ) { … … 1104 1119 ); 1105 1120 register_setting( 'mailarchiver_archiver_privacy_section', 'mailarchiver_archiver_privacy_mail' ); 1106 if ( PwdProtect::is_available() ) { 1107 $description = esc_html__( 'Note: this is NOT a strong security feature; it\'s just a simple way to protect privacy in case of data leaks from external services. Think about it as a simple "password protection", with the password stored in plain text in your WordPress database.', 'mailarchiver' ); 1108 $description .= '<br/>' . esc_html__( 'Encryption used:', 'mailarchiver' ) . ' ' . PwdProtect::get_encryption_details(); 1121 1122 1123 if ( '' === $this->current_archiver['privacy']['encryption'] ) { 1124 if ( PwdProtect::is_available() ) { 1125 $description = esc_html__( 'Note: this is NOT a strong security feature; it\'s just a simple way to protect privacy in case of data leaks from external services. Think about it as a simple "password protection", with the password stored in plain text in your WordPress database.', 'mailarchiver' ); 1126 $description .= '<br/>' . esc_html__( 'Encryption used:', 'mailarchiver' ) . ' ' . PwdProtect::get_encryption_details(); 1127 } else { 1128 $description = esc_html__( 'Your server does not have OpenSSL installed. Mail body encryption is unavailable.', 'mailarchiver' ); 1129 } 1130 $description = esc_html__( 'Key used to encrypt mail body: once set, you can\'t change it. Let blank to not encrypt it.', 'mailarchiver' ) . '<br/>' . $description; 1131 $enabled = PwdProtect::is_available(); 1132 $value = PwdProtect::is_available() ? Secret::get( $this->current_archiver['privacy']['encryption'] ) : ''; 1133 $readonly = false; 1109 1134 } else { 1110 $description = esc_html__( 'Your server does not have OpenSSL installed. Mail body encryption is unavailable.', 'mailarchiver' ); 1135 $description = esc_html__( 'The key is already set. You can\'t change it.', 'mailarchiver' ); 1136 $enabled = true; 1137 $readonly = true; 1138 $value = $this->password_set; 1111 1139 } 1112 1140 add_settings_field( … … 1118 1146 [ 1119 1147 'id' => 'mailarchiver_archiver_privacy_encryption', 1120 'value' => PwdProtect::is_available() ? Secret::get( $this->current_archiver['privacy']['encryption'] ) : '', 1121 'description' => esc_html__( 'Key used to encrypt mail body. Let blank to not encrypt it.', 'mailarchiver' ) . '<br/>' . $description, 1122 'full_width' => false, 1123 'enabled' => PwdProtect::is_available(), 1148 'value' => $value, 1149 'description' => $description, 1150 'full_width' => false, 1151 'enabled' => $enabled, 1152 'readonly' => $readonly, 1124 1153 ] 1125 1154 ); -
mailarchiver/trunk/includes/system/class-form.php
r2606924 r3465101 114 114 * @param string $description Optional. A description to display. 115 115 * @param boolean $full_width Optional. Is the control full width? 116 * @param boolean $enabled Optional. Is the control enabled? 116 * @param boolean $enabled Optional. Is the control enabled? 117 * @param boolean $readonly Optional. Is the control readonly? 117 118 * @return string The HTML string ready to print. 118 119 * @since 1.0.0 119 120 */ 120 public function field_input_password( $id, $value = '', $description = null, $full_width = true, $enabled = true ) {121 if ( $full_width ) { 122 $width = ' style="width:100%;"'; 123 } else { 124 $width = ''; 125 } 126 $html = '<input' . ( $enabled ? '' : ' disabled' ) . ' name="' . $id . '" type="password" id="' . $id . '" value="' . $value . '"' . $width . ' />';121 public function field_input_password( $id, $value = '', $description = null, $full_width = true, $enabled = true, $readonly = false ) { 122 if ( $full_width ) { 123 $width = ' style="width:100%;"'; 124 } else { 125 $width = ''; 126 } 127 $html = '<input' . ( $enabled ? '' : ' disabled' ) . ' name="' . $id . '" type="password" id="' . $id . '" value="' . $value . '"' . $width . ' ' . ( $readonly ? 'readonly' : '' ) . '/>'; 127 128 if ( isset( $description ) ) { 128 129 $html .= '<p class="description">' . $description . '</p>'; … … 138 139 */ 139 140 public function echo_field_input_password( $args ) { 140 echo $this->field_input_password( $args['id'], $args['value'], $args['description'], $args['full_width'], $args['enabled'] );141 echo $this->field_input_password( $args['id'], $args['value'], $args['description'], $args['full_width'], $args['enabled'], $args['readonly'] ?? false ); 141 142 } 142 143 -
mailarchiver/trunk/init.php
r3439734 r3465101 13 13 define( 'MAILARCHIVER_PRODUCT_ABBREVIATION', 'mailarchiver' ); 14 14 define( 'MAILARCHIVER_SLUG', 'mailarchiver' ); 15 define( 'MAILARCHIVER_VERSION', '4. 4.0' );15 define( 'MAILARCHIVER_VERSION', '4.5.0' ); 16 16 define( 'MAILARCHIVER_MONOLOG_VERSION', '2.9.3' ); 17 17 define( 'MAILARCHIVER_CODENAME', '"-"' ); -
mailarchiver/trunk/mailarchiver.php
r3439734 r3465101 11 11 * Plugin URI: https://perfops.one/mailarchiver 12 12 * Description: Automatically archive and store all emails sent from your site. 13 * Version: 4. 4.013 * Version: 4.5.0 14 14 * Requires at least: 6.2 15 15 * Requires PHP: 8.1 -
mailarchiver/trunk/readme.txt
r3439734 r3465101 5 5 Requires PHP: 8.1 6 6 Tested up to: 6.9 7 Stable tag: 4. 4.07 Stable tag: 4.5.0 8 8 License: GPLv3 9 9 License URI: https://www.gnu.org/licenses/gpl-3.0.html
Note: See TracChangeset
for help on using the changeset viewer.
