WordPress Plugins Security Analysis

rezaduty
InfoSec Write-ups
Published in
9 min readFeb 28, 2023

--

40 0Days in 40 Days

We are excited to announce the launch of our 40 Vulnerabilities in 40 Days Campaign! Our goal is to raise awareness about the importance of proactive vulnerability management and to encourage everyone to take action to secure their systems.

Starting from March 1st, we will be showcasing one vulnerability every day for 40 days, along with details on how to detect and remediate it. Our team of experts will be available to provide insights and best practices, so you can learn from real-world scenarios and understand the impact of these vulnerabilities.

We believe that knowledge is power, and by educating ourselves and others, we can help make the world a safer place. Join us and become a part of the 40 Vulnerabilities in 40 Days Campaign today!

What is Zero-Day

A zero-day vulnerability is a security weakness in software or hardware that is unknown to the party responsible for patching or otherwise protecting the system. This vulnerability can be exploited by attackers to conduct malicious activities such as unauthorized access to sensitive data, spreading malware, or disrupting normal operations.

Zero-day vulnerabilities are particularly dangerous because they can be used by attackers before the vendor has had a chance to release a patch or a fix for the issue. Attackers can take advantage of these vulnerabilities to launch targeted attacks, which can have serious consequences, such as data theft, financial loss, or reputational damage.

Vulnerabilities List

CVE-2022–45834

CVE-2022–4367

CVE-2022–4011

CVE-2022–3941

CVE-2022–4412

CVE-2022–4411

CVE-2022–4406

CVE-2022–4405

CVE-2022–4404

CVE-2022–4528

CVE-2022–4529

CVE-2022–4530

CVE-2022–4531

CVE-2022–4532

CVE-2022–4533

CVE-2022–4534

CVE-2022–4535

CVE-2022–4536

CVE-2022–4537

CVE-2022–4538

CVE-2022–4539

CVE-2022–4540

CVE-2022–4541

CVE-2022–4550

CVE-2022–46847

CVE-2022–4423

CVE-2022–4424

CVE-2022–4425

CVE-2022–4443

CVE-2022–47171

CVE-2022–47163

CVE-2022–47162

CVE-2022–47159

CVE-2022–47155

CVE-2022–47154

CVE-2022–47152

CVE-2022–47147

CVE-2022–47138

CVE-2022–47141

CVE-2022–47143

CVE-2022–47139

CVE-2022–47135

CVE-2022–47448

CVE-2022–47447

CVE-2022–47440

CVE-2022–47446

CVE-2022–47443

CVE-2022–47422

CVE-2022–4549

CVE-2022–4548

CVE-2022–47427

Plugins Type

CSRF Vulnerability

Example Request:

POST /wp-admin/options-general.php?page=wp_csv_to_db_menu_page HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/109.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost/wp-admin/options-general.php?page=wp_csv_to_db_menu_page
Content-Type: application/x-www-form-urlencoded
Content-Length: 135
Origin: http://localhost
Connection: close
Cookie: ip-geo-block=0%3D%261%3D%262%3Dooooxxxxx%263%3D%264%3Doo; cwisAppSettings=%7B%22actionLang%22%3A%22en%22%2C%22licenseKey%22%3A%22%22%2C%22pagination%22%3A%2210%22%7D; cwisScanSettings=%7B%22autopath%22%3A1%2C%22database%22%3A0%2C%22depth%22%3A%22-1%22%2C%22extskip%22%3A%22mp3%2C%20wav%2C%20m4a%2C%20flac%2C%20mp4%2C%20ogg%2C%20webm%2C%20mpg%2C%20ogv%2C%20m4v%2C%20asf%2C%20avi%2C%20flv%2C%20swf%2C%20css%2C%20webp%2C%20jpeg%2C%20svg%2C%20jpg%2C%20png%2C%20gif%2C%20raw%2C%20bmp%2C%20eot%2C%20ttf%2C%20woff%2C%20woff2%2C%20otf%22%2C%22email%22%3A%22%22%2C%22level%22%3A%222%22%2C%22scanpath%22%3A%22%22%2C%22secvuln%22%3A0%2C%22sendalerts%22%3A0%2C%22sendreports%22%3A0%2C%22filter%22%3A%22%22%2C%22filterexp%22%3A0%2C%22filterinv%22%3A0%7D; pdb-settings-page-tab=7; catablog-view-cookie[sort]=date; catablog-view-cookie[order]=asc; catablog-view-cookie[view]=list; sbp_kw_length=10; sbp_the_showkws=all; wordpress_86a9106ae65537651a8e456835b316ab=admin%7C1672058229%7CI6KAHIvytE4ccHwA97dKH2Q2WikDymlWMew0yokSzUa%7Ccfe7d43647d0f3f22cb502cc54bf0d6bd6d7e0bccc6a9f5ed6f2e19d0f11bee0; amp_d59f9d=ERnkChTbaIODMJrTas9SFN...1gk2lofbc.1gk2mu60i.0.0.0; session=b8dd9c85-204f-4c56-94f4-deb76b12a9fc.0mOS4JetV2KWKlLS8pV2iSME5w0; TZ=-12600; wp-settings-1=libraryContent%3Dbrowse%26editor%3Dhtml%26urlbutton%3Dcustom%26posts_list_mode%3Dexcerpt%26mfold%3Do; wp-settings-time-1=1671092813; fm_cookie_605921e05e4e17a736ecaa4dd4099774=605921e05e4e17a736ecaa4dd4099774; PHPSESSID=fd128c23fa58597c4ee00fc022913a8a; wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_86a9106ae65537651a8e456835b316ab=admin%7C1672058229%7CI6KAHIvytE4ccHwA97dKH2Q2WikDymlWMew0yokSzUa%7C23324c5244c71b64a0c1ae38c2f2ca175d4e9fb4df2cac536e4691703eac99e3
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
table_select=ahc_visits_time&csv_file=&num_cols=&num_cols_csv_file=&sel_start_row=&execute_button=Import+to+DB&delete_db_button_hidden=

Example Vulnerable Code:

The displayed code snippet is used in WordPress and can save the information in the CSV file to the WordPress database. After filling the WordPress form with the required information, the code connects to the WordPress database and stores the information in the CSV file in the desired table of the WordPress database. This code also has a special value “update_db” which, if checked, will update the data in the CSV file instead of creating a new record. If no records have been updated, a success message is displayed. But if there is a problem connecting with the database, an error message will be displayed.

if ( isset( $_POST[ 'execute_button' ] ) ) {
// If "Update DB Rows" was checked
if ( isset( $_POST[ 'update_db' ] ) )
// Setup sql 'on duplicate update' loop
$updateOnDuplicate = ' ON DUPLICATE KEY UPDATE ';
foreach ( $db_cols as $db_col ) {
$updateOnDuplicate .= "$db_col=VALUES($db_col),";}
$updateOnDuplicate = rtrim( $updateOnDuplicate, ',' );
$sql = 'INSERT INTO ' . $_POST[ 'table_select' ] . ' (' . $db_cols_implode . ') ' . 'VALUES ' . $values_implode . $updateOnDuplicate;
$db_query_update = $wpdb->query( $sql );} else {
$sql = 'INSERT INTO ' . $_POST[ 'table_select' ] . ' (' . $db_cols_implode . ') ' . 'VALUES ' . $values_implode;
$db_query_insert = $wpdb->query( $sql );}
// If db db_query_update is successful
if ( $db_query_update ) {
$success_message = __( 'Congratulations! The database has been updated successfully.', 'wp_csv_to_db' );}
// If db db_query_insert is successful
elseif ( $db_query_insert ) {
$success_message = __( 'Congratulations! The database has been updated successfully.', 'wp_csv_to_db' );
$success_message .= '<br /><strong>' . count( $values ) . '</strong> ' . __( 'record(s) were inserted into the', 'wp_csv_to_db' ) . ' <strong>' . $_POST[ 'table_select' ] . '</strong> ' . __( 'database table.', 'wp_csv_to_db' ); }
// If db db_query_insert is successful AND there were no rows to udpate
elseif ( ($db_query_update === 0) && ($db_query_insert === '') ) {
$message_info_style .= '* ' . __( 'There were no rows to update. All .csv values already exist in the database.', 'wp_csv_to_db' ) . '<br />';} else {
$error_message .= '* ' . __( 'There was a problem with the database query.', 'wp_csv_to_db' ) . '<br />';
$error_message .= '* ' . __( 'A duplicate entry was found in the database for a .csv file entry.', 'wp_csv_to_db' ) . '<br />';
$error_message .= '* ' . __( 'If necessary; please use the option below to "Update Database Rows".', 'wp_csv_to_db' ) . '<br />';}

CSRF Protection Parameter

One of the useful methods to prevent CSRF vulnerability in the development of WordPress plugins is to use unique tokens. To use this method, you need to use tokens in your plugin development code that are uniquely added to the form. For example, you can use the form author token.

For example, in the code below, the form author token is added as a variable containing a random value in the form:

function add_csrf_nonce_field() {wp_nonce_field( 'csrf_nonce_action', 'csrf_nonce_name' );}add_action( 'form_name_form_tag', 'add_csrf_nonce_field'

In the code below, the token of the form author is checked after submitting the form, and if the token is not correct, the form is considered invalid:

function verify_csrf_nonce_field() {
if ( !isset( $_POST['csrf_nonce_name'] ) || !wp_verify_nonce( $_POST['csrf_nonce_name'], 'csrf_nonce_action' ) ) {wp_die(

You can also use change tokens like time token. For example, you can add a time token like this:

function add_csrf_nonce_field() {$nonce_value = time();echo '<input type="hidden" name="csrf_nonce_name" value="' . $nonce_value . '" />';}add_action( 'form_name_form_tag', 'add_csrf_nonce_field' );

In the following code, the time token is checked after submitting the form and if the token is older than one minute, it considers the form invalid:

function verify_csrf_nonce_field() {$submitted_nonce = isset( $_POST['csrf_nonce_name'] ) ? intval( $_POST['csrf_nonce_name'] ) : 0;if ( time() - $submitted_nonce > 60 ) {wp_die( 'Invalid CSRF nonce. Please tryagain.');}}add_action('form_name_process_action', 'verify_csrf_nonce_field');

You can also use WordPress framework features, such as the wp_verify_nonce class, to prevent CSRF. Using the wp_verify_nonce class in the WordPress framework is a useful and advanced method to prevent CSRF attacks.

The wp_verify_nonce class uses a random token that is generated on each new request and after the form is submitted, the token is compared with the token submitted in the form.

To use the wp_verify_nonce class in the development of WordPress plugins, you can use the following code:

function add_csrf_nonce_field() {wp_nonce_field( 'csrf_nonce_action', 'csrf_nonce_name' );}add_action( 'form_name_form_tag', 'add_csrf_nonce_field' );
function verify_csrf_nonce_field() {if ( !isset( $_POST['csrf_nonce_name'] ) || !wp_verify_nonce( $_POST['csrf_nonce_name'], 'csrf_nonce_action' ) ) {wp_die('Invalid CSRF nonce. Please try again.')

HTTP Header Injection

The displayed code attempts to obtain the IP address of the user requesting the page. This is done by using different variables on the server side. This code can be useful for users who use proxy or proxy server. Normally, the user’s IP address is shown by default in a part of the browser’s address bar, but in some cases, the user’s IP address can be hidden by using a proxy or proxy server. The displayed code can obtain the user’s IP address using the standard HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_FORWARDED_FOR and HTTP_FORWARDED. If none of these variables are available, the IP address is considered invalid and the function returns an empty value.

Also, the filter_var function is used to check the correctness of the filtered IP address. If the IP address is not valid, the function returns empty.

POST /wp-login.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/109.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost/wp-login.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 103
Origin: http://localhost
Connection: close
Cookie: amp_d59f9d=ERnkChTbaIODMJrTas9SFN...1gk2lofbc.1gk2mu60i.0.0.0; session=b8dd9c85-204f-4c56-94f4-deb76b12a9fc.0mOS4JetV2KWKlLS8pV2iSME5w0; TZ=-12600; fm_cookie_605921e05e4e17a736ecaa4dd4099774=605921e05e4e17a736ecaa4dd4099774; PHPSESSID=fd128c23fa58597c4ee00fc022913a8a; wordpress_test_cookie=WP%20Cookie%20check
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
log=admin&pwd=admiandmin&wp-submit=Log+In&redirect_to=http%3A%2F%2Flocalhost%2Fwp-admin%2F&testcookie=1

HTTP Header Injection Methods

A useful way to avoid http header injection vulnerability in WordPress plugin development is to use wp_remote_get and wp_remote_post functions. These functions use the cURL library and by default, the http header is also filtered in all the texts that are sent.

To use the wp_remote_get and wp_remote_post functions in the development of WordPress plugins, you can use the following code:

$response = wp_remote_get( 'http://example.com/api/endpoint' );if ( is_wp_error( $response ) ) {wp_die( 'Error: ' . $response->get_error_message() );}$response = wp_remote_post( 'http://example.com/api/endpoint', array('body' => array('param1' =>'value1','param2' => 'value2')) );if ( is_wp_error( $response ) ) {wp_die( 'Error: ' .$response->get_error_message() );}

You can also use the wp_http_validate_url function to filter invalid entries.

The function checks whether the submitted URL is valid or not. If the URL is invalid, the wp_http_validate_url function will return an error and you will not be able to execute your code.

To use the wp_http_validate_url function in the development of WordPress plugins, you can use the following code:

$url = 'http://example.com';if ( !wp_http_validate_url( $url ) ) {wp_die( 'Error: Invalid URL' );}

You can also use the esc_url_raw function to control Internet access. This function filters the submitted URL and deletes it if the URL is invalid.

To use the esc_url_raw function in the development of WordPress plugins, you can use the following code:

$url = 'http://example.com'; $url = esc_url_raw($url);

CSRF (Cross-Site Request Forgery) Mitigation

Cross-Site Request Forgery (CSRF) is a type of security vulnerability that occurs when a malicious website is able to trick a user’s browser into sending a request to another website, without the user’s knowledge or consent. This can be used to steal sensitive information or to perform unauthorized actions on behalf of the user.

  • Synchronizer token pattern: This involves adding a unique token to each form or request that is generated by the server and passed to the client. The client must then include this token in all subsequent requests to the server, which the server can then use to verify that the request was initiated by the user.
  • Same-Site Cookies: This is a flag that can be set on a cookie, which tells the browser to only send the cookie on requests to the same domain that set the cookie. This makes it more difficult for a malicious website to perform a CSRF attack, as it won’t have access to the necessary cookies.
  • Referrer header check: This involves checking the value of the referrer header in each request to ensure that it was sent from the same domain. This helps to prevent CSRF attacks that use methods such as image tags or JavaScript to send requests.
  • CAPTCHA: A CAPTCHA can be used to require the user to prove that they are a human before performing a sensitive action. This makes it more difficult for a malicious website to perform a CSRF attack, as it won’t be able to complete the CAPTCHA.
  • Use of Anti-CSRF libraries: Anti-CSRF libraries, such as the OWASP CSRFGuard, provide an easy-to-use solution for protecting against CSRF attacks by automatically generating and validating tokens for each request.

HTTP header injection Mitigation

HTTP header injection is a type of security vulnerability that occurs when an attacker is able to inject malicious content into HTTP headers. This can be used to manipulate the behavior of web applications or to steal sensitive information.

To prevent HTTP header injection, it’s important to follow these best practices:

  • Input validation: Ensure that all user-supplied data is properly validated and sanitized to prevent malicious data from being included in HTTP headers.
  • Use secure encoding and decoding functions: Use secure encoding and decoding functions, such as HTML entities and URL encoding, to ensure that special characters are properly handled.
  • Limit header size: Limit the size of HTTP headers to prevent excessive data from being included in the headers.
  • Use a web application firewall (WAF): A WAF can provide protection against HTTP header injection by detecting and blocking malicious requests.
  • Keep software up to date: Ensure that all software, including web applications and the underlying operating system, is kept up to date to address known vulnerabilities.
  • Regularly perform security testing: Regularly perform security testing, including penetration testing, to identify and remediate vulnerabilities in your systems.

Hadess performs offensive cybersecurity services through infrastructures and software that include vulnerability analysis, scenario attack planning, and implementation of custom integrated preventive projects. We organized our activities around the prevention of corporate, industrial, and laboratory cyber threats.

--

--