From 15d4db3b4a7dbc9a7e089f9329a396f8408ed7d9 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 17 Feb 2016 17:30:51 +1300 Subject: [PATCH 1/6] [ss-2015-028] Block unauthenticated access to dev/build/defaults --- dev/DevelopmentAdmin.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/DevelopmentAdmin.php b/dev/DevelopmentAdmin.php index 348391085..55584cb20 100644 --- a/dev/DevelopmentAdmin.php +++ b/dev/DevelopmentAdmin.php @@ -33,7 +33,8 @@ class DevelopmentAdmin extends Controller { parent::init(); // Special case for dev/build: Defer permission checks to DatabaseAdmin->init() (see #4957) - $requestedDevBuild = (stripos($this->getRequest()->getURL(), 'dev/build') === 0); + $requestedDevBuild = (stripos($this->getRequest()->getURL(), 'dev/build') === 0) + && (stripos($this->getRequest()->getURL(), 'dev/build/defaults') === false); // We allow access to this controller regardless of live-status or ADMIN permission only // if on CLI. Access to this controller is always allowed in "dev-mode", or of the user is ADMIN. From e2c77c5a8f13e901c51a3684210811559b592f0c Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 17 Feb 2016 15:09:21 +1300 Subject: [PATCH 2/6] [ss-2016-002] Ensure Gridfield actions respect CSRF --- forms/gridfield/GridField.php | 12 +++ .../gridfield/GridFieldDeleteActionTest.php | 96 ++++++++++++++++--- 2 files changed, 95 insertions(+), 13 deletions(-) diff --git a/forms/gridfield/GridField.php b/forms/gridfield/GridField.php index c18115514..e0414914d 100644 --- a/forms/gridfield/GridField.php +++ b/forms/gridfield/GridField.php @@ -833,6 +833,18 @@ class GridField extends FormField { */ public function gridFieldAlterAction($data, $form, SS_HTTPRequest $request) { $data = $request->requestVars(); + + // Protection against CSRF attacks + $token = $this + ->getForm() + ->getSecurityToken(); + if(!$token->checkRequest($request)) { + $this->httpError(400, _t("Form.CSRF_FAILED_MESSAGE", + "There seems to have been a technical problem. Please click the back button, ". + "refresh your browser, and try again." + )); + } + $name = $this->getName(); $fieldData = null; diff --git a/tests/forms/gridfield/GridFieldDeleteActionTest.php b/tests/forms/gridfield/GridFieldDeleteActionTest.php index 2d0f2c4d6..2f4d2d909 100644 --- a/tests/forms/gridfield/GridFieldDeleteActionTest.php +++ b/tests/forms/gridfield/GridFieldDeleteActionTest.php @@ -42,15 +42,54 @@ class GridFieldDeleteActionTest extends SapphireTest { $this->assertEquals(3, count($deleteButtons), 'Delete buttons should show when logged in.'); } + public function testActionsRequireCSRF() { + $this->logInWithPermission('ADMIN'); + $this->setExpectedException( + 'SS_HTTPResponse_Exception', + _t("Form.CSRF_FAILED_MESSAGE", + "There seems to have been a technical problem. Please click the back button, ". + "refresh your browser, and try again." + ), + 400 + ); + $stateID = 'testGridStateActionField'; + $request = new SS_HTTPRequest( + 'POST', + 'url', + array(), + array( + 'action_gridFieldAlterAction?StateID='.$stateID, + 'SecurityID' => null, + ) + ); + $this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request); + } + public function testDeleteActionWithoutCorrectPermission() { if(Member::currentUser()) { Member::currentUser()->logOut(); } $this->setExpectedException('ValidationException'); $stateID = 'testGridStateActionField'; - Session::set($stateID, array('grid'=>'', 'actionName'=>'deleterecord', - 'args'=>array('RecordID'=>$this->idFromFixture('GridFieldAction_Delete_Team', 'team1')))); - $request = new SS_HTTPRequest('POST', 'url', array(), - array('action_gridFieldAlterAction?StateID='.$stateID=>true)); + Session::set( + $stateID, + array( + 'grid' => '', + 'actionName' => 'deleterecord', + 'args' => array( + 'RecordID' => $this->idFromFixture('GridFieldAction_Delete_Team', 'team1') + ) + ) + ); + $token = SecurityToken::inst(); + $request = new SS_HTTPRequest( + 'POST', + 'url', + array(), + array( + 'action_gridFieldAlterAction?StateID='.$stateID => true, + $token->getName() => $token->getValue(), + ) + ); $this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request); $this->assertEquals(3, $this->list->count(), 'User should\'t be able to delete records without correct permissions.'); @@ -59,10 +98,26 @@ class GridFieldDeleteActionTest extends SapphireTest { public function testDeleteActionWithAdminPermission() { $this->logInWithPermission('ADMIN'); $stateID = 'testGridStateActionField'; - Session::set($stateID, array('grid'=>'', 'actionName'=>'deleterecord', - 'args'=>array('RecordID'=>$this->idFromFixture('GridFieldAction_Delete_Team', 'team1')))); - $request = new SS_HTTPRequest('POST', 'url', array(), - array('action_gridFieldAlterAction?StateID='.$stateID=>true)); + Session::set( + $stateID, + array( + 'grid'=>'', + 'actionName'=>'deleterecord', + 'args' => array( + 'RecordID' => $this->idFromFixture('GridFieldAction_Delete_Team', 'team1') + ) + ) + ); + $token = SecurityToken::inst(); + $request = new SS_HTTPRequest( + 'POST', + 'url', + array(), + array( + 'action_gridFieldAlterAction?StateID='.$stateID=>true, + $token->getName() => $token->getValue(), + ) + ); $this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request); $this->assertEquals(2, $this->list->count(), 'User should be able to delete records with ADMIN permission.'); } @@ -76,11 +131,26 @@ class GridFieldDeleteActionTest extends SapphireTest { $form = new Form(new Controller(), 'mockform', new FieldList(array($this->gridField)), new FieldList()); $stateID = 'testGridStateActionField'; - Session::set($stateID, array('grid'=>'', 'actionName'=>'deleterecord', - 'args'=>array('RecordID'=>$this->idFromFixture('GridFieldAction_Delete_Team', 'team1')))); - $request = new SS_HTTPRequest('POST', 'url', array(), - array('action_gridFieldAlterAction?StateID='.$stateID=>true)); - + Session::set( + $stateID, + array( + 'grid'=>'', + 'actionName'=>'deleterecord', + 'args' => array( + 'RecordID' => $this->idFromFixture('GridFieldAction_Delete_Team', 'team1') + ) + ) + ); + $token = SecurityToken::inst(); + $request = new SS_HTTPRequest( + 'POST', + 'url', + array(), + array( + 'action_gridFieldAlterAction?StateID='.$stateID=>true, + $token->getName() => $token->getValue(), + ) + ); $this->gridField->gridFieldAlterAction(array('StateID'=>$stateID), $this->form, $request); $this->assertEquals(2, $this->list->count(), 'User should be able to delete records with ADMIN permission.'); From faa94d51d570788dcebc2f2ef6e9de4d179ce1e4 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Wed, 17 Feb 2016 23:19:19 +1300 Subject: [PATCH 3/6] [ss-2016-003] Hostname, IP and Protocol Spoofing through HTTP Headers --- control/Director.php | 40 +++++++++--------- control/HTTPRequest.php | 25 ++++++++--- core/Constants.php | 9 ++-- core/startup/ParameterConfirmationToken.php | 42 +++++++++---------- .../09_Security/04_Secure_Coding.md | 5 ++- 5 files changed, 68 insertions(+), 53 deletions(-) diff --git a/control/Director.php b/control/Director.php index 0236f8a68..46565d7b5 100644 --- a/control/Director.php +++ b/control/Director.php @@ -507,28 +507,28 @@ class Director implements TemplateGlobalProvider { */ public static function is_https() { $return = false; + + // See https://en.wikipedia.org/wiki/List_of_HTTP_header_fields + // See https://support.microsoft.com/?kbID=307347 + $headerOverride = false; + if(TRUSTED_PROXY) { + $headers = (defined('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) ? array(SS_TRUSTED_PROXY_PROTOCOL_HEADER) : null; + if(!$headers) { + // Backwards compatible defaults + $headers = array('HTTP_X_FORWARDED_PROTO', 'HTTP_X_FORWARDED_PROTOCOL', 'HTTP_FRONT_END_HTTPS'); + } + foreach($headers as $header) { + $headerCompareVal = ($header === 'HTTP_FRONT_END_HTTPS' ? 'on' : 'https'); + if(!empty($_SERVER[$header]) && strtolower($_SERVER[$header]) == $headerCompareVal) { + $headerOverride = true; + break; + } + } + } + if ($protocol = Config::inst()->get('Director', 'alternate_protocol')) { $return = ($protocol == 'https'); - } else if( - TRUSTED_PROXY - && isset($_SERVER['HTTP_X_FORWARDED_PROTO']) - && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' - ) { - // Convention for (non-standard) proxy signaling a HTTPS forward, - // see https://en.wikipedia.org/wiki/List_of_HTTP_header_fields - $return = true; - } else if( - TRUSTED_PROXY - && isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) - && strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https' - ) { - // Less conventional proxy header - $return = true; - } else if( - isset($_SERVER['HTTP_FRONT_END_HTTPS']) - && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) == 'on' - ) { - // Microsoft proxy convention: https://support.microsoft.com/?kbID=307347 + } else if($headerOverride) { $return = true; } else if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) { $return = true; diff --git a/control/HTTPRequest.php b/control/HTTPRequest.php index 1aab8f26a..a75131371 100644 --- a/control/HTTPRequest.php +++ b/control/HTTPRequest.php @@ -655,14 +655,27 @@ class SS_HTTPRequest implements ArrayAccess { * @return string */ public function getIP() { - if (TRUSTED_PROXY && !empty($_SERVER['HTTP_CLIENT_IP'])) { - //check ip from share internet - return $_SERVER['HTTP_CLIENT_IP']; - } elseif (TRUSTED_PROXY && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { - //to check ip is pass from proxy - return $_SERVER['HTTP_X_FORWARDED_FOR']; + $headerOverrideIP = null; + if(TRUSTED_PROXY) { + $headers = (defined('SS_TRUSTED_PROXY_IP_HEADER')) ? array(SS_TRUSTED_PROXY_IP_HEADER) : null; + if(!$headers) { + // Backwards compatible defaults + $headers = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR'); + } + foreach($headers as $header) { + if(!empty($_SERVER[$header])) { + $headerOverrideIP = $_SERVER[$header]; + break; + } + } + } + + if ($headerOverrideIP) { + return $headerOverrideIP; } elseif(isset($_SERVER['REMOTE_ADDR'])) { return $_SERVER['REMOTE_ADDR']; + } else { + return null; } } diff --git a/core/Constants.php b/core/Constants.php index 3e958a0ea..a7e1b92aa 100644 --- a/core/Constants.php +++ b/core/Constants.php @@ -179,10 +179,13 @@ if(!isset($_SERVER['HTTP_HOST'])) { /** * Fix HTTP_HOST from reverse proxies */ - if (TRUSTED_PROXY && isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { - + $trustedProxyHeader = (defined('SS_TRUSTED_PROXY_HOST_HEADER')) + ? SS_TRUSTED_PROXY_HOST_HEADER + : 'HTTP_X_FORWARDED_HOST'; + + if (TRUSTED_PROXY && !empty($_SERVER[$trustedProxyHeader])) { // Get the first host, in case there's multiple separated through commas - $_SERVER['HTTP_HOST'] = strtok($_SERVER['HTTP_X_FORWARDED_HOST'], ','); + $_SERVER['HTTP_HOST'] = strtok($_SERVER[SS_TRUSTED_PROXY_HOST_HEADER], ','); } } diff --git a/core/startup/ParameterConfirmationToken.php b/core/startup/ParameterConfirmationToken.php index 6c98300a0..b141fa037 100644 --- a/core/startup/ParameterConfirmationToken.php +++ b/core/startup/ParameterConfirmationToken.php @@ -163,26 +163,25 @@ class ParameterConfirmationToken { // Are we http or https? Replicates Director::is_https() without its dependencies/ $proto = 'http'; - if( - TRUSTED_PROXY - && isset($_SERVER['HTTP_X_FORWARDED_PROTO']) - && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' - ) { - // Convention for (non-standard) proxy signaling a HTTPS forward, - // see https://en.wikipedia.org/wiki/List_of_HTTP_header_fields - $proto = 'https'; - } else if( - TRUSTED_PROXY - && isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) - && strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https' - ) { - // Less conventional proxy header - $proto = 'https'; - } else if( - isset($_SERVER['HTTP_FRONT_END_HTTPS']) - && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) == 'on' - ) { - // Microsoft proxy convention: https://support.microsoft.com/?kbID=307347 + // See https://en.wikipedia.org/wiki/List_of_HTTP_header_fields + // See https://support.microsoft.com/?kbID=307347 + $headerOverride = false; + if(TRUSTED_PROXY) { + $headers = (defined('SS_TRUSTED_PROXY_PROTOCOL_HEADER')) ? array(SS_TRUSTED_PROXY_PROTOCOL_HEADER) : null; + if(!$headers) { + // Backwards compatible defaults + $headers = array('HTTP_X_FORWARDED_PROTO', 'HTTP_X_FORWARDED_PROTOCOL', 'HTTP_FRONT_END_HTTPS'); + } + foreach($headers as $header) { + $headerCompareVal = ($header === 'HTTP_FRONT_END_HTTPS' ? 'on' : 'https'); + if(!empty($_SERVER[$header]) && strtolower($_SERVER[$header]) == $headerCompareVal) { + $headerOverride = true; + break; + } + } + } + + if($headerOverride) { $proto = 'https'; } else if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) { $proto = 'https'; @@ -190,9 +189,6 @@ class ParameterConfirmationToken { $proto = 'https'; } - if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) $proto = 'https'; - if(isset($_SERVER['SSL'])) $proto = 'https'; - $parts = array_filter(array( // What's our host $_SERVER['HTTP_HOST'], diff --git a/docs/en/02_Developer_Guides/09_Security/04_Secure_Coding.md b/docs/en/02_Developer_Guides/09_Security/04_Secure_Coding.md index 633b59831..6b56bb01d 100644 --- a/docs/en/02_Developer_Guides/09_Security/04_Secure_Coding.md +++ b/docs/en/02_Developer_Guides/09_Security/04_Secure_Coding.md @@ -580,7 +580,11 @@ server IPs using the SS_TRUSTED_PROXY_IPS define in your _ss_environment.php. :::php define('SS_TRUSTED_PROXY_IPS', '127.0.0.1,192.168.0.1'); + define('SS_TRUSTED_PROXY_HOST_HEADER', 'HTTP_X_FORWARDED_HOST'); + define('SS_TRUSTED_PROXY_IP_HEADER', 'HTTP_X_FORWARDED_FOR'); + define('SS_TRUSTED_PROXY_PROTOCOL_HEADER', 'HTTP_X_FORWARDED_PROTOCOL'); +At the same time, you'll also need to define which headers you trust from these proxy IPs. Since there are multiple ways through which proxies can pass through HTTP information on the original hostname, IP and protocol, these values need to be adjusted for your specific proxy. The header names match their equivalent `$_SERVER` values. If there is no proxy server, 'none' can be used to distrust all clients. If only trusted servers will make requests then you can use '*' to trust all clients. @@ -603,7 +607,6 @@ In a future release this behaviour will be changed to be on by default, and this variable will be no longer necessary, thus it will be necessary to always set SS_TRUSTED_PROXY_IPS if using a proxy. - ## Related * [http://silverstripe.org/security-releases/](http://silverstripe.org/security-releases/) From 6cd66a6b13e47439da503df5185e20c3ea0f01e3 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 24 Feb 2016 12:01:41 +1300 Subject: [PATCH 4/6] Added 3.2.2-rc2 changelog --- docs/en/04_Changelogs/rc/3.2.2-rc2.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/en/04_Changelogs/rc/3.2.2-rc2.md diff --git a/docs/en/04_Changelogs/rc/3.2.2-rc2.md b/docs/en/04_Changelogs/rc/3.2.2-rc2.md new file mode 100644 index 000000000..41a03f1f8 --- /dev/null +++ b/docs/en/04_Changelogs/rc/3.2.2-rc2.md @@ -0,0 +1,11 @@ +# 3.2.2-rc2 + + + +## Change Log + +### Security + + * 2016-02-17 [faa94d5](https://github.com/silverstripe/silverstripe-framework/commit/faa94d51d570788dcebc2f2ef6e9de4d179ce1e4) Hostname, IP and Protocol Spoofing through HTTP Headers (Ingo Schommer) - See [ss-2016-003](http://www.silverstripe.org/download/security-releases/ss-2016-003) + * 2016-02-17 [15d4db3](https://github.com/silverstripe/silverstripe-framework/commit/15d4db3b4a7dbc9a7e089f9329a396f8408ed7d9) Block unauthenticated access to dev/build/defaults (Damian Mooyman) - See [ss-2015-028](http://www.silverstripe.org/download/security-releases/ss-2015-028) + * 2016-02-17 [e2c77c5](https://github.com/silverstripe/silverstripe-framework/commit/e2c77c5a8f13e901c51a3684210811559b592f0c) Ensure Gridfield actions respect CSRF (Damian Mooyman) - See [ss-2016-002](http://www.silverstripe.org/download/security-releases/ss-2016-002) From 50aab6d8d4d8cbe18282de774d2e26150558eb04 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 24 Feb 2016 15:14:58 +1300 Subject: [PATCH 5/6] Update translations --- lang/cs.yml | 5 +++++ lang/lt.yml | 5 +++++ lang/sk.yml | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/lang/cs.yml b/lang/cs.yml index 6245a3427..60ec7fad0 100644 --- a/lang/cs.yml +++ b/lang/cs.yml @@ -301,6 +301,8 @@ cs: FROMWEB: 'Z webu' FindInFolder: 'Hledat ve složce' IMAGEALT: 'Alternativní text (alt)' + IMAGEALTTEXT: 'Alternativní text (alt) - bude ukázán, když obrázek nemúže být zobrazen' + IMAGEALTTEXTDESC: 'Zobrazeno na obrazovce, když obrázek nemůže být zobrazen' IMAGEDIMENSIONS: Rozměry IMAGEHEIGHTPX: Výška IMAGETITLE: 'Titul text (tooltip) - další informace o obrázku' @@ -334,10 +336,13 @@ cs: LeftAndMain: CANT_REORGANISE: 'Nemáte oprávnění měnit stránky nejvyšší úrovně. Vaše změna nebyla uložena.' DELETED: Smazáno. + DropdownBatchActionsDefault: Akce HELP: Nápověda + PAGETYPE: 'Typ stránky' PERMAGAIN: 'Byli jste odhlášeni z CMS. Pokud se chcete znovu přihlásit, zadejte níže své uživatelské jméno a heslo.' PERMALREADY: 'Omlouvám se, ale nemůžete vstoupit do této části CMS. Pokud se chcete přihlásit jako někdo jiný, udělejte tak níže.' PERMDEFAULT: 'Musíte být přihlášen/a k přístup do oblasti administrace, níže zadejte vaše přihlašovací údaje, prosím.' + PLEASESAVE: 'Prosím uložte stránku: Tato stránka nemohla být aktualizována, ještě nebyla uložena.' PreviewButton: Náhled REORGANISATIONSUCCESSFUL: 'Strom webu reorganizován úspěšně.' SAVEDUP: Uloženo. diff --git a/lang/lt.yml b/lang/lt.yml index 2a06f3eb5..13d5c7e0f 100644 --- a/lang/lt.yml +++ b/lang/lt.yml @@ -301,6 +301,8 @@ lt: FROMWEB: 'Iš interneto' FindInFolder: 'Rasti kataloge' IMAGEALT: 'Alternatyvus tekstas (alt)' + IMAGEALTTEXT: 'Alternatyvus tekstas (alt) - rodomas, jeigu nepavyko parodyti paveikslėlio' + IMAGEALTTEXTDESC: 'Rodomas, jeigu nepavyko parodyti paveikslėlio' IMAGEDIMENSIONS: Matmenys IMAGEHEIGHTPX: Aukštis IMAGETITLE: 'Pavadinimo tekstas (tooltip) - papildomai informacijai apie paveikslėlį' @@ -334,10 +336,13 @@ lt: LeftAndMain: CANT_REORGANISE: 'Jūs neturite leidimo keisti aukščiausio lygio puslapių. Jūsų pakeitimai neišsaugoti.' DELETED: Ištrinta. + DropdownBatchActionsDefault: Veiksmai HELP: Pagalba + PAGETYPE: 'Puslapio tipas' PERMAGAIN: 'Jūs atsijungėte. Norėdami vėl prisijungti, įveskite savo duomenis į žemiau esančius laukelius.' PERMALREADY: 'Deja, bet Jūs negalite patekti į šią TVS dalį. Jeigu norite prisijungti kitu vartotoju, tai atlikite žemiau.' PERMDEFAULT: 'Jūs turite būti prisijungę, norėdami pasiekti administravimo zoną; prašome suvesti prisijungimo duomenis į žemiau esančius laukelius.' + PLEASESAVE: 'Prašome išsaugoti puslapį: Šis puslapis negali būti atnaujintas, nes jis dar nėra išsaugotas.' PreviewButton: Peržiūra REORGANISATIONSUCCESSFUL: 'Puslapių medis pertvarkytas sėkmingai.' SAVEDUP: Išsaugota. diff --git a/lang/sk.yml b/lang/sk.yml index 52bba5a82..9433fb357 100644 --- a/lang/sk.yml +++ b/lang/sk.yml @@ -301,6 +301,8 @@ sk: FROMWEB: 'Z webu' FindInFolder: 'Vyhľadať v priečinku' IMAGEALT: 'Atlernatívny text (alt)' + IMAGEALTTEXT: 'Atlernatívny text (alt) - sa zobrazí, ak nemôže byť zobrazený obrázok' + IMAGEALTTEXTDESC: 'Zobrazí sa na obrazovke, keď obrázok nemôže byť zobrazený' IMAGEDIMENSIONS: Rozmery IMAGEHEIGHTPX: Výška IMAGETITLE: 'Text titulky (tooltip) - pre doplňujúce informácie o obrázku' @@ -334,10 +336,13 @@ sk: LeftAndMain: CANT_REORGANISE: 'Nemáte oprávnenie meniť stránky najvyššej úrovne. Vaša zmena nebola uložená.' DELETED: Zmazané. + DropdownBatchActionsDefault: Akcie HELP: Pomoc + PAGETYPE: 'Typ stránky:' PERMAGAIN: 'Boli ste odhlásený' PERMALREADY: 'Je nám ľúto, ale k tejto časti CMS nemáte prístup . Ak sa chcete prihlásiť ako niekto iný, urobte tak nižšie.' PERMDEFAULT: 'Musíte byť prihlásený/á k prístupu do oblasti administrácie, zadajte vaše prihlasovacie údaje dole, prosím.' + PLEASESAVE: 'Prosím uložte stránku: Táto stránka nemôže byť aktualizovaná, ešte nebola uložená.' PreviewButton: Náhľad REORGANISATIONSUCCESSFUL: 'Strom webu bol reorganizovaný úspešne.' SAVEDUP: Uložené. From 531b8b167baf2954ee53747cfa4ad00946a79c84 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 24 Feb 2016 15:33:02 +1300 Subject: [PATCH 6/6] Added 3.2.2 changelog --- docs/en/04_Changelogs/3.2.2.md | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 docs/en/04_Changelogs/3.2.2.md diff --git a/docs/en/04_Changelogs/3.2.2.md b/docs/en/04_Changelogs/3.2.2.md new file mode 100644 index 000000000..8252dd678 --- /dev/null +++ b/docs/en/04_Changelogs/3.2.2.md @@ -0,0 +1,40 @@ +# 3.2.2 + + + +## Change Log + +### Security + + * 2016-02-17 [faa94d5](https://github.com/silverstripe/silverstripe-framework/commit/faa94d51d570788dcebc2f2ef6e9de4d179ce1e4) Hostname, IP and Protocol Spoofing through HTTP Headers (Ingo Schommer) - See [ss-2016-003](http://www.silverstripe.org/download/security-releases/ss-2016-003) + * 2016-02-17 [15d4db3](https://github.com/silverstripe/silverstripe-framework/commit/15d4db3b4a7dbc9a7e089f9329a396f8408ed7d9) Block unauthenticated access to dev/build/defaults (Damian Mooyman) - See [ss-2015-028](http://www.silverstripe.org/download/security-releases/ss-2015-028) + * 2016-02-17 [e2c77c5](https://github.com/silverstripe/silverstripe-framework/commit/e2c77c5a8f13e901c51a3684210811559b592f0c) Ensure Gridfield actions respect CSRF (Damian Mooyman) - See [ss-2016-002](http://www.silverstripe.org/download/security-releases/ss-2016-002) + * 2015-11-11 [245e0aa](https://github.com/silverstripe/silverstripe-framework/commit/245e0aae2f5f3eb0acba1d198ad8e196bb224462) Fix FormField error messages not being encoded safely (Damian Mooyman) - See [ss-2015-026](http://www.silverstripe.org/download/security-releases/ss-2015-026) + * 2015-11-09 [53b3bc7](https://github.com/silverstripe/silverstripe-framework/commit/53b3bc707bcccb8f5e5060f85ab1398a0975bba2) Dont expose class on error (Hamish Friedlander) - See [ss-2015-025](http://www.silverstripe.org/download/security-releases/ss-2015-025) + * 2015-11-01 [ac4342d](https://github.com/silverstripe/silverstripe-framework/commit/ac4342d81d19201bd8d3814f168240db1ac565fe) XML escape RSSFeed $link parameter (Ingo Schommer) - See [ss-2015-022](http://www.silverstripe.org/download/security-releases/ss-2015-022) + * 2015-10-28 [97f21fd](https://github.com/silverstripe/silverstripe-framework/commit/97f21fddb3c565052f19ee3b35366f48e1e9a36f) Fix rewrite hash links XSS (Damian Mooyman) - See [ss-2015-021](http://www.silverstripe.org/download/security-releases/ss-2015-021) + +### Bugfixes + + * 2016-02-15 [8771859](https://github.com/silverstripe/silverstripe-framework/commit/87718597e8f04872c285808d0666fbb69c5100ba) "where" method in SQLUpdate Example (Richard Rudy) + * 2016-01-28 [3fcf1e2](https://github.com/silverstripe/silverstripe-framework/commit/3fcf1e2c98629dcd0048ff9447bad4cd30b4bf95) edge case on many many extra fields (fixes 4991) (Mark Stephens) + * 2016-01-27 [3d0178e](https://github.com/silverstripe/silverstripe-cms/commit/3d0178ebc0b7408442ad2532f998ed47839e7117) Use correct formaction for doRollback exemption (Damian Mooyman) + * 2016-01-24 [d8e354d](https://github.com/silverstripe/silverstripe-framework/commit/d8e354d144383fb6459adf92731853d2e54268d6) PHPDocs on DataList::getIDList() and UnsavedRelationList::getIDList() (Damian Mooyman) + * 2016-01-22 [bf8bf5e](https://github.com/silverstripe/silverstripe-framework/commit/bf8bf5e4d558126bb99ea63881f1885faafddd3d) Prevent Versioned::doRollbackTo from creating incorrect versions on subclasses of Versioned DataObjects (Damian Mooyman) + * 2016-01-21 [cca7129](https://github.com/silverstripe/silverstripe-framework/commit/cca7129385dbb3be1001a8861423c2cf490f02d4) Revert lost documentation (Damian Mooyman) + * 2016-01-11 [85ba918](https://github.com/silverstripe/silverstripe-framework/commit/85ba918a54f51dd524d45f2c93172a18421ae3bf) Update field IDs for file link (fixes silverstripe/silverstripe-cms#1307) (Loz Calver) + * 2016-01-11 [d637141](https://github.com/silverstripe/silverstripe-cms/commit/d6371414876e32e7369ec0219a57d2186cfe3f0f) preg_quote() anchors in SiteTreeLinkTracking (fixes #1359) (Loz Calver) + * 2016-01-05 [00544ff](https://github.com/silverstripe/silverstripe-framework/commit/00544ff100048afdb7ccb1905304dddf8ab3205a) session_regenerate_id uses config system (Daniel Hensby) + * 2016-01-05 [4335d8e](https://github.com/silverstripe/silverstripe-framework/commit/4335d8ed221a2b402299b32e31f97fc2956ec161) Members with no ID inherit logged in user permission (Daniel Hensby) + * 2015-12-15 [afbb5cf](https://github.com/silverstripe/silverstripe-framework/commit/afbb5cfed4d29aea5868f0f12cd735dc5abe10d3) Vimeo oEmbed endpoint redirecting to no www (UndefinedOffset) + * 2015-12-14 [d265c9b](https://github.com/silverstripe/silverstripe-framework/commit/d265c9b733ddac27d6df286ce000b09e1c69b986) Allow omitting a value for OptionsetField submissions (fixes #4824) (Loz Calver) + * 2015-12-11 [5a21b2f](https://github.com/silverstripe/silverstripe-framework/commit/5a21b2fb15ed9c675594f0f990765bd4f97155c7) Guard against users being added to all groups on unsaved Group. (Mateusz Uzdowski) + * 2015-11-27 [94742fa](https://github.com/silverstripe/silverstripe-framework/commit/94742fa3e2efad8f77f4acd1f9d06bf74916c5e6) Revert method visibility regression (Damian Mooyman) + * 2015-11-18 [e9b833f](https://github.com/silverstripe/silverstripe-framework/commit/e9b833f5f0f989af8d611f8cfe71f0b0e2cb0159) ConfirmedPassword field correctly reports mismatching passwords (Christopher Darling) + * 2015-11-17 [68d99be](https://github.com/silverstripe/silverstripe-framework/commit/68d99be24b63a933f041cd80a248a7b7fa8d588c) Hidden errors for composite fields nested inside FieldGroups (fixes #4773) (Loz Calver) + * 2015-11-17 [97e90b8](https://github.com/silverstripe/silverstripe-cms/commit/97e90b8ebd8078bb60ecea66bdd3761380f93a61) RedirectorPage toggles not working (fixes #1328) (Loz Calver) + * 2015-11-17 [b624eb9](https://github.com/silverstripe/silverstripe-cms/commit/b624eb98f1d1ff36811a3294ad29b31a50683d60) Setting target for unwritten VirtualPage breaks write (Loz Calver) + * 2015-11-16 [2983d82](https://github.com/silverstripe/silverstripe-cms/commit/2983d823d1eef293ef11aac9e01336e23ed52b59) Ensure VirtualPage forwards request/response data to virtual controllers (fixes #1329) (Loz Calver) + * 2015-11-12 [fea1158](https://github.com/silverstripe/silverstripe-framework/commit/fea1158d193ed4d037df94101e3b3f2d24a6ce49) Fix print button only displaying first page (Damian Mooyman) + * 2015-11-11 [a40812a](https://github.com/silverstripe/silverstripe-framework/commit/a40812ac3320d27f243ef0ed54aa003fc53720b6) Don’t reuse DBConnector (fixes #4735) (Sam Minnee) + * 2015-11-05 [f577ecb](https://github.com/silverstripe/silverstripe-framework/commit/f577ecb81149d0d09dc846204f17b2153a244b5a) prevent use cache on browser back button (Igor Nadj)