CVE-2016-9456 (PHP, published 2017-03-28T02:59Z)
Description: value: Revive Adserver before 3.2.3 suffers from Cross-Site Request Forgery (CSRF). The Revive Adserver team conducted a security audit of the admin interface scripts in order to identify and fix other potential CSRF vulnerabilities. Over 20+ such issues were fixed.
Severity: MEDIUM (CVSS v3 base score: 8.8)
Weakness: CWE-352 \u2014 Cross-Site Request Forgery (CSRF)
The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
Repository: https://github.com/revive-adserver/revive-adserver
Files changed:
lib/OA/Admin/Template.php
lib/max/Admin/Inventory/TrackerAppend.php
lib/max/Admin/Inventory/themes/TrackerAppend.html
lib/max/other/html.php
lib/templates/admin/campaign-zone.html
www/admin/banner-modify.php
www/admin/campaign-modify.php
www/admin/campaign-zone-link.php
www/admin/channel-acl.php
www/admin/channel-modify.php
www/admin/lib-maintenance-priority.inc.php
www/admin/maintenance-acl-check.php
www/admin/maintenance-appendcode-check.php
www/admin/maintenance-banners-check.php
www/admin/maintenance-encoding.php
www/admin/maintenance-menus.php
www/admin/maintenance-plugins.php
www/admin/maintenance-priority-calculate.php
www/admin/maintenance-priority.php
www/admin/maintenance-storage-move.php
www/admin/maintenance-storage.php
www/admin/run-mpe.php
www/admin/tracker-append.php
www/admin/tracker-variables.php
www/admin/updates-history.php
www/admin/zone-modify.php
Commit message: Fix other CSRF issues

Cross-Site Request Forgery (CSRF)
---------------------------------

Following a number of CSRF reports, the Revive Team has conducted a security
audit of the admin interface scripts in order to identify and fix other
potential CSRF vulnerabilities.

The effort led to fixing 20+ such issues: please see the commit for the full
list of files affected.

A CVE-ID has been requested, but not assigned yet.

CWE: CWE-352
CVSSv2: 5 (AV:N/AC:L/Au:N/C:N/I:N/A:P)


Vulnerable code:
    
        addPageLinkTool($GLOBALS["strDuplicate"], MAX::constructUrl(MAX_URL_ADMIN, "tracker-modify.php?clientid=".$advertiserId."&trackerid=".$trackerId."&duplicate=true&returnurl=".urlencode(basename($_SERVER['SCRIPT_NAME']))), "iconTrackerDuplicate");
        addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "tracker-delete.php?token=" . urlencode(phpAds_SessionGetToken()) . "&clientid=".$advertiserId."&trackerid=".$trackerId."&returnurl=advertiser-trackers.php"), "iconDelete", null, $deleteConfirm);
        addPageLinkTool($GLOBALS["strDuplicate"], MAX::constructUrl(MAX_URL_ADMIN, "campaign-modify.php?duplicate=1&clientid=$clientid&campaignid=$campaignid&returnurl=".urlencode(basename($_SERVER['SCRIPT_NAME']))), "iconCampaignDuplicate");
            <input type='hidden' name='returnurl' value='".htmlspecialchars(basename($_SERVER['SCRIPT_NAME']))."'>
        addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "campaign-delete.php?token=" . urlencode(phpAds_SessionGetToken()) . "&clientid=$clientid&campaignid=$campaignid&returnurl=advertiser-campaigns.php"), "iconDelete", null, $deleteConfirm);
    global $phpAds_TextDirection;
    addPageLinkTool($GLOBALS["strDuplicate"], MAX::constructUrl(MAX_URL_ADMIN, "banner-modify.php?duplicate=true&clientid=$advertiserId&campaignid=$campaignId&bannerid=$bannerId&returnurl=".urlencode(basename($_SERVER['SCRIPT_NAME']))), "iconBannerDuplicate");
        addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "banner-delete.php?token=" . urlencode(phpAds_SessionGetToken()) . "&clientid=$advertiserId&campaignid=$campaignId&bannerid=$bannerId&returnurl=campaign-banners.php"), "iconDelete", null, $deleteConfirm);
        addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "zone-delete.php?token=" . urlencode(phpAds_SessionGetToken()) . "&affiliateid=$affiliateid&zoneid=$zoneid&returnurl=affiliate-zones.php"), "iconDelete", null, $deleteConfirm);
    addPageLinkTool($GLOBALS["strDuplicate"], MAX::constructUrl(MAX_URL_ADMIN, "channel-modify.php?duplicate=true&agencyid=$agencyid&affiliateid=$websiteId&channelid=$channelid&returnurl=".urlencode(basename($_SERVER['SCRIPT_NAME']))), "iconTargetingChannelDuplicate");
    addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "channel-delete.php?token=" . urlencode(phpAds_SessionGetToken()) . "&agencyid=$agencyid&affiliateid=$websiteId&channelid=$channelid&returnurl=$deleteReturlUrl"), "iconDelete", null, $deleteConfirm);
OA_Permission::checkSessionToken();

?>
    $objResponse->addAssign("run-mpe", "innerHTML", "<img src='run-mpe.php' />");
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-menus.php?action=build'>Rebuild Menu Cache</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?action=hook'>Rebuild Component Hooks Cache</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?action=pref'>Rebuild Preferences List</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?action=reg'>Rebuild Delivery Hooks Cache</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?action=rep'>Plugin Report</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?action=exp'>Export All Plugins</a>&nbsp;&nbsp;";
/*echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?action=dep'>Check Dependencies</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-priority-calculate.php'>$strRecalculatePriority</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-storage-move.php'>$strMoveToDirectory</a>&nbsp;&nbsp;";

Fixed code:
        // Also assign a template variable for other usages
        $this->assign("csrfToken", phpAds_SessionGetToken());
        $this->csrf_token    = phpAds_SessionGetToken();

    <input type="hidden" name="token" value="{csrf_token}" />
    echo "<input type='hidden' name='token' value='".urlencode(phpAds_SessionGetToken())."' />";
        $token = phpAds_SessionGetToken();

        addPageLinkTool($GLOBALS["strDuplicate"], MAX::constructUrl(MAX_URL_ADMIN, "tracker-modify.php?token=".urlencode($token)."&clientid=".$advertiserId."&trackerid=".$trackerId."&duplicate=true&returnurl=".urlencode(basename($_SERVER['SCRIPT_NAME']))), "iconTrackerDuplicate");
            <input type='hidden' name='token' value='".htmlspecialchars($token, ENT_QUOTES)."'>
        addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "tracker-delete.php?token=".urlencode($token)."&clientid=".$advertiserId."&trackerid=".$trackerId."&returnurl=advertiser-trackers.php"), "iconDelete", null, $deleteConfirm);

        $token = phpAds_SessionGetToken();

        addPageLinkTool($GLOBALS["strDuplicate"], MAX::constructUrl(MAX_URL_ADMIN, "campaign-modify.php?token=".urlencode($token)."&duplicate=1&clientid=$clientid&campaignid=$campaignid&returnurl=".urlencode(basename($_SERVER['SCRIPT_NAME']))), "iconCampaignDuplicate");
            <input type='hidden' name='token' value='".htmlspecialchars($token, ENT_QUOTES)."'>
            <input type='hidden' name='returnurl' value='".htmlspecialchars(basename($_SERVER['SCRIPT_NAME'], ENT_QUOTES))."'>
        addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "campaign-delete.php?token=".urlencode($token)."&clientid=$clientid&campaignid=$campaignid&returnurl=advertiser-campaigns.php"), "iconDelete", null, $deleteConfirm);
    global $phpAds_TextDirection;

    $token = phpAds_SessionGetToken();

    addPageLinkTool($GLOBALS["strDuplicate"], MAX::constructUrl(MAX_URL_ADMIN, "banner-modify.php?token=".urlencode($token)."&duplicate=true&clientid=$advertiserId&campaignid=$campaignId&bannerid=$bannerId&returnurl=".urlencode(basename($_SERVER['SCRIPT_NAME']))), "iconBannerDuplicate");
    <input type='hidden' name='token' value='".htmlspecialchars($token, ENT_QUOTES)."'>
        <input type='hidden' name='token' value='".htmlspecialchars($token, ENT_QUOTES)."'>
        addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "banner-delete.php?token=".urlencode($token)."&clientid=$advertiserId&campaignid=$campaignId&bannerid=$bannerId&returnurl=campaign-banners.php"), "iconDelete", null, $deleteConfirm);

    $token = phpAds_SessionGetToken();

        <input type='hidden' name='token' value='".htmlspecialchars($token, ENT_QUOTES)."'>
        addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "zone-delete.php?token=".urlencode($token)."&affiliateid=$affiliateid&zoneid=$zoneid&returnurl=affiliate-zones.php"), "iconDelete", null, $deleteConfirm);
    $token = phpAds_SessionGetToken();

    addPageLinkTool($GLOBALS["strDuplicate"], MAX::constructUrl(MAX_URL_ADMIN, "channel-modify.php?token=".urlencode($token)."&duplicate=true&agencyid=$agencyid&affiliateid=$websiteId&channelid=$channelid&returnurl=".urlencode(basename($_SERVER['SCRIPT_NAME']))), "iconTargetingChannelDuplicate");
    addPageLinkTool($GLOBALS["strDelete"], MAX::constructUrl(MAX_URL_ADMIN, "channel-delete.php?token=".urlencode($token)."&agencyid=$agencyid&affiliateid=$websiteId&channelid=$channelid&returnurl=$deleteReturlUrl"), "iconDelete", null, $deleteConfirm);
  <input id="csrf-token" type="hidden" value="{$csrfToken|escape}" />
      "token": $("#csrf-token").val(),
          // Refresh token
          $("#csrf-token").val(extractPart(data, "value", "token"));

    OA_Permission::checkSessionToken();

    OA_Permission::checkSessionToken();

OA_Permission::checkSessionToken();

// CSRF Token
echo "<!--token-value-start-->".phpAds_SessionGetToken()."<!--token-value-end-->";
    OA_Permission::checkSessionToken();

    OA_Permission::checkSessionToken();

    $objResponse->addAssign("run-mpe", "innerHTML", "<img src='run-mpe.ph?token=".urlencode(phpAds_SessionGetToken())."' />");
    OA_Permission::checkSessionToken();

    echo "<input type='hidden' name='token' value='".htmlspecialchars(phpAds_SessionGetToken(), ENT_QUOTES)."' />";
    OA_Permission::checkSessionToken();

    echo "<input type='hidden' name='token' value='".htmlspecialchars(phpAds_SessionGetToken(), ENT_QUOTES)."' />";
    OA_Permission::checkSessionToken();

        echo "<input type='hidden' name='token' value='".htmlspecialchars(phpAds_SessionGetToken(), ENT_QUOTES)."' />";
    OA_Permission::checkSessionToken();

    echo "<input type='hidden' name='token' value='".htmlspecialchars(phpAds_SessionGetToken(), ENT_QUOTES)."' />";
    OA_Permission::checkSessionToken();

echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-menus.php?action=build&amp;token=".urlencode(phpAds_SessionGetToken())."'>Rebuild Menu Cache</a>&nbsp;&nbsp;";
    OA_Permission::checkSessionToken();

$token = 'token='.urlencode(phpAds_SessionGetToken()).'&amp;';

echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?{$token}action=hook'>Rebuild Component Hooks Cache</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?{$token}action=pref'>Rebuild Preferences List</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?{$token}action=reg'>Rebuild Delivery Hooks Cache</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?{$token}action=rep'>Plugin Report</a>&nbsp;&nbsp;";
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?{$token}action=exp'>Export All Plugins</a>&nbsp;&nbsp;";
/*echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-plugins.php?{$token}action=dep'>Check Dependencies</a>&nbsp;&nbsp;";
OA_Permission::checkSessionToken();
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-priority-calculate.php?token=".urlencode(phpAds_SessionGetToken())."'>$strRecalculatePriority</a>&nbsp;&nbsp;";
OA_Permission::checkSessionToken();
echo "<img src='" . OX::assetPath() . "/images/".$phpAds_TextDirection."/icon-undo.gif' border='0' align='absmiddle'>&nbsp;<a href='maintenance-storage-move.php?token=".urlencode(phpAds_SessionGetToken())."'>$strMoveToDirectory</a>&nbsp;&nbsp;";
OA_Permission::checkSessionToken();
    OA_Permission::checkSessionToken();

        OA_Permission::checkSessionToken();

                echo "<input type='token' name='submit' value='".htmlspecialchars(phpAds_SessionGetToken(), ENT_QUOTES)."'>";
    OA_Permission::checkSessionToken();

                    <input type="hidden" name="token" value="<?php echo htmlspecialchars(phpAds_SessionGetToken()); ?>" />
    OA_Permission::checkSessionToken();