Headline
CVE-2023-4482: Diff [2896127:2961861] for amazon-auto-links/trunk – WordPress Plugin Repository
The Auto Amazon Links plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the style parameter in versions up to, and including, 5.3.1 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers with contributor access to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
amazon-auto-links/trunk/amazon-auto-links.php
r2896127
r2961861
6
6
\* Author: Michael Uno (miunosoft)
7
7
\* Author URI: https://michaeluno.jp
8
\* Version: 5.4.0b02
8
\* Version: 5.3.2
9
9
\* Text Domain: amazon-auto-links
10
10
\* Domain Path: /language
…
…
19
19
\*/
20
20
class AmazonAutoLinks\_Registry\_Base {
21
const VERSION = '5.4.0b02'; // <--- DON'T FORGET TO CHANGE THIS AS WELL!!
21
const VERSION = '5.3.2'; // <--- DON'T FORGET TO CHANGE THIS AS WELL!!
22
22
const NAME = 'Auto Amazon Links';
23
23
const DESCRIPTION = 'Formerly, Amazon Auto Links. The plugin generates links of Amazon products just coming out today. You just pick categories and they appear even in JavaScript disabled browsers.';
amazon-auto-links/trunk/include/core/component/button/button_type/classic/admin/post_meta_box/AmazonAutoLinks_PostMetaBox_Button_CSS.php
r2896127
r2961861
22
22
);
23
23
24
/\*\*
25
\* Validates submitted form data.
26
\* @since 5.3.2
27
\*/
28
public function validate( $aInputs, $aOldInputs, $oFactory ) {
29
// Prevent script injections
30
$aInputs\[ 'button\_css' \] = strip\_tags( $aInputs\[ 'button\_css' \] );
31
$aInputs\[ 'custom\_css' \] = strip\_tags( $aInputs\[ 'custom\_css' \] );
32
return $aInputs;
33
}
34
24
35
}
amazon-auto-links/trunk/include/core/component/button/button_type/flat/admin/post_meta_box/AmazonAutoLinks_Button_Flat_PostMetaBox_CSS.php
r2896127
r2961861
23
23
'AmazonAutoLinks\_Button\_Flat\_FormFields\_CSS',
24
24
);
25
25
26
/\*\*
27
\* Validates submitted form data.
28
\* @since 5.3.2
29
\*/
30
public function validate( $aInputs, $aOldInputs, $oFactory ) {
31
// Prevent script injections
32
$aInputs\[ 'button\_css' \] = strip\_tags( $aInputs\[ 'button\_css' \] );
33
$aInputs\[ 'custom\_css' \] = strip\_tags( $aInputs\[ 'custom\_css' \] );
34
return $aInputs;
35
}
36
26
37
}
amazon-auto-links/trunk/include/core/component/button/button_type/image/admin/post_meta_box/AmazonAutoLinks_Button_Image_PostMetaBox_CSS.php
r2896127
r2961861
23
23
'AmazonAutoLinks\_Button\_Image\_FormFields\_CSS',
24
24
);
25
25
26
/\*\*
27
\* Validates submitted form data.
28
\* @since 5.3.2
29
\*/
30
public function validate( $aInputs, $aOldInputs, $oFactory ) {
31
// Prevent script injections
32
$aInputs\[ 'button\_css' \] = strip\_tags( $aInputs\[ 'button\_css' \] );
33
$aInputs\[ 'custom\_css' \] = strip\_tags( $aInputs\[ 'custom\_css' \] );
34
return $aInputs;
35
}
36
26
37
}
amazon-auto-links/trunk/include/core/component/unit/unit_type/contextual/admin/form_field/AmazonAutoLinks_FormFields_ContextualUnit_Main.php
r2896127
r2961861
28
28
array(
29
29
'field\_id' => $sFieldIDPrefix . 'criteria',
30
'title' => \_\_( 'Criteria', 'amazon-auto-links' ),
31
'type' => 'revealer',
32
'select\_type' => 'checkbox',
30
'title' => \_\_( 'Additional Criteria', 'amazon-auto-links' ),
31
'type' => 'checkbox',
33
32
'label' => array(
34
33
'post\_title' => \_\_( 'Post Title', 'amazon-auto-links' ),
35
34
'taxonomy\_terms' => \_\_( 'Taxonomy Terms', 'amazon-auto-links' ),
36
35
'breadcrumb' => \_\_( 'Breadcrumb', 'amazon-auto-links' ),
37
'site\_title' => \_\_( 'Site Title', 'amazon-auto-links' ),
38
'url\_query' => \_\_( 'URL Query', 'amazon-auto-links' ),
39
'post\_meta' => \_\_( 'Post Meta', 'amazon-auto-links' ),
40
36
),
41
37
'default' => array(
…
…
43
39
'taxonomy\_terms' => true,
44
40
'breadcrumb' => false,
45
'site\_title' => false,
46
'url\_query' => false,
47
'post\_meta' => false,
48
41
),
49
'selectors' => array(
50
'url\_query' => '.fieldrow\_http\_query\_parameters',
51
'post\_meta' => '.fieldrow\_post\_meta\_keys',
52
),
53
),
54
array( // 5.4.0
55
'field\_id' => $sFieldIDPrefix . 'http\_query\_parameters',
56
'title' => \_\_( 'URL Query Keys', 'amazon-auto-links' ),
57
'type' => 'text',
58
'attributes' => array(
59
'class' => 'width-full',
60
),
61
'repeatable' => true,
62
'tip' => array(
63
\_\_( 'The parameter of the GET HTTP request seen in URLs to be used as a search keyword.', 'amazon-auto-links' ), ),
64
'hidden' => true,
65
'class' => array(
66
'fieldrow' => 'fieldrow\_http\_query\_parameters',
67
),
68
),
69
array( // 5.4.0
70
'field\_id' => $sFieldIDPrefix . 'post\_meta\_keys',
71
'title' => \_\_( 'Post Meta Keys', 'amazon-auto-links' ),
72
'type' => 'text',
73
'attributes' => array(
74
'class' => 'width-full',
75
),
76
'repeatable' => true,
77
'tip' => array(
78
\_\_( 'Set the post meta key names known as custom fields whose value will be used as a search keyword.', 'amazon-auto-links' ),
79
),
80
'hidden' => true,
81
'class' => array(
82
'fieldrow' => 'fieldrow\_post\_meta\_keys',
83
),
84
),
85
array( // 5.4.0
86
'field\_id' => $sFieldIDPrefix . 'concatenate\_keywords',
87
'title' => \_\_( 'Concatenate', 'amazon-auto-links' ),
88
'type' => 'checkbox',
89
'label' => \_\_( 'Concatenate multiple keywords to perform search at once rather than with a single word multiple times.', 'amazon-auto-links' ),
90
// 'hidden' => true,
91
// 'class' => array(
92
// 'fieldrow' => 'fieldrow\_concatenate\_keywords',
93
// ),
94
42
),
95
43
array(
amazon-auto-links/trunk/include/core/component/unit/unit_type/contextual/admin/post_meta_box/AmazonAutoLinks_UnitPostMetaBox_Main_contextual.php
r2896127
r2961861
49
49
public function validate( $aInputs, $aOldInputs, $oFactory ) {
50
50
51
// $\_aErrors = array();
52
// $\_bVerified = true;
53
51
$\_aErrors = array();
52
$\_bVerified = true;
53
54
54
// Formats the options
55
$\_oUnitOption = new AmazonAutoLinks\_UnitOption\_contextual( null, $aInputs );
55
$\_oUnitOption = new AmazonAutoLinks\_UnitOption\_contextual(
56
null,
57
$aInputs
58
);
56
59
$\_aFormatted = $\_oUnitOption->get();
57
60
58
61
// An invalid value is found.
59
// if ( ! $\_bVerified ) {
60
//
61
// // Set the error array for the input fields.
62
// $oFactory->setFieldErrors( $\_aErrors );
63
// $oFactory->setSettingNotice( \_\_( 'There was an error in your input.', 'amazon-auto-links' ) );
64
// return $aInputs;
65
//
66
// }
62
if ( ! $\_bVerified ) {
63
64
// Set the error array for the input fields.
65
$oFactory->setFieldErrors( $\_aErrors );
66
$oFactory->setSettingNotice( \_\_( 'There was an error in your input.', 'amazon-auto-links' ) );
67
return $aInputs;
68
69
}
67
70
68
71
// Drop unset keys.
amazon-auto-links/trunk/include/core/component/unit/unit_type/contextual/option/AmazonAutoLinks_UnitOption_contextual.php
r2896127
r2961861
30
30
'taxonomy\_terms' => true,
31
31
'breadcrumb' => false,
32
'site\_title' => false, // 5.4.0
33
'url\_query' => false, // 5.4.0
34
'post\_meta' => false, // 5.4.0
35
32
),
36
'http\_query\_parameters' => array(), // 5.4.0
37
'post\_meta\_keys' => array(), // 5.4.0
38
'concatenate\_keywords' => false, // 5.4.0
39
33
'additional\_keywords' => '',
40
34
'excluding\_keywords' => '', // 3.12.0
…
…
47
41
48
42
/\*\*
43
\*
49
44
\* @return array
50
45
\*/
…
…
54
49
}
55
50
56
/\*\*
57
\* @param array $aUnitOptions
58
\* @param array $aDefaults
59
\* @param array $aRawOptions
60
\* @return array
61
\* @since 5.4.0
62
\*/
63
protected function \_getUnitOptionsFormatted( array $aUnitOptions, array $aDefaults, array $aRawOptions ) {
64
$aUnitOptions\[ 'http\_query\_parameters' \] = array\_values( array\_unique( array\_filter( $this->getElementAsArray( $aUnitOptions, 'http\_query\_parameters' ) ) ) ); // drop empty elements & reorder the keys
65
$aUnitOptions\[ 'post\_meta\_keys' \] = array\_values( array\_unique( array\_filter( $this->getElementAsArray( $aUnitOptions, 'post\_meta\_keys' ) ) ) ); // drop empty elements & reorder the keys
66
return parent::\_getUnitOptionsFormatted( $aUnitOptions, $aDefaults, $aRawOptions );
67
}
68
69
51
}
amazon-auto-links/trunk/include/core/component/unit/unit_type/contextual/output/AmazonAutoLinks_ContextualUnit_SearchKeyword.php
r2896127
r2961861
18
18
class AmazonAutoLinks\_ContextualUnit\_SearchKeyword extends AmazonAutoLinks\_PluginUtility {
19
19
20
/\*\*
21
\* @var AmazonAutoLinks\_UnitOption\_Base
22
\*/
23
public $oUnitOption;
24
25
public $aCriteria = array(
26
// 1 or 0 as string (saved form value)
27
'post\_title' => '0',
28
'site\_title' => '0',
29
'taxonomy\_terms' => '0',
30
'breadcrumb' => '0',
31
'url\_query' => '0',
32
'post\_meta' => '0',
33
);
20
public $aCriteria = array();
34
21
public $sAdditionalKeywords = '';
35
public $sExcludingKeywords = ''; // 3.12.0
36
public $aQueryKeys = array(); // 5.4.0
37
public $aPostMetaKeys = array(); // 5.4.0
22
public $sExcludingKeywords = ''; // 3.12.0
38
23
39
24
private $\_\_\_oPost;
…
…
42
27
/\*\*
43
28
\* Sets up properties.
44
\* @since 3
45
\* @since 5.4.1 Removed all the parameters and replaced them with a unit option object.
46
29
\*/
47
public function \_\_construct( $oUnitOption ) {
30
public function \_\_construct( array $aCriteria, $sAdditionalKeywords='', $sExcludingKeywords='' ) {
48
31
49
$this->oUnitOption = $oUnitOption;
50
$this->aCriteria = $oUnitOption->get( 'criteria' ) + $this->aCriteria;
51
$this->sAdditionalKeywords = $oUnitOption->get( 'additional\_keywords' );
52
$this->sExcludingKeywords = $oUnitOption->get( 'excluding\_keywords' );
53
$this->aQueryKeys = array\_filter( $this->getAsArray( $oUnitOption->get( 'http\_query\_parameters' ) ) );
54
$this->aPostMetaKeys = array\_filter( $this->getAsArray( $oUnitOption->get( 'post\_meta\_keys' ) ) );
32
$this->aCriteria = $aCriteria;
33
$this->sAdditionalKeywords = $sAdditionalKeywords;
34
$this->sExcludingKeywords = $sExcludingKeywords;
55
35
56
36
// Allow ajax unit loading to set referrer's request
57
$this->\_\_\_oPost = apply\_filters( 'aal\_filter\_post\_object', $this->getElement( $GLOBALS, 'post' ) );
58
59
// Currently, only the \`s\` URL query parameter is used
37
$this->\_\_\_oPost = apply\_filters(
38
'aal\_filter\_post\_object',
39
$this->getElement( $GLOBALS, 'post' )
40
);
41
// Currently, only the \`s\` element is used
60
42
$\_aGET = array(
61
43
's' => \_sanitize\_text\_fields( $this->getElement( $\_GET, array( 's' ) ) ), // sanitization done
62
44
);
63
45
$this->\_\_\_aGET = apply\_filters( 'aal\_filter\_http\_get', $\_aGET );
64
65
46
}
66
47
67
48
/\*\*
68
\* @return array The search keywords.
49
\*
50
\* @return array The search keywords.
69
51
\*/
70
52
public function get() {
71
53
72
54
$\_aKeywords = $this->\_\_\_getSearchKeywordsByCriteria( $this->aCriteria );
73
$\_aKeywords = array\_merge(
74
$\_aKeywords,
75
$this->\_\_\_getSiteSearchKeywords(),
76
$this->getStringIntoArray( $this->sAdditionalKeywords, ',' )
77
);
55
$\_aKeywords = array\_merge( $\_aKeywords, $this->\_\_\_getSiteSearchKeywords() );
56
$\_aKeywords = $this->\_\_\_getFormattedSearchKeywordsArray( $\_aKeywords );
57
58
$\_aAdditionalWords = $this->getStringIntoArray( $this->sAdditionalKeywords, ',' );
59
$\_aKeywords = array\_merge( $\_aKeywords, $\_aAdditionalWords );
60
78
61
$\_aExcludeWords = $this->getStringIntoArray( $this->sExcludingKeywords, ',' );
62
$\_aKeywords = array\_udiff( $\_aKeywords, $\_aExcludeWords, 'strcasecmp' ); // case-insensitive
79
63
80
// Formatting - remove blocked characters and sanitize doubled whitespaces
81
foreach ( $\_aKeywords as $\_i => $\_sKeyword ) {
82
foreach( $\_aExcludeWords as $\_sExcludeWord ) {
83
$\_sKeyword = str\_ireplace( $\_sExcludeWord, '', $\_sKeyword ); // remove the excluding characters.
84
}
85
$\_aKeywords\[ $\_i \] = preg\_replace('/\\s+/', ' ', $\_sKeyword );
86
}
87
// @deprecated 5.4.0 As more contexts are used, phrases can be passed and a word in a phrase should be removed, not exact match of a word.
88
// $\_aKeywords = array\_udiff( $\_aKeywords, $\_aExcludeWords, 'strcasecmp' ); // case-insensitive
89
return array\_unique( $\_aKeywords );
64
$\_aKeywords = array\_unique( $\_aKeywords );
65
return $\_aKeywords;
90
66
91
67
}
92
68
93
69
/\*\*
94
\* @return array
70
\* @return array
95
71
\*/
96
72
private function \_\_\_getSiteSearchKeywords() {
73
74
$\_sQuery = $this->getElement( $this->\_\_\_aGET, 's' );
97
75
$\_sQuery = str\_replace(
98
76
array( '+' ),
99
77
',',
100
$this->getElement( $this->\_\_\_aGET, 's' )
78
$\_sQuery
101
79
);
102
return array\_filter( explode( ',', $\_sQuery ) );
80
return explode( ',', $\_sQuery );
81
103
82
}
104
83
105
84
/\*\*
106
\* @return array
107
\* @deprecated 5.4.0
85
\*
86
\* @return array
108
87
\*/
109
// private function \_\_\_getFormattedSearchKeywordsArray( array $aKeywords ) {
110
// $aKeywords = array\_unique( array\_filter( $aKeywords ) );
111
// if ( empty( $aKeywords ) ) {
112
// $aKeywords\[\] = get\_bloginfo( 'name' );
113
// }
114
// return $aKeywords;
115
// }
88
private function \_\_\_getFormattedSearchKeywordsArray( array $aKeywords ) {
89
$aKeywords = array\_unique( array\_filter( $aKeywords ) );
90
if ( empty( $aKeywords ) ) {
91
$aKeywords\[\] = get\_bloginfo( 'name' );
92
}
93
return $aKeywords;
94
}
116
95
117
96
/\*\*
118
\*
119
\* @since 3
120
\* @param array $aCriteria
97
\*
98
\* @since 3
99
\* @param array $aCriteria
121
100
\* The structure:
122
\* \`\`\`
123
101
\* array(
124
102
\* 'post\_title' => true,
125
103
\* 'breadcrumb' => true,
126
104
\* 'taxonomy\_terms' => true,
127
\* 'site\_title' => true,
128
105
\* )
129
\* \`\`\`
130
\* @return array
106
\* @return array
131
107
\*/
132
108
private function \_\_\_getSearchKeywordsByCriteria( array $aCriteria ) {
109
133
110
$\_aKeywords = array();
134
111
foreach( $this->\_\_\_getFormattedCriteriaArray( $aCriteria ) as $\_sCriteriaKey ) {
…
…
141
118
}
142
119
return $\_aKeywords;
120
143
121
}
144
122
/\*\*
145
\* @since 3
146
\* @return array
123
\*
124
\* @since 3
125
\* @return array
147
126
\*/
148
127
private function \_\_\_getFormattedCriteriaArray( array $aCriteria ) {
149
return array\_keys( array\_filter( $aCriteria ) );
128
return array\_keys(
129
array\_filter( $aCriteria )
130
);
150
131
}
151
132
/\*\*
152
\* @since 5.4.0
153
\* @return array
154
\*/
155
private function \_\_\_getSearchKeywordsByType\_post\_meta() {
156
$\_aKeywords = array();
157
foreach( $this->aPostMetaKeys as $\_sPostMetaKey ) {
158
if ( ! isset( $this->\_\_\_oPost->ID ) ) {
159
continue;
160
}
161
$\_sKeyword = get\_post\_meta( $this->\_\_\_oPost->ID, $\_sPostMetaKey, true );
162
if ( empty( $\_sKeyword ) ) {
163
continue;
164
}
165
$\_aKeywords\[\] = $\_sKeyword;
166
}
167
return $\_aKeywords;
168
}
169
/\*\*
170
\* @since 5.4.0
171
\* @return array
172
\*/
173
private function \_\_\_getSearchKeywordsByType\_url\_query() {
174
$\_aKeywords = array();
175
foreach( $this->aQueryKeys as $\_sQueryKey ) {
176
$\_sKeyword = trim( sanitize\_text\_field( $this->getElement( $\_GET, $\_sQueryKey ) ) ); // sanitization done
177
if ( empty( $\_sKeyword ) ) {
178
continue;
179
}
180
$\_aKeywords\[\] = $\_sKeyword;
181
}
182
return $\_aKeywords;
183
}
184
/\*\*
185
\* @since 5.4.0
186
\* @return array
187
\*/
188
private function \_\_\_getSearchKeywordsByType\_site\_title() {
189
return array( get\_bloginfo( 'name' ) );
190
}
191
/\*\*
192
\* @since 3
193
\* @return array
133
\*
134
\* @since 3
135
\* @return array
194
136
\*/
195
137
private function \_\_\_getSearchKeywordsByType\_post\_title() {
…
…
200
142
201
143
/\*\*
202
\* @since 3
203
\* @return array
144
\*
145
\* @since 3
146
\* @return array
204
147
\*/
205
148
private function \_\_\_getSearchKeywordsByType\_breadcrumb() {
…
…
212
155
213
156
/\*\*
214
\* @since 3
215
\* @return array
157
\*
158
\* @since 3
159
\* @return array
216
160
\*/
217
161
private function \_\_\_getSearchKeywordsByType\_taxonomy\_terms() {
…
…
222
166
223
167
// Retrieve associated taxonomies.
224
$\_aTaxonomyObjects = get\_object\_taxonomies( $this->\_\_\_oPost->post\_type, 'objects' );
168
$\_aTaxonomyObjects = get\_object\_taxonomies(
169
$this->\_\_\_oPost->post\_type,
170
'objects'
171
);
225
172
226
173
// Generate current taxonomy terms.
227
$\_aTaxonomyNames = array();
174
$\_aTaxoomyNames = array();
228
175
foreach( $\_aTaxonomyObjects as $\_sKey => $\_oTaxonomy ) {
229
176
if ( ! $\_oTaxonomy->public ) {
230
177
continue;
231
178
}
232
$\_aTaxonomyNames\[\] = $\_oTaxonomy->name;
179
$\_aTaxoomyNames\[\] = $\_oTaxonomy->name;
233
180
}
234
181
$\_aTermsObjects = wp\_get\_post\_terms(
235
182
$this->\_\_\_oPost->ID,
236
$\_aTaxonomyNames
183
$\_aTaxoomyNames
237
184
);
238
185
186
239
187
$\_aTerms = array();
240
188
foreach( $\_aTermsObjects as $\_oTerm ) {
241
if ( 'uncategorized' === $\_oTerm->slug ) {
189
if ( in\_array( 'uncategorized', array( $\_oTerm->slug ) ) ) {
242
190
continue;
243
191
}
amazon-auto-links/trunk/include/core/component/unit/unit_type/contextual/output/AmazonAutoLinks_UnitOutput_contextual.php
r2896127
r2961861
56
56
private function \_\_\_getKeywords() {
57
57
58
$\_oContextualSearch = new AmazonAutoLinks\_ContextualUnit\_SearchKeyword( $this->oUnitOption );
58
$\_oContextualSearch = new AmazonAutoLinks\_ContextualUnit\_SearchKeyword(
59
$this->oUnitOption->get( 'criteria' ),
60
$this->oUnitOption->get( 'additional\_keywords' ),
61
$this->oUnitOption->get( 'excluding\_keywords' )
62
);
59
63
$\_aSearchKeywords = $\_oContextualSearch->get(); // get as an array
60
64
61
if ( $this->oUnitOption->get( 'concatenate\_keywords' ) ) {
62
$\_aSearchKeywords = array( implode( ' ', $\_aSearchKeywords ) );
63
}
64
65
// @todo make these optional
66
65
shuffle( $\_aSearchKeywords );
67
66
array\_splice( $\_aSearchKeywords, 5 ); // up to 5 keywords.
amazon-auto-links/trunk/include/core/component/widget/contextual/AmazonAutoLinks_ContextualProductWidget.php
r2896127
r2961861
158
158
$this->\_\_\_addFieldsByFieldClass( $\_aClasses );
159
159
160
// Register custom filed type.
161
new AmazonAutoLinks\_RevealerCustomFieldType( $oFactory->oProp->sClassName );
162
163
160
// Product filters
164
161
$this->addSettingSections(
…
…
291
288
// Sanitize the form inputs.
292
289
$\_oItemFormatValidator = new AmazonAutoLinks\_FormValidator\_ItemFormat( $aSubmit, $aStored );
293
$aSubmit = $\_oItemFormatValidator->get();
294
295
// Formats the options
296
$\_oUnitOption = new AmazonAutoLinks\_UnitOption\_contextual( null, $aSubmit );
297
return $\_oUnitOption->get();
298
290
$aSubmit = $\_oItemFormatValidator->get();
291
return $aSubmit;
292
299
293
}
300
294
…
…
345
339
'breadcrumb' => null,
346
340
'taxonomy\_terms' => null,
347
'site\_title' => null,
348
'url\_query' => null,
349
'post\_meta' => null,
350
341
),
351
'http\_query\_parameters' => array(), // 5.4.0
352
'post\_meta\_keys' => array(), // 5.4.0
353
'concatenate\_keywords' => false, // 5.4.0
354
342
'additional\_keywords' => '',
355
343
'excluding\_keywords' => '', // 3.12.0
amazon-auto-links/trunk/readme.txt
r2896127
r2961861
7
7
Tested up to: 6.2.0
8
8
Requires MySQL: 5.0.3
9
Stable tag: 5.3.1
9
Stable tag: 5.3.2
10
10
License: GPLv2 or later
11
11
License URI: http://www.gnu.org/licenses/gpl-2.0.html
…
…
382
382
\== Changelog ==
383
383
384
\#### 5.3.1 - 04/06/2023
385
\- Fixed an issue that loading units with JavaScript failed with third-party caching plugins.
386
\- Fixed an incompatibility issue with WordPress 6.2 which caused a critical error in the background.
387
388
384
\#### 5.3.2 - 09/02/2023
385
\- Fixed a bug that legacy option values of PA-API keys were referred if existed even after saving empty PA-API keys.
386
\- Fixed non-sanitized user inputs.
389
387
390
388
\#### Old Log