Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix EZP-20289 Symfony CSRF protection not integrated with legacy #552

Merged
merged 2 commits into from Jan 30, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/bc/5.1/changes-5.1.txt
Expand Up @@ -12,6 +12,16 @@ Change of behavior
only if at least one selection is made, otherwise FALSE. In previous releases
this method always returned TRUE

- Fixed EZP-20289: Symfony CSRF protection not integrated with legacy

Changed ezFormToken to do csrf protection in same way as Symfony meaning
there is now a new setting that must be set pr project to accomplish good
security, set site.ini\[HTMLForms]\Secret on pure legacy/4.x setup.

If your running eZ Publish 5.x, the already existing yml parameter %secret%
will be automatically injected to eZFormToke for you, assuming
config.yml framework.csrf_protection is set to true (enabled).


Removed features
----------------
Expand Down
91 changes: 82 additions & 9 deletions extension/ezformtoken/event/ezxformtoken.php
Expand Up @@ -27,6 +27,79 @@ class ezxFormToken

const REPLACE_KEY = '@$ezxFormToken@';

/**
* @var string|null
*/
static protected $secret;

/**
* @var string
*/
static protected $intention = 'legacy';

/**
* @var string
*/
static protected $formField = self::FORM_FIELD;

/**
* @var string
*/
static protected $token;

/**
* @return string
*/
static protected function getSecret()
{
if ( self::$secret === null )
{
self::$secret = eZINI::instance( 'site.ini' )->variable( 'HTMLForms', 'Secret' );
}

return self::$secret;
}

/**
* @param string $secret
*/
static public function setSecret( $secret )
{
self::$secret = $secret;
}

/**
* @return string
*/
static protected function getIntention()
{
return self::$intention;
}

/**
* @param string $intention
*/
static public function setIntention( $intention )
{
self::$intention = $intention;
}

/**
* @return string
*/
static protected function getFormField()
{
return self::$formField;
}

/**
* @param string $formField
*/
static public function setFormField( $formField )
{
self::$formField = $formField;
}

/**
* request/input event listener
* Checks if form token is valid if user is logged in.
Expand Down Expand Up @@ -55,9 +128,9 @@ static public function input( eZURI $uri )
return null;
}*/

if ( !empty( $_POST[self::FORM_FIELD] ) )
if ( !empty( $_POST[self::getFormField()] ) )
{
$token = $_POST[self::FORM_FIELD];
$token = $_POST[self::getFormField()];
}
// allow ajax calls using POST with other formats than forms (such as
// json or xml) to still validate using a custom http header
Expand Down Expand Up @@ -107,7 +180,7 @@ static public function output( $templateResult )
}

$token = self::getToken();
$field = self::FORM_FIELD;
$field = self::getFormField();
$replaceKey = self::REPLACE_KEY;

eZDebugSetting::writeDebug( 'ezformtoken', 'Output protected (all forms will be modified)', __METHOD__ );
Expand Down Expand Up @@ -149,7 +222,7 @@ static public function output( $templateResult )
static public function reset()
{
eZDebugSetting::writeDebug( 'ezformtoken', 'Reset form token', __METHOD__ );
eZSession::unsetkey( self::SESSION_KEY, false );
self::$token = null;
}

/**
Expand All @@ -160,12 +233,12 @@ static public function reset()
*/
static public function getToken()
{
if ( eZSession::issetkey( self::SESSION_KEY ) )
return eZSession::get( self::SESSION_KEY );
if ( self::$token === null )
{
self::$token = sha1( self::getSecret() . self::getIntention() . session_id() );
}

$token = md5( uniqid( self::SESSION_KEY, true ) );
eZSession::set( self::SESSION_KEY, $token );
return $token;
return self::$token;
}

/**
Expand Down
5 changes: 5 additions & 0 deletions settings/site.ini
Expand Up @@ -313,6 +313,11 @@ QuickSettingsList[]=TemplateSettings;ShowXHTMLCode;site.ini;Inline template debu
QuickSettingsList[]=TemplateSettings;ShowUsedTemplates;site.ini;List of used templates
QuickSettingsList[]=DatabaseSettings;SQLOutput;site.ini;SQL debug output

[HTMLForms]
## Settings dealing with HTML forms and security aspects of it.
# Setting to specify a secret for the csrf protection, it
# is highly recommended that you specify this pr project.
Secret=ThisTokenIsNotSoSecretChangeIt

[URLTranslator]
# Controls whether the url translation is enabled or not.
Expand Down