Skip to content
Permalink
Browse files Browse the repository at this point in the history
* [Security/CSRF] Fixed a medium risk CSRF (cross-site request forger…
…y) vulnerability reported by High-Tech Bridge (HTB23269). We don't have any evidence of this having taken place in the wild, but we were able to reproduce the results with the proof-of-concept in the advisory. A logged in worker could be tricked into visiting a URL that could perform certain actions in their browser session. Cerb now uses the Synchronizer pattern: a session-based token included with every HTML FORM and Ajax request that is compared to the active session. This verifies that such requests are coming from an existing Cerb page rather than an external source. When a potential CSRF attack is detected, the event is now logged in the PHP log as a warning.
  • Loading branch information
jstanden committed Aug 13, 2015
1 parent f911b25 commit 12de87f
Show file tree
Hide file tree
Showing 196 changed files with 308 additions and 17 deletions.
3 changes: 3 additions & 0 deletions features/cerberusweb.core/api/uri/login.php
Expand Up @@ -304,6 +304,9 @@ private function _processAuthenticated($worker) { /* @var $worker Model_Worker *

$session->setVisit($visit);

// Generate a CSRF token for the session
$_SESSION['csrf_token'] = CerberusApplication::generatePassword(256);

if(isset($_SESSION['login_post_url'])) {
$redirect_path = explode('/', $_SESSION['login_post_url']);

Expand Down
Expand Up @@ -4,6 +4,7 @@
<input type="hidden" name="action" value="saveRole">
<input type="hidden" name="id" value="{if !empty($role->id)}{$role->id}{else}0{/if}">
<input type="hidden" name="do_delete" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

{if $saved}
<div class="ui-widget">
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="branding">
<input type="hidden" name="action" value="saveJson">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset>
<legend>Settings</legend>
Expand Down
Expand Up @@ -3,6 +3,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="cache">
<input type="hidden" name="action" value="saveCachePeek">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

{foreach from=$engines item=engine key=engine_id}
<fieldset class="peek" style="margin-bottom:0;">
Expand Down
Expand Up @@ -28,6 +28,7 @@
<input type="hidden" name="section" value="license">
<input type="hidden" name="action" value="saveJson">
<input type="hidden" name="do_delete" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset>
<legend>Update License</legend>
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="localization">
<input type="hidden" name="action" value="saveJson">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset>
<legend>Date &amp; Time</legend>
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="action" value="savePeekPopup">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="do_delete" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>storage/mail/fail/{$filename}:</b>
<div>
Expand Down
Expand Up @@ -28,6 +28,8 @@
<input type="hidden" name="section" value="mail_failed">
<input type="hidden" name="action" value="">
<input type="hidden" name="explore_from" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<table cellpadding="5" cellspacing="0" border="0" width="100%" class="worklistBody">

{* Column Headers *}
Expand Down
Expand Up @@ -11,11 +11,13 @@
{/foreach}

{if !$has_atleast_one}
<form action="{devblocks_url}{/devblocks_url}">
<form action="{devblocks_url}{/devblocks_url}" method="POST">
<input type="hidden" name="c" value="config">
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="mail_filtering">
<input type="hidden" name="action" value="createDefaultVa">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<div class="help-box" style="padding:5px;border:0;">
<h1 style="margin-bottom:5px;text-align:left;">Create a global Virtual Attendant</h1>

Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="mail_from">
<input type="hidden" name="action" value="saveJson">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<div style="margin-bottom:10px;">
<button type="button" onclick="genericAjaxPopup('peek','c=config&a=handleSectionAction&section=mail_from&action=peek&id=0',null,false,'550');"><span class="glyphicons glyphicons-circle-plus" style="color:rgb(0,180,0);"></span> {'common.add'|devblocks_translate|capitalize}</button>
Expand Down
Expand Up @@ -4,6 +4,7 @@
<input type="hidden" name="section" value="mail_from">
<input type="hidden" name="action" value="savePeek">
<input type="hidden" name="id" value="{$address->address_id}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset class="peek">
<legend>Send worker replies as:</legend>
Expand Down
Expand Up @@ -6,6 +6,7 @@
<input type="hidden" name="view_id" value="{$view_id}">
{if !empty($model) && !empty($model->id)}<input type="hidden" name="id" value="{$model->id}">{/if}
<input type="hidden" name="do_delete" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<div id="mailTemplateTabs">
<ul>
Expand Down
Expand Up @@ -33,6 +33,8 @@
<input type="hidden" name="section" value="html_template">
<input type="hidden" name="action" value="">
<input type="hidden" name="explore_from" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<table cellpadding="5" cellspacing="0" border="0" width="100%" class="worklistBody">

{* Column Headers *}
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="mail_import">
<input type="hidden" name="action" value="parseMessageJson">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>Paste a message source:</b>
<div>
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="mail_incoming">
<input type="hidden" name="action" value="saveJson">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset>
<legend>{'common.settings'|devblocks_translate|capitalize}</legend>
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="mail_relay">
<input type="hidden" name="action" value="saveJson">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<p>
The email relay enables workers to respond to messages from external mail applications (e.g. Gmail, mobile phones, Outlook, etc) instead of always requiring them to use Cerb in the web browser.
Expand Down
Expand Up @@ -12,6 +12,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="mail_routing">
<input type="hidden" name="action" value="saveRouting">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>Which group should receive any unrouted new mail?</b><br>
<select name="default_group_id">
Expand Down
Expand Up @@ -4,6 +4,7 @@
<input type="hidden" name="section" value="mail_routing">
<input type="hidden" name="action" value="saveMailRoutingRuleAdd">
<input type="hidden" name="id" value="{$rule->id}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>Rule Name:</b> (e.g. ProductX Support)<br>
<input type="text" name="name" value="{$rule->name}" size="45" style="width:95%;"><br>
Expand Down
@@ -1,12 +1,5 @@
<form action="{devblocks_url}{/devblocks_url}" method="POST" id="frmCerb6PluginDownload">
{*
<input type="hidden" name="c" value="config">
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="plugin_library">
<input type="hidden" name="action" value="saveDownloadPopup">
<input type="hidden" name="plugin_id" value="{$plugin->id}">
<input type="hidden" name="view_id" value="{$view_id}">
*}
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>{$plugin->name}</b><br>
<br>
Expand Down
Expand Up @@ -26,6 +26,8 @@
<input type="hidden" name="context_id" value="">
<input type="hidden" name="id" value="{$view->id}">
<input type="hidden" name="explore_from" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<table cellpadding="1" cellspacing="0" border="0" width="100%" class="worklistBody">

{* Column Headers *}
Expand Down
Expand Up @@ -6,6 +6,7 @@
<input type="hidden" name="plugin_id" value="{$plugin->id}">
<input type="hidden" name="view_id" value="{$view_id}">
{if $is_uninstallable}<input type="hidden" name="uninstall" value="0">{/if}
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<div>
<b>{'common.status'|devblocks_translate|capitalize}:</b>
Expand Down
Expand Up @@ -26,6 +26,8 @@
<input type="hidden" name="context_id" value="">
<input type="hidden" name="id" value="{$view->id}">
<input type="hidden" name="explore_from" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<table cellpadding="1" cellspacing="0" border="0" width="100%" class="worklistBody">

{* Column Headers *}
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="action" value="saveTabSettings">
<input type="hidden" name="portal" value="{$instance->code}">
<input type="hidden" name="do_delete" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>Portal Name:</b> ("Support Portal", "Contact Form", "ProductX FAQ")<br>
<input type="text" name="portal_name" value="{if !empty($instance->name)}{$instance->name}{else}{$instance->manifest->name}{/if}" size="65"><br>
Expand Down
Expand Up @@ -7,6 +7,7 @@
<input type="hidden" name="action" value="saveAddTemplatePeek">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="portal" value="{$portal}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>Template:</b><br>
<select name="template">
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="action" value="doTemplatesBulkUpdate">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="ids" value="{$ids}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset>
<legend>{'common.bulk_update.with'|devblocks_translate|capitalize}</legend>
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="action" value="saveExportTemplatesPeek">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="portal" value="{$portal}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>Filename:</b> (.xml)<br>
<input type="text" name="filename" size="45" value="cerb_portal_templates_{$smarty.const.APP_BUILD}.xml"><br>
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="action" value="saveImportTemplatesPeek">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="portal" value="{$portal}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>Import File:</b> (.xml)<br>
<input type="file" name="import_file" size="45"><br>
Expand Down
Expand Up @@ -6,6 +6,7 @@
<input type="hidden" name="id" value="{$template->id}">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="do_delete" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>{$template->path}:</b><br>
<textarea name="content" wrap="off" style="height:300px;width:98%;">{$template->content}</textarea><br>
Expand Down
Expand Up @@ -20,6 +20,8 @@
<input type="hidden" name="view_id" value="{$view->id}">
<input type="hidden" name="c" value="config">
<input type="hidden" name="a" value="">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<table cellpadding="1" cellspacing="0" border="0" width="100%" class="worklistBody">

{* Column Headers *}
Expand Down
Expand Up @@ -4,6 +4,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="portals">
<input type="hidden" name="action" value="saveAddPortalPeek">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>Portal Name:</b> ("Support Portal", "Contact Form", "ProductX FAQ")<br>
<input type="text" name="name" value="" style="width:98%;" autofocus="true"><br>
Expand Down
Expand Up @@ -21,6 +21,8 @@
<input type="hidden" name="view_id" value="{$view->id}">
<input type="hidden" name="c" value="config">
<input type="hidden" name="a" value="">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<table cellpadding="1" cellspacing="0" border="0" width="100%" class="worklistBody">

{* Column Headers *}
Expand Down
Expand Up @@ -14,6 +14,7 @@
<input type="hidden" name="section" value="scheduler">
<input type="hidden" name="action" value="saveJobJson">
<input type="hidden" name="id" value="{$job->manifest->id}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<label><input type="checkbox" name="enabled" value="1" {if $enabled}checked{/if}> <b>Enabled</b></label>

Expand Down
Expand Up @@ -4,6 +4,7 @@
<input type="hidden" name="section" value="search">
<input type="hidden" name="action" value="saveSearchSchemaPeek">
<input type="hidden" name="schema_extension_id" value="{$schema->id}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

{foreach from=$search_engines item=engine key=engine_id}
<fieldset class="peek">
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="a" value="handleSectionAction">
<input type="hidden" name="section" value="security">
<input type="hidden" name="action" value="saveJson">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset>
<legend>Remote Administration</legend>
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="action" value="doSessionsBulkUpdate">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="ids" value="{$ids}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset>
<legend>{'common.bulk_update.with'|devblocks_translate|capitalize}</legend>
Expand Down
Expand Up @@ -21,6 +21,8 @@
<input type="hidden" name="view_id" value="{$view->id}">
<input type="hidden" name="c" value="config">
<input type="hidden" name="a" value="">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<table cellpadding="3" cellspacing="0" border="0" width="100%" class="worklistBody">

{* Column Headers *}
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="action" value="doAttachmentsBulkUpdate">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="ids" value="{$ids}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset>
<legend>{'common.bulk_update.with'|devblocks_translate|capitalize}</legend>
Expand Down
Expand Up @@ -21,6 +21,8 @@
<input type="hidden" name="view_id" value="{$view->id}">
<input type="hidden" name="c" value="config">
<input type="hidden" name="a" value="">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<table cellpadding="1" cellspacing="0" border="0" width="100%" class="worklistBody">

{* Column Headers *}
Expand Down
Expand Up @@ -3,6 +3,7 @@
<form action="{devblocks_url}{/devblocks_url}" method="POST" style="margin-bottom:5px;">
<input type="hidden" name="c" value="config">
<input type="hidden" name="a" value="">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset>
<legend>Database</legend>
Expand Down
Expand Up @@ -4,6 +4,7 @@
<input type="hidden" name="section" value="storage_content">
<input type="hidden" name="action" value="saveStorageSchemaPeek">
<input type="hidden" name="ext_id" value="{$schema->manifest->id}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

{$schema->renderConfig()}

Expand Down
Expand Up @@ -14,6 +14,7 @@
<input type="hidden" name="id" value="{$profile->id}">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="do_delete" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<b>{'common.name'|devblocks_translate|capitalize}:</b><br>
<input type="text" name="name" value="{$profile->name}" style="width:98%;" autofocus="true"><br>
Expand Down
Expand Up @@ -19,6 +19,8 @@
<input type="hidden" name="view_id" value="{$view->id}">
<input type="hidden" name="c" value="config">
<input type="hidden" name="a" value="">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<table cellpadding="1" cellspacing="0" border="0" width="100%" class="worklistBody">

{* Column Headers *}
Expand Down
Expand Up @@ -5,6 +5,7 @@
<input type="hidden" name="action" value="doWorkersBulkUpdate">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="ids" value="{$ids}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset class="peek">
<legend>{'common.bulk_update.with'|devblocks_translate|capitalize}</legend>
Expand Down
Expand Up @@ -6,6 +6,7 @@
<input type="hidden" name="id" value="{$worker->id}">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="do_delete" value="0">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset class="peek">
<legend>{'common.properties'|devblocks_translate|capitalize}</legend>
Expand Down
Expand Up @@ -3,6 +3,7 @@
<input type="hidden" name="a" value="doAddressBatchUpdate">
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="ids" value="{$ids}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset class="peek">
<legend>{'common.bulk_update.with'|devblocks_translate|capitalize}</legend>
Expand Down
Expand Up @@ -7,6 +7,7 @@
<input type="hidden" name="link_context_id" value="{$link_context_id}">
{/if}
<input type="hidden" name="view_id" value="{$view_id}">
<input type="hidden" name="_csrf_token" value="{$session.csrf_token}">

<fieldset class="peek">
<legend>{'common.properties'|devblocks_translate}</legend>
Expand Down

0 comments on commit 12de87f

Please sign in to comment.