@@ -239,7 +239,8 @@ public function init(Model $beanAdapter = null, View $view = null, $isBusinessVa
239239 {
240240 $ this ->beanAdapter = $ beanAdapter ;
241241 $ this ->view ->setVar ("Separator " , $ this ->actionsSeparator );
242-
242+ $ this ->view ->setVar ("CSRF_TOKEN_FORM_FIELD " , CSRF_TOKEN_FORM_FIELD );
243+ $ this ->view ->setVar ("CRSFTOKEN " , $ this ->getCSRFToken ());
243244 // $this->doAction($beanAdapter,$isBusinessValidationError);
244245
245246 if (!empty ($ this ->currentRecord [0 ])) {
@@ -276,6 +277,43 @@ public function init(Model $beanAdapter = null, View $view = null, $isBusinessVa
276277
277278 }
278279
280+ /**
281+ * Manages and gets CSRF Token
282+ * @return string The CSRF Token
283+ */
284+ protected function getCSRFToken ()
285+ {
286+ if (@empty ($ _SESSION ['token ' ])) {
287+ if (function_exists ('mcrypt_create_iv ' )) {
288+ // TODO random_bytes
289+ $ _SESSION ['token ' ] = bin2hex (mcrypt_create_iv (32 , MCRYPT_DEV_URANDOM ));
290+ } else {
291+ $ _SESSION ['token ' ] = bin2hex (openssl_random_pseudo_bytes (32 ));
292+ }
293+ }
294+ // print_r($_SESSION['token']);
295+ return $ _SESSION ['token ' ];
296+
297+ }
298+
299+ /**
300+ * Detects CSRF attack
301+ * @return bool True if it detetecs a pibble attack.
302+ */
303+ public function detectedCSRF ()
304+ {
305+ $ csrf_token_field = CSRF_TOKEN_FORM_FIELD ;
306+ if (@!empty ($ _POST [$ csrf_token_field ])) {
307+ if ($ _SESSION ["token " ] == $ _POST [$ csrf_token_field ]) {
308+ return false ;
309+ } else {
310+ return true ;
311+ }
312+ } else {
313+ return true ;
314+ }
315+ }
316+
279317 /**
280318 * Verifies if action's name is valid
281319 * @param string $action The action name
@@ -465,6 +503,16 @@ private function doAction(BeanAdapter $beanAdapter, $isBusinessValidationError =
465503 // Note: also excluded in observing mode.
466504 try {
467505 if (!isset ($ _REQUEST ["getState " ])) {
506+
507+ // Handles CSRF
508+ if (isset ($ _REQUEST [$ this ->record_add ]) || isset ($ _REQUEST [$ this ->record_update ]) || isset ($ _REQUEST [$ this ->record_delete ])) {
509+ if ($ this ->detectedCSRF ()) {
510+ $ isBusinessValidationError = true ;
511+ $ this ->addError ("{RES:CRSFErrorMessage} " );
512+ }
513+ }
514+
515+ // Handles ADD
468516 if (isset ($ _REQUEST [$ this ->record_add ]) && !$ isBusinessValidationError ) {
469517 $ beanAdapter ->insert ();
470518 if ($ beanAdapter ->getBean ()->isSqlError ()) {
@@ -474,6 +522,8 @@ private function doAction(BeanAdapter $beanAdapter, $isBusinessValidationError =
474522 if (!empty ($ this ->redirectAfterAdd ))
475523 header ("Location: " . $ this ->redirectAfterAdd );
476524 }
525+
526+ // Handles UPDATE
477527 if (isset ($ _REQUEST [$ this ->record_update ]) && !$ isBusinessValidationError ) {
478528 $ beanAdapter ->update ($ this ->currentRecord );
479529 if ($ beanAdapter ->getBean ()->isSqlError ()) {
@@ -484,6 +534,7 @@ private function doAction(BeanAdapter $beanAdapter, $isBusinessValidationError =
484534 header ("Location: " . $ this ->redirectAfterUpdate );
485535 }
486536
537+ // Handles DELETE
487538 if (isset ($ _REQUEST [$ this ->record_delete ]) && !$ isBusinessValidationError ) {
488539 $ beanAdapter ->delete ($ this ->currentRecord );
489540 if ($ beanAdapter ->getBean ()->isSqlError ()) {
@@ -494,6 +545,7 @@ private function doAction(BeanAdapter $beanAdapter, $isBusinessValidationError =
494545 header ("Location: " . $ this ->redirectAfterDelete );
495546 }
496547
548+ // Handles Reset
497549 if (isset ($ _REQUEST [$ this ->record_close ])) {
498550 if (!empty ($ this ->redirectAfterClose ))
499551 header ("Location: " . $ this ->redirectAfterClose );
0 commit comments