How to fix Potential for Information Disclosure in CakePHP

fix Potential for Information Disclosure in CakePHP

The default application skeleton contained a beforeRender() method on the AppController that could potentially lead to unwanted information disclosure in your application. The unsafe default code was present between 3.1.0 and 3.5.0 of the application skeleton.

Risks

The default beforeRender hook would automatically serialize all view variables into JSON/XML if the _serialize view variable was not defined by the controller action. Controller methods that define the _serialize variable would behave correctly and only expose the named variables.

This behavior is triggered by the AppController and ErrorController loading RequestHandlerComponent, which configures the View class to be used based on the client’s Accept header. Then code in AppController::beforeRender() would enable all view variables to be serialized if no variables were explicitly listed.

The default controllers generated by bake set the _serialize view variable. This helps limit the impact, but could still lead to unwanted information exposure if entity classes are not correctly configured.

How to fix

You can fix the potential for information disclosure by modifying your application code. Unfortunately we cannot resolve this problem for you through a patch release of CakePHP or its appplication skeleton.

If you don’t have ErrorController in your src/Controller directory (CakePHP <= 3.3)

If you are using CakePHP 3.3.0 or greater and do not have an ErrorController in your application, you should download an ErrorController and put it into your src/Controller directory.

If you don’t use JSON/XML response based on client requests

  • Remove $this->loadComponent(‘RequestHandler’) from the initialize() method of your AppController and ErrorController.
  • Remove $this->set(‘_serialize’, true); from the beforeRender() of your AppController.

If you use JSON/XML response based on client requests

  • Remove $this->set(‘_serialize’, true); from the beforeRender() of your AppController.
  • Remove $this->set(‘_serialize’, [ (variable names) ]) from all controller actions, that should not return JSON/XML.
  • Add $this->set(‘_serialize’, [ (variable names) ]) explicitly to some actions of your controllers, which you want to return JSON/XML.

While we have no reports of information disclosure in the wild, this issue was found by Kurita Takashi and we felt this was important to disclose.

Read From Official CakePHP blog

How to Working with Views in CakePHP

Working with Views in CakePHP

The letter “V” in the MVC is for Views. Views are responsible for sending output to user based on request. View Classes is a powerful way to speed up the development process.

View Templates

The View Templates file of CakePHP has default extension .ctp (CakePHP Template). These templates get data from controller and then render the output so that it can be displayed properly to the user. We can use variables, various control structures in template.

Template files are stored in src/Template/, in a directory named after the controller that uses the files, and named after the action it corresponds to. For example, the View file for the Products controller’s “view()” action, would normally be found in src/Template/Products/view.ctp.

In short, the name of the controller (ProductsController) is same as the name of the folder (Products) but without the word Controller and name of action/method (view()) of the controller (ProductsController) is same as the name of the View file(view.ctp).

View Variables

View variables are variables which get the value from controller. We can use as many variables in view templates as we want. We can use the set() method to pass values to variables in views. These set variables will be available in both the view and the layout your action renders. The following is the syntax of the set() method.

Syntax

Cake\View\View::set(string $var, mixed $value)

This method takes two arguments − the name of the variable and its value.

Example

Make Changes in the config/routes.php file as shown in the following program.

config/routes.php

<?php
   use Cake\Core\Plugin;
   use Cake\Routing\RouteBuilder;
   use Cake\Routing\Router;

   Router::defaultRouteClass('DashedRoute');
   Router::scope('/', function (RouteBuilder $routes) {
      $routes->connect('template',['controller'=>'Products','action'=>'view']);
      $routes->fallbacks('DashedRoute');
   });
   Plugin::routes();

Create a ProductsController.php file at src/Controller/ProductsController.php. Copy the following code in the controller file.

src/Controller/ProductsController.php

<?php
   namespace App\Controller;
   use App\Controller\AppController;
   
   class ProductsController extends AppController{
      public function view(){
         $this->set('Product_Name','XYZ');
      }
   }
?>

Create a directory Products at src/Template and under that folder create a View file called view.ctp. Copy the following code in that file.

src/Template/Products/view.ctp

Value of variable is: <?php echo $Product_Name; ?>

Execute the above example by visiting the following URL.

http://localhost:85/CakePHP/template

Output

The above URL will produce the following output.

 

products

How to Learn Tutorial in CakePHP

Learn Tutorial in CakePHP

CakePHP is an open-source framework for PHP. It is intended to make developing, deploying and maintaining applications much easier. CakePHP is based on an MVC-like architecture that is both powerful and easy to grasp. Models, Views, and Controllers guarantee a strict but natural separation of business logic from data and presentation layers.

Audience

This tutorial is meant for web developers and students who would like to learn how to develop websites using CakePHP. It will provide a good understanding of how to use this framework.

Prerequisites

Before you proceed with this tutorial, we assume that you have knowledge of HTML, Core PHP, and Advance PHP. We have used CakePHP version 3.2.7 in all the examples.

Tutorials on How to Install CakePHP

Tutorials on How to Install CakePHP

Installing CakePHP is simple and easy. You can install it from composer or you can download it from github − https://github.com/cakephp/cakephp/releases. We will further understand how to install CakePHP in WampServer. After downloading it from github, extract all the files in a folder called “CakePHP” in WampServer. You can give custom name to folder but we have used “CakePHP”.

CakePHP has a few system requirements:

  • HTTP Server. For example: Apache. Having mod_rewrite is preferred, but by no means required. You can also use nginx, or Microsoft IIS if you prefer.
  • PHP 5.6.0 or greater (including PHP 7.3).
  • mbstring PHP extension
  • intl PHP extension
  • simplexml PHP extension
  • PDO PHP extension

 

While a database engine isn’t required, we imagine that most applications will utilize one. CakePHP supports a variety of database storage engines:

  • MySQL (5.5.3 or greater)
  • MariaDB (5.5 or greater)
  • PostgreSQL
  • Microsoft SQL Server (2008 or higher)
  • SQLite 3

Installing CakePHP

Before starting you should make sure that your PHP version is up to date:

php -v

You should have PHP 5.6.0 (CLI) or higher. Your webserver’s PHP version must also be of 5.6.0 or higher, and should be the same version your command line interface (CLI) uses.

Installing Composer

CakePHP uses Composer, a dependency management tool, as the officially supported method for installation.

  • Installing Composer on Linux and macOS

    1. Run the installer script as described in the official Composer documentation and follow the instructions to install Composer.

    2. Execute the following command to move the composer.phar to a directory that is in your path:

      mv composer.phar /usr/local/bin/composer
      
  • Installing Composer on Windows

    For Windows systems, you can download Composer’s Windows installer here. Further instructions for Composer’s Windows installer can be found within the README here.

 

cakephp starting project
CakePHP starting a Project with Command

After a successful installation of cakephp run the server to see the setting information about the application

Read the official CakePHP Installation Document

CakePHP Overview At a glance

CakePHP is an open source Rapid Development MVC framework  written in PHP, modeled after the concepts of Ruby on Rails, and distributed under the MIT License. It makes developing, deploying and maintaining applications much easier. CakePHP has number of libraries to reduce the overload of most common tasks. Following are the advantages of using CakePHP.

  • Open Source
  • MVC Framework
  • Templating Engine
  • Caching Operations
  • Search Engine Friendly URLs
  • Easy CRUD (Create, Read, Update, Delete) Database Interactions.
  • Libraries and Helpers
  • Built-in Validation
  • Localization
  • Email, Cookie, Security, Session, and Request Handling Components
  • View Helpers for AJAX, JavaScript, HTML Forms and More

CakePHP Request Cycle

The following illustration describes how a Request Lifecycle works −

CakePHP Request Cycle

A typical CakePHP request cycle starts with a user requesting a page or resource in your application. At a high level, each request goes through the following steps −

  • The webserver rewrite rules direct the request to webroot/index.php.
  • Your application’s autoloader and bootstrap files are executed.
  • Any dispatch filters that are configured can handle the request, and optionally generate a response.
  • The dispatcher selects the appropriate controller & action based on routing rules.
  • The controller’s action is called and the controller interacts with the required Models and Components.
  • The controller delegates response creation to the View to generate the output resulting from the model data.
  • The view uses Helpers and Cells to generate the response body and headers.
  • The response is sent back to the client.

 

Initial release: April 2005; 13 years ago
Stable release: 3.6.2 / 2018-04-27

How to Services in CakePHP

Services in CakePHP

Authentication

Components are the service layer in CakePHP, Authentication is the process of identifying the correct user. CakePHP supports three types of authentication.

  • FormAuthenticate − It allows you to authenticate users based on form POST data. Usually this is a login form that users enter information into. This is default authentication method.
  • BasicAuthenticate − It allows you to authenticate users using Basic HTTP authentication.
  • DigestAuthenticate − It allows you to authenticate users using Digest HTTP authentication.

Example for FormAuthentication

Make changes in the config/routes.php file as shown in the following code.

config/routes.php

<?php
   use Cake\Core\Plugin;
   use Cake\Routing\RouteBuilder;
   use Cake\Routing\Router;

   Router::defaultRouteClass('DashedRoute');
   Router::scope('/', function (RouteBuilder $routes) {
      $routes->connect('/auth',['controller'=>'Authexs','action'=>'index']);
      $routes->connect('/login',['controller'=>'Authexs','action'=>'login']);
      $routes->connect('/logout',['controller'=>'Authexs','action'=>'logout']);
      $routes->fallbacks('DashedRoute');
   });
   Plugin::routes();

Change the code of AppController.php file as shown in the following program.

src/Controller/AppController.php

<?php
   namespace App\Controller;
   use Cake\Controller\Controller;
   use Cake\Event\Event;
   use Cake\Controller\Component\AuthComponent;

   class AppController extends Controller{
      public function initialize(){
         parent::initialize();
         
         $this->loadComponent('RequestHandler');
         $this->loadComponent('Flash');
         $this->loadComponent('Auth', [
            'authenticate' => [
               'Form' => [
                  'fields' => ['username' => 'username', 'password' => 'password']
               ]
            ],
            'loginAction' => ['controller' => 'Authexs', 'action' => 'login'],
            'loginRedirect' => ['controller' => 'Authexs', 'action' => 'index'],
            'logoutRedirect' => ['controller' => 'Authexs', 'action' => 'login']
         ]);
      
         $this->Auth->config('authenticate', [
            AuthComponent::ALL => ['userModel' => 'users'], 'Form']);
      }
   
      public function beforeRender(Event $event){
         if (!array_key_exists('_serialize', $this=>viewVars) &&
         in_array($this->response=>type(), ['application/json', 'application/xml'])) {
            $this->set('_serialize', true);
         }
      }
   }

Create AuthexsController.php file at src/Controller/AuthexsController.php. Copy the following code in the controller file.

src/Controller/AuthexsController.php

<?php
   namespace App\Controller;
   use App\Controller\AppController;
   use Cake\ORM\TableRegistry;
   use Cake\Datasource\ConnectionManager;
   use Cake\Event\Event;
   use Cake\Auth\DefaultPasswordHasher;

   class AuthexsController extends AppController{
      var $components = array('Auth');
      public function index(){
      }
      public function login(){
         if($this->request->is('post')){
            $user = $this->Auth->identify();
            
            if($user){
               $this->Auth->setUser($user);
               return $this->redirect($this->Auth->redirectUrl());
            } else
            $this->Flash->error('Your username or password is incorrect.');
         }
      }
      public function logout(){
         return $this->redirect($this->Auth->logout());
      }
   }
?>

Create a directory Authexs at src/Template and under that directory create a View file called login.ctp. Copy the following code in that file.

src/Template/Authexs/login.ctp

<?php
   echo $this->Form->create();
   echo $this->Form->input('username');
   echo $this->Form->input('password');
   echo $this->Form->button('Submit');
   echo $this->Form->end();
?>

Create another View file called logout.ctp. Copy the following code in that file.

src/Template/Authexs/logout.ctp

You are successfully loggedout.

Create another View file called index.ctp. Copy the following code in that file.

src/Template/Authexs/index.ctp

You are successfully logged in. 
<?php echo 
   $this->Html->link('logout',["controller" => "Authexs","action" => "logout"]); 
?>

Execute the above example by visiting the following URL.

http://localhost:85/CakePHP/auth

Output

As the authentication has been implemented so once you try to visit the above URL, you will be redirected to the login page as shown below.

Services Authexes

After providing the correct credentials, you will be logged in and redirected to the screen as shown below.

Services Auth

After clicking on the logout link, you will be redirected to the login screen again.

How to Update a Record in CakePHP

Update a Record in CakePHP

To update a record in database we first need to get hold of a table using TableRegistry class. We can fetch the instance out of registry using the get() method. The get() method will take the name of the database table as an argument. Now, this new instance is used to get particular record that we want to update.

Call the get() method with this new instance and pass the primary key to find a record which will be saved in another instance. Use this instance to set new values that you want to update and then finally call the save() method with the TableRegistry class’s instance to update record.

Example

Make changes in the config/routes.php file as shown in the following code.

config/routes.php

<?php use CakeCorePlugin; use CakeRoutingRouteBuilder; use CakeRoutingRouter; Router::defaultRouteClass(‘DashedRoute’); Router::scope(‘/’, function (RouteBuilder $routes) { $routes->connect(‘/users/edit’, [‘controller’ => ‘Users’, ‘action’ => ‘edit’]); $routes->fallbacks(‘DashedRoute’); }); Plugin::routes();

Create a UsersController.php file at src/Controller/UsersController.php. Copy the following code in the controller file.

src/controller/UsersController.php

<?php namespace AppController; use AppControllerAppController; use CakeORMTableRegistry; use CakeDatasourceConnectionManager; class UsersController extends AppController{ public function index(){ $users = TableRegistry::get(‘users’); $query = $users->find(); $this->set(‘results’,$query); } public function edit($id){ if($this->request->is(‘post’)){ $username = $this->request->data(‘username’); $password = $this->request->data(‘password’); $users_table = TableRegistry::get(‘users’); $users = $users_table->get($id); $users->username = $username; $users->password = $password; if($users_table->save($users)) echo “User is udpated”; $this->setAction(‘index’); } else { $users_table = TableRegistry::get(‘users’)->find(); $users = $users_table->where([‘id’=>$id])->first(); $this->set(‘username’,$users->username); $this->set(‘password’,$users->password); $this->set(‘id’,$id); } } } ?>

Create a directory Users at src/Template, ignore if already created, and under that directory create a view called index.ctp. Copy the following code in that file.

src/Template/Users/index.ctp

<a href = “add”>Add User</a> <table> <tr> <td>ID</td> <td>Username</td> <td>Password</td> <td>Edit</td> <td>Delete</td> </tr> <?php foreach ($results as $row): echo “<tr><td>”.$row->id.”</td>”; echo “<td>”.$row->username.”</td>”; echo “<td>”.$row->password.”</td>”; echo “<td><a href = ‘”.$this->Url->build ([“controller” => “Users”,”action” => “edit”,$row->id]). “‘>Edit</a></td>”; echo “<td><a href = ‘”.$this->Url->build ([“controller” => “Users”,”action” => “delete”,$row->id]). “‘>Delete</a></td></tr>”; endforeach; ?> </table>

Create another View file under the Users directory called edit.ctp and copy the following code in it.

src/Template/Users/edit.ctp

<?php echo $this->Form->create(“Users”,array(‘url’=>’/users/edit/’.$id)); echo $this->Form->input(‘username’,[‘value’=>$username]); echo $this->Form->input(‘password’,[‘value’=>$password]); echo $this->Form->button(‘Submit’); echo $this->Form->end(); ?>

Execute the above example by visiting the following URL and click on Edit link to edit record.

http://localhost:85/CakePHP/users

Output

After visiting the above URL and clicking on the Edit link, you will receive the following output where you can edit record.

Update a Record