Environment specific configuration in zend


In software development life cycle, we generally need different type of environments for different purpose like – “development”, “testing”, “production” etc.

And all these environments has some environment specific configuration. like in development server “display error” will be on and payment mode will be “testmode” But in production server “display error” will be off and payment mode will be “livemode” In production server error logging will be on but in testing server it may not be on. Database connection will be different for each environment. etc etc…

Problem:

Its been a big headache to server management team to modify configuration files each time code update to any server.
Here we have created multiple configuration files for each server and automatically loaded environment wise configuration file using “zend-framework”.

Solution:

Here we will consider 3 environment- “Production”, “QA” and “Development” in order to explain the process.
So we will create 4 ini files:
common_config.ini: to keep common configuration (which don’t change with environments)
app_prod.ini: “Production” server specific configuration
app_QA.ini: “QA” server specific configuration
app_dev.ini: “Development” server specific configuration

common_config.ini:

[Production]
phpSettings.error_log = [path to file] "/application.log"

includePaths.application = APP_PATH
includePaths.library = APP_LIB

bootstrap.path = [path to file] "/Bootstrap.php"
bootstrap.class = "Project_Bootstrap"

autoloadernamespaces.0 = "Project"

resources.frontController.moduleControllerDirectoryName = "controllers"
resources.frontController.moduleDirectory = [path to file] "/modules"

resources.frontController.defaultControllerName = "index"
resources.frontController.defaultAction = "index"
resources.frontController.defaultModule = "account"
[QA : Production]
[Development : Production]

Look at last 2 lines- it is saying QA and Development server both will extend configuration from Production.

app_prod.ini:

[Production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
phpSettings.log_errors = 1

;payment related credentials
payment.mode = "liveMode"
;db configuration
resources.db.adapter = "Pdo_Mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "user1"
resources.db.params.password = "pass1"
resources.db.params.dbname = "db_prod"

app_QA.ini:

[QA]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
phpSettings.log_errors = 1

;payment related credentials
payment.mode = "testMode"
;db configuration
resources.db.adapter = "Pdo_Mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "user2"
resources.db.params.password = "pass2"
resources.db.params.dbname = "db_qa"

app_dev.ini:

Similar to QA. you now know what will be in this configuration file. 🙂

So we made ready all configuration files. Now need to load proper configuration for environments.
index.php file will contain something like this:

 

defined('COMMON_CONFIG_INI_PATH') || define('COMMON_CONFIG_INI_PATH',
        [path to file] . '/Config/common_config.ini');

// set APP_INI_PATH according to environment
switch (APP_ENV) {
    case 'Production' :
        defined('APP_INI_PATH') || define('APP_INI_PATH',
            [path to file] . '/Config/app_prod.ini');
        break;
    case 'QA' :
        defined('APP_INI_PATH') || define('APP_INI_PATH',
            [path to file] . '/Config/app_QA.ini');
        break;
    case 'Development' :
        defined('APP_INI_PATH') || define('APP_INI_PATH',
            [path to file] . '/Config/app_dev.ini');
}

defined('APP_LOG_PATH') || define('APP_LOG_PATH',
        realpath(dirname(__FILE__) . '/../logs'));

//Bootstrap the application
require_once('Zend/Application.php');
//load zend_app with config file and run
$application = new Zend_Application(APP_ENV,
        array(
            'config' => array(
                        COMMON_CONFIG_INI_PATH,
                        APP_INI_PATH
                       )
             )
    );
$application->bootstrap()->run();

So here we we have set 2 constant for configuration files according to environment: COMMON_CONFIG_INI_PATH and APP_INI_PATH
and loaded these 2 configuration while bootstrapping.

You are done. Nothing more. Simple, isn’t it? 🙂

Advertisements

HOW  XSS attack handled by different PHP frameworks?


As we know PHP is Open Source, so we can play over it. It also has list of Frameworks to follow for web development.But, while doing development we have to take care about XSS attacks. Now, Question arrise 🙂

What  is XSS?

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into trusted web sites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in form of a browser side script, to a different end user. These attacks can occur anywhere a web application uses input from a user within the output it generates without validating or encoding it.

An attacker can use XSS to send a malicious script to an unsuspecting user. The end user’s browser has no way to know that the script should not be trusted, and will execute the script. Because it thinks the script came from a trusted source, the malicious script can access any cookies, session tokens, or other sensitive information retained by the browser and used with that site. These scripts can even rewrite the content of the HTML page.

Basically, there are two types of XSS attacks:
1.) Stored: due to malicious code is saved on the server, and then sent to the end users, without proper encoding
2.) Reflected: due to malicious code is usually sent to the server in GET or POST parameters in http request, and the server returns that code in response, without proper encoding
It can be protect with :
a.) Filter input, escape output
b.) character encoding

How PHP FramWorks Handle XSS?
  • Yii– output escaping with integrated HTMLPurifier
  • Kohana2 – input filtering / global XSS filter
  • Kohana3 – input filtering, they recommend output escaping with HTMLPurifier, but it’s not included
  • CakePHP – offered a utility called Sanitize, but it is deprecated as of CakePHP 2.4 and will be removed in CakePHP 3.0
  • CodeIgniter – input filtering / global XSS filter
  • Zend Framework – custom output escaping
  • HTMLPurifier is a great solution when you need to display clean HTML that came from untrusted source, but for escaping every piece of data, which won’t be displayed as HTML, is overkill.
  • Global XSS filtering is a very bad idea, beacuse of the reason we mentioned above, you don’t know in which context the data will be used.
  • Sanitize : add() – Sanitize the data in the controller before saving
    beforeSave() – Sanitize the data in the model callback before saving
    afterFind() – Sanitize the data in the model callback after finding
  • OWASP has good security encoding library, but unfortunately, PHP version is not complete yet. They have a good reference for this matter. View
Example:
<body><?php echo htmlencode($untrusted_var); ?></data>
<input value=”<?php echo htmlencode($untrusted_var); ?>” />
While we can in most cases just use php’s htmlentities function.
So, it’s better to write custom wrapper functions, so we can change code only in one place if, for example, we want to add additional filtering or switch to another library.
function htmlencode($str) {
    $str = HTMLPurifier_Encoder::cleanUTF8($str);
    $str = htmlspecialchars($str, ENT_QUOTES, ‘UTF-8’);
    return $str;
}
This function will encode all html characters and prevent breaking the context.
If you need to write user data which contains html, HTMLPurifier will do the job.
I hope this will help you to understand XSS and to use it in your web development eailsy. 🙂
Enjoy Coding!

Setting Default controller for Different Environments in Zend


Sometimes, we create different environment in which we define some default module, controller and action.
So, here the point we need to remember is:

If you do not have modular structure then setting folowing to application.ini should work

resources.frontController.defaultControllerName = “site”
resources.frontController.defaultAction = “action”
resources.frontController.defaultModule = “module”

If you have modular structure then add following

resources.frontController.defaultControllerName = “site”
resources.frontController.defaultAction = “actionName”
resources.frontController.defaultModule = “moduleName”
resources.frontController.params.prefixDefaultModule = “1” // this is imp.
resources.frontController.moduleDirectory = APPLICATION_PATH “/modules”

resources.frontController.params.prefixDefaultModule = “1”
This allows you to re-purpose an existing module to be the default module for an application.
🙂

How to create CRON in zend


It is seen many times that People are struggling to create a Cron.
Creating a cron is not a difficult job. Developer used to struggle about how to set it up.

Cron is nothing but a script which will run on terminal (command prompt)

We will talk about creating a cron using zend framework in php language.

First question arrives in framework:
Generally frameworks have a structure, as zend has its own MVC structure. Now if we want to create a cron for the project which is built in zend, can we use the benefits of a framework? i.e., controller, model, library, helper etc.

The answer is:
Yes, and it is fairly easy in zend.

Lets check how:
Lets assume we already created our module, controller and model and other necessary things to implement certain functionality and already tested using browser.

Now if we directly run the controller from terminal,  it will not work. Because there are no proper bootstrapping done, hence zend will not be able to identify the controller as controller etc.

So, we will create a public php file which will be run in terminal and will bootstrap the zend and call that particular controller.

Lets create cron.php in the public directory of our project,  add put all the necessary constants required to bootstrap. Like-

// Define path to application directory
defined('APP_PATH') || define('APP_PATH', realpath(dirname(__FILE__) . '/../app'));

// Define path to library directory
defined('APP_LIB') || define('APP_LIB', realpath(dirname(__FILE__) . '/../lib'));

// Set application ini path
defined('APP_INI_PATH') || define('APP_INI_PATH', APP_LIB . '/Config/app.ini');

// Ensure library/ is on include_path
 set_include_path(implode(PATH_SEPARATOR, array(
     realpath(APP_PATH . '/../lib'),
     get_include_path()
 )));

// Define application APP_ENV
 defined('APP_ENV') || define('APP_ENV', 'cron-name');

/** Zend_Application */
 require_once 'Zend/Application.php';

// Create application, bootstrap, and run
 $application = new Zend_Application(
 APP_ENV,
 APP_LIB . '/Config/app.ini'
 );
 $application->bootstrap()->run();

Note highlighted APP_ENV, this will be used to call controller.

following code will be in “Config/app.ini” file

['cron-name]
 resources.db.adapter = "pdo_mysql"
 resources.db.params.host = "localhost"
 resources.db.params.username = "root"
 resources.db.params.password = ""
 resources.db.params.dbname = "dbname" 

 resources.frontController.params.prefixDefaultModule = "1"
 resources.frontController.defaultModule         = "yourModuleName"
 resources.frontController.defaultControllerName = "yourControllerName"
 resources.frontController.defaultAction         = "index"

All done. Just type “php cron.php” in your terminal and it will work as usual.

Important notes about cron:

  • Cron should NOT be session protected.
  • browser access of cron file should be restricted. We can achieve this by
        if (PHP_SAPI !== 'cli') {
                echo 'Access Restricted';
                exit;
         }

Hope this will help you building cron while using zend framework. 🙂