close

Plugin Directory

Changeset 3465101


Ignore:
Timestamp:
02/19/2026 12:56:55 PM (3 months ago)
Author:
PierreLannoy
Message:

MailArchiver 4.5.0 released from GitHub

Location:
mailarchiver
Files:
12 edited
1 copied

Legend:

Unmodified
Added
Removed
  • mailarchiver/tags/4.5.0/CHANGELOG.md

    r3439734 r3465101  
    33
    44The 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)).
    513
    614## [4.4.0] - 2026-01-14
  • mailarchiver/tags/4.5.0/admin/class-mailarchiver-admin.php

    r2937545 r3465101  
    7070     */
    7171    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';
    7280
    7381    /**
     
    576584                    $this->current_archiver['privacy']['mailanonymization'] = ( array_key_exists( 'mailarchiver_archiver_privacy_mail', $_POST ) ? true : false );
    577585                    $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'] = [];
    580595                    $proc = new ProcessorTypes();
    581596                    foreach ( array_reverse( $proc->get_all() ) as $processor ) {
     
    11041119        );
    11051120        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;
    11091134        } 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;
    11111139        }
    11121140        add_settings_field(
     
    11181146            [
    11191147                '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,
    11241153            ]
    11251154        );
  • mailarchiver/tags/4.5.0/includes/system/class-form.php

    r2606924 r3465101  
    114114     * @param   string  $description    Optional. A description to display.
    115115     * @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?
    117118     * @return  string The HTML string ready to print.
    118119     * @since   1.0.0
    119120     */
    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' : '' ) . '/>';
    127128        if ( isset( $description ) ) {
    128129            $html .= '<p class="description">' . $description . '</p>';
     
    138139     */
    139140    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 );
    141142    }
    142143
  • mailarchiver/tags/4.5.0/init.php

    r3439734 r3465101  
    1313define( 'MAILARCHIVER_PRODUCT_ABBREVIATION', 'mailarchiver' );
    1414define( 'MAILARCHIVER_SLUG', 'mailarchiver' );
    15 define( 'MAILARCHIVER_VERSION', '4.4.0' );
     15define( 'MAILARCHIVER_VERSION', '4.5.0' );
    1616define( 'MAILARCHIVER_MONOLOG_VERSION', '2.9.3' );
    1717define( 'MAILARCHIVER_CODENAME', '"-"' );
  • mailarchiver/tags/4.5.0/mailarchiver.php

    r3439734 r3465101  
    1111 * Plugin URI:        https://perfops.one/mailarchiver
    1212 * Description:       Automatically archive and store all emails sent from your site.
    13  * Version:           4.4.0
     13 * Version:           4.5.0
    1414 * Requires at least: 6.2
    1515 * Requires PHP:      8.1
  • mailarchiver/tags/4.5.0/readme.txt

    r3439734 r3465101  
    55Requires PHP: 8.1
    66Tested up to: 6.9
    7 Stable tag: 4.4.0
     7Stable tag: 4.5.0
    88License: GPLv3
    99License URI: https://www.gnu.org/licenses/gpl-3.0.html
  • mailarchiver/trunk/CHANGELOG.md

    r3439734 r3465101  
    33
    44The 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)).
    513
    614## [4.4.0] - 2026-01-14
  • mailarchiver/trunk/admin/class-mailarchiver-admin.php

    r2937545 r3465101  
    7070     */
    7171    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';
    7280
    7381    /**
     
    576584                    $this->current_archiver['privacy']['mailanonymization'] = ( array_key_exists( 'mailarchiver_archiver_privacy_mail', $_POST ) ? true : false );
    577585                    $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'] = [];
    580595                    $proc = new ProcessorTypes();
    581596                    foreach ( array_reverse( $proc->get_all() ) as $processor ) {
     
    11041119        );
    11051120        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;
    11091134        } 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;
    11111139        }
    11121140        add_settings_field(
     
    11181146            [
    11191147                '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,
    11241153            ]
    11251154        );
  • mailarchiver/trunk/includes/system/class-form.php

    r2606924 r3465101  
    114114     * @param   string  $description    Optional. A description to display.
    115115     * @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?
    117118     * @return  string The HTML string ready to print.
    118119     * @since   1.0.0
    119120     */
    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' : '' ) . '/>';
    127128        if ( isset( $description ) ) {
    128129            $html .= '<p class="description">' . $description . '</p>';
     
    138139     */
    139140    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 );
    141142    }
    142143
  • mailarchiver/trunk/init.php

    r3439734 r3465101  
    1313define( 'MAILARCHIVER_PRODUCT_ABBREVIATION', 'mailarchiver' );
    1414define( 'MAILARCHIVER_SLUG', 'mailarchiver' );
    15 define( 'MAILARCHIVER_VERSION', '4.4.0' );
     15define( 'MAILARCHIVER_VERSION', '4.5.0' );
    1616define( 'MAILARCHIVER_MONOLOG_VERSION', '2.9.3' );
    1717define( 'MAILARCHIVER_CODENAME', '"-"' );
  • mailarchiver/trunk/mailarchiver.php

    r3439734 r3465101  
    1111 * Plugin URI:        https://perfops.one/mailarchiver
    1212 * Description:       Automatically archive and store all emails sent from your site.
    13  * Version:           4.4.0
     13 * Version:           4.5.0
    1414 * Requires at least: 6.2
    1515 * Requires PHP:      8.1
  • mailarchiver/trunk/readme.txt

    r3439734 r3465101  
    55Requires PHP: 8.1
    66Tested up to: 6.9
    7 Stable tag: 4.4.0
     7Stable tag: 4.5.0
    88License: GPLv3
    99License URI: https://www.gnu.org/licenses/gpl-3.0.html
Note: See TracChangeset for help on using the changeset viewer.