CSRF Protection in PHP

Cross-site request forgery [CSRF] is a type of attack where a user is tricked/forced into performing an unwanted action on a friendly website that they are authenticated with. For example, if a user is logged into their bank and then visits a malicious site, it is possible that the malicious site can use the user’s session to make requests to the bank server. Essentially, the malicious script inherits the user’s credentials and authorization to the bank’s site and can act on the user’s behalf. Since every request that the user makes to the bank’s server includes the session and cookie data, a request from the user’s browser that is initiated from another site to the bank will include this information as well. Since a CSRF attack uses the user’s browser and session, the bank server cannot identify that the request is malicious.

A simplified example of a CSRF attack is a user being logged into their bank and then visiting a page that has this image element:

To combat these attacks, the Open Web Application Security Project suggests in their Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet to use the synchronizer token pattern. This method requires a unique random challenge token to be sent with each request that only the server can identify as being a valid request and can be sent to the server with a form using a hidden form field or included as a variable in a request. It is also critical that the token be used only in POST requests, so that it is not exposed, such as in the referrer section of an http request to a malicious site or when a user copies and pastes a url to share with a friend.

A common technique is to use a unique algorithm using the session id combined with the form/request that is being validated, meaning all tokens are form/request specific and expire when a user logs out. Using the session id alone would not be enough, since it can be discovered and used. One algorithm to generate a token could be concatenating the name of the form/request with the session id and running that through a hashing function like md5 or sha1 like this:

This can be taken one step further and add a secret key to make the token that much more difficult to duplicate:

The next step is to add this token into the form using a hidden form field:

Now to validate the incoming form is valid, just check the token:

 

While your site may or may not be a high CSRF target, CSRF prevention is very easy to implement and should be used in any application that handles a form or request. CSRF prevention must go beyond using just a static secret key or limiting form submission to POST requests, both of these solutions are still vulnerable to CSRF attacks. A unique identifier that cannot be predicted is critical to successful CSRF security. It is also important to safeguard all POSTed requests, not just form submissions.

Composer

Composer is a tool for dependency management in PHP. It allows you to declare the libraries your project depends on and it will manage (install/update) them for you.

Dependency management

Composer is not a package manager in the same sense as Yum or Apt are. Yes, it deals with “packages” or libraries, but it manages them on a per-project basis, installing them in a directory (e.g. vendor) inside your project. By default it does not install anything globally. Thus, it is a dependency manager. It does however support a “global” project for convenience via the global command.

This idea is not new and Composer is strongly inspired by node’s npm and ruby’s bundler.

Suppose:

  1. You have a project that depends on a number of libraries.
  2. Some of those libraries depend on other libraries.

Composer:

  1. Enables you to declare the libraries you depend on.
  2. Finds out which versions of which packages can and need to be installed, and installs them (meaning it downloads them into your project).

How do you increase the max number of concurrent connections in Apache?

By default, apache2 is configured to support 150 concurrent connections. This forces all parallel requests beyond that limit to wait. Especially if, for example, active sync clients maintain a permanent connection for push events to arrive.

This is an example configuration to provide 8000 concurrent connections. Please ensure that your apache is using the mpm_worker. This allows us to serve lots of concurrent connections by using less RAM than with mpm_prefork as we are going to start much less processes. (mpm_event, which is stated to be stable by Apache nowadays, shows problems in load tests, with connection timeouts.)

<IfModule mpm_worker_module>
    ServerLimit              250
    StartServers              10
    MinSpareThreads           75
    MaxSpareThreads          250 
    ThreadLimit               64
    ThreadsPerChild           32
    MaxRequestWorkers       8000
    MaxConnectionsPerChild 10000
</IfModule>

Note: MaxRequestWorkers was previously named MaxClients and MaxConnectionsPerChild was previously named MaxRequestsPerChild. If you are using old (pre 2.4) version of Apache you might need to use the old names.

The short explanation of the parameters:

ServerLimit Declares the maximum number of running apache processes. If you change this value you have to restart the daemon.
StartServers The number of processes to start initially when starting the apache daemon.
MinSpareThreads/MaxSpareThreads This regulates how many threads may stay idle without being killed. Apache regulates this on its own very well with default values.
ThreadsPerChild How many threads can be created per process. Can be changed during a reload.
ThreadLimit ThreadsPerChild can be configured as high as this value during runtime. If you change this value you have to restart the daemon.
MaxRequestWorkers This declares how many concurrent connections we provide. Divided by ThreadsPerChild you get the suitable ServerLimit value. Maybe less than ServerLimit * ThreadsPerChild to reserve some resources that can be engaged during runtime with increasing MaxRequestWorkers and reloading the configuration.
MaxConnectionsPerChild Defines the number of Connections that a process can handle during its lifetime (keep-alives are counted once). After that, it will be killed. This can be used to prevent possible apache memory leaks. If set to 0 the lifetime is infinite.

 

 

Best Practice 4 – Code should be written to be reviewed

While writing your software code, keep in mind that someone is going to review your code and you will have to face criticism about one or more of the following points but not limited to:

  • Bad coding
  • Not the following standard
  • Not keeping performance in mind
  • History, Indentation, Comments are not appropriate.
  • Readability is poor
  • Open files are not closed
  • Allocated memory has not been released
  • Too many global variables.
  • Too much hard coding.
  • Poor error handling.
  • No modularity.
  • Repeated code.

Keep all the above-mentioned points in your mind while coding and stop them before they jump in your source code. Once you are done with your coding, go for a self-review atleast once. I’m sure, a self-review would help you in removing 90% problems yourself.

Once you are completely done with your coding and self review, request your peer for a code review. I would strongly recommend to accept review comments happily and should be thankful to your code reviewers about the comments. Same time, it is never good to criticize any source code written by someone else. If you never did it, try it once and check the coder’s expression.

It is special chacter(s) which have special meaning in Regular Expression.

For Example:
*, ., /, \, ? and ^.

Sr Meta character Desctiption
1 [ ] Match any character within [phc]
Means find “p” OR “h” OR “c”
2 Range
a-z means a to z(a,b,c, … z)

0-0 means 0 to 9 (0,1,2,3,4,5,6,7,8,9)

A-Z means A to Z(A,B,C,D ….. Z)

3 ^ Caret It means start with a character

For example: ^ab (start with “a”)

Inside the bracket if have opposite meaning.

For example: [^a](must not start with “a”)

4 $ End with character

For Example

Abc$ means end with “c”

5 . The . (period) means any character(s) in this position,
For example, ph. will find php, php-tutorial and php-tutorial-php but not aphp because it has no following character
6 ? Matches the preceding character 0 or 1 times only.

For example:

colou?r will find both color (0 times) and colour (1 time).

7 * Matches the preceding character 0 or more times.
For example:

tre* will find tree (2 times) and tread (1 time) and trough (0 times).

8 + Matches the previous character 1 or more times.
For example:

tre+ will find tree (2 times) and tread (1 time) but NOT trough (0 times).

9 {n} Preceding character, or character range, n times exactly.
For example:

find a local phone number we could use [0-9]{3}-[0-9]{4} which would find any number of the form 723-4567 OR 132-3234 OR 214-3433.

10 () To group a character.

For Example:
(php), will find the “php” only.

11 | Vertical bar used for OR

(a|c) find either “a” OR “c”

12 \d any character in the range 0 – 9
13 \D Any character not in between 0-9
14 \s Whitespace or tab
15 \S Not whitespace or tab
16 \w Alphanumeric characters (a-z, 0-9, A-Z)
17 \W Not alphanumeric character (a-z, 0-9, A-Z)

15 Tips to Optimize Your PHP Script for Better Performance for Developers

If you are a developer, it is essential for you to optimize your script early in the development process itself. Following the best practices while coding your PHP script is a good starting point to write a well optimized PHP code.

This tutorial provides few tips to optimize PHP code from a developer point of view.

1. Use Native PHP Functions

As much as possible, try to use native PHP functions rather than writing your own functions to achieve the objective. For example, you can use range( b, k) to get an array of alphabets starting from b to k in sequence, if it is only needed once in the script rather than declaring an array with these values in a function and returning it on its call.

2. Use Single Quotes

Using single quotes ( ‘ ‘ ) is faster than using double quotes( ” ” ) if you are going to keep only the string inside it avoiding any variables. Double quotes checks for the presence of variable and adds little bit of overhead.

3. Use = = =

Use “= = =” instead of “= =”, as the former strictly checks for a closed range which makes it faster.

4. Use Appropriate Str Functions

str_replace is faster than preg_replace, but strtr is faster than str_replace by a factor of 4.

5. Calculate Only Once

Calculate and assign the value to the variable if that value is getting used numerous time rather than calculating it again and again where it is being used.

For example, the following will degrade the performance.

for( $i=0; i< count($arrA); $i++){
  echo count($arrA);
}

The script below will perform much better.

$len = count($arrA);
for( $i=0; i< $len; $i++){
  echo $len;
}

6. Pass Reference to Function

Pass reference to the function if it does not affect your logic. A function manipulating the reference is faster than those manipulating the value been passed as here one more copy of the value is getting created. Especially it adds overhead when the value passed by you is a big array.

For example, let us create a function in two different way to increment by 1, each element of an array having values 0 to 99.

<?php
  // passing by reference
  function  computeValue( &$param ){
  	// Something goes here
  	foreach( $param as $k => $value){
  	  $param[$k] = $value + 1;
  	}
  }
  $x = array();
  for( $i =0; $i<99; $i++){
    $x[$i] = $i;
  }
  computeValue( $x);
  
  // array with 100 elements each incremented by 1
  print_r( $x );

?>                   		 

The function above works faster than the function below although both will produce the same result ( increment each element of the array by 1. )

  <?php
  	// passing by value
    function  computeValue( $param ){
      // Something goes here
      foreach( $param as $k => $value){
      	$param[$k] = $value + 1;
      }
      
      return $param;
    }
    $x = array();
    for( $i =0; $i<99; $i++){
      $x[$i] = $i;
    }
	// array with 100 elements each incremented by 1
    print_r(computeValue( $x));
    
  ?>

7. Create Classes Only When its Required

Don’t create classes and method until and unless its really needed, used and reused as well.

8. Disable Debugging Messages

File operations are expensive. So, if you have written lot of custom functions to log errors and warning during your development process, make sure you remove them before you push the code to production.

9. Use Caching Techniques

Use cache to reduce the load of database operations as well as the script compilation. We can use memcache for the reducing database load and APC for opcode caching and intermediate code optimization.

10. Close the Connection

Get into the habit to unset the variables and close database connection in your PHP code. It saves memory.

11. Reduce Number of Hits to DB

Try to reduce the number of hits to the database. Make queries aggregate so that you call the database less number of times. For example:

<?php
  $con=mysqli_connect("localhost","username","somepassword","anydb");
  
  if (mysqli_connect_errno())
  {
    echo "Failed to connect to MySQL" ;
	mysqli_connect_error(); 
  }

  function insertValue( $val ){
    mysqli_query($con,"INSERT INTO tableX (someInteger) VALUES ( $val )");
  }
  
  for( $i =0; $i<99; $i++){
    //  Calling function to execute query one by one 
    insertValue( $i );
  }					
  // Closing the connection as best practice		
  mysqli_close($con);

?> 

The script above is much slower than the script below:

<?php
  $con=mysqli_connect("localhost","username","somepassword","anydb");
  if (mysqli_connect_errno())
  {
  	echo "Failed to connect to MySQL" ;
  	mysqli_connect_error(); 
  }
   
  function insertValues( $val ){
     // Creating query for inserting complete array in single execution.
    $query= " INSERT INTO tableX(someInteger) VALUES .implode(',', $val)";      
    mysqli_query($con, $query);
  }
  
  $data = array();
  for( $i =0; $i<99; $i++){
    // Creating an array of data to be inserted.
    $data[ ]  =   '(" ' . $i. '")' ;
  }
  // Inserting the data in a single call
  insertValues( $data );
  // Closing the connection as a best practice
  mysqli_close($con);

?> 

12. Frequently Used Switch Cases

Keep most frequently used switch cases on the top.

13. Use Methods in Derived Classes

Methods in derived classes are faster than base classes. For example, let there be a function in both base class and derived class for performing task1. It is named as “forTask1” in base class and “forTask1again” in derived class, so that they will not override.

Call to the function “forTask1again( )” which is in derived class will work faster than call to the function “forTask1( )” as it is from base class.

<?php
  class someBaseClass
  {
  	public function forTask1($string)
  	{
  		// perform task 1
  	}
  	public function forTask2( )
  	{
  		// perform task 2
  	}
  }
  
  class derivedClass extends someBaseClass
  {
  	public function forTask1again($string)
  	{
  		//perform task 1 same as the function in base class.
  	}
  	public function forTask3($string)
  	{
  		//perform task 3
  	}
  }
  //Instantiating the derived class below.
  $objDerivedClass = new derivedClass( ); 
  
  // The call below works slow for task1 as it is from base class.
  $resultTask1 = $objDerivedClass->forTask1( );
  
  // The call below works faster for task1 as 
  // it is from derived class.
  $sameResultTask1 = $objDerivedClass->forTask1again();
?>

14. Use JSON

Use JSON instead of XML while working with web services as there are native php function like json_encode( ) and json_decode( ) which are very fast. If you are bound to have XML form of data, then use regular expression to parse it instead of DOM manipulation.

15. Use isset

Use isset( ) where ever possible instead of using count( ), strlen( ), sizeof( ) to check whether the value returned is greater than 0.

For example, let us assume that you have a function which returns an array with values or a NULL array. Now you want to check whether the returned array is with values or not, then use the following:

if(isset($returnValue)){
  // do something here
}

In this case, use the above code block, instead of the following:

if(count($returnValue) > 0){
  // do something here
}