8 Practices to Secure Your Web App

Share this article

When it comes to application security, in addition to securing your hardware and platform, you also need to write your code securely. This article will explain how to keep your application secure and less vulnerable to hacking. The following are the best habits that a programmer can develop in order to protect his or her application from attack:

  • Input data validation
  • Guarding against XSS attacks
  • Guarding against CSRF attacks
  • Preventing SQL Injection attacks
  • Protecting the file system
  • Protecting session data
  • Proper error handling
  • Guarding included files

Input Data Validation

While designing your application, you should be striving to guard your app against bad input. The rule of thumb to follow is this: don’t trust user input. Although your app is intended for good people, there is always a chance that some bad user will try to attack your app by entering bad input. If you always validate and filter the incoming data, you can build a secure application. Always validate data in your PHP code. If you are using JavaScript to validate user input, there is always a chance that the user might have turned off JavaScript in her browser. In this case your app will not be able to validate the input. Validating in JavaScript is okay, but to guard against these types of problems then you should re-validate the data in PHP as well too.

Guarding Against XSS Attacks

Cross-site scripting attack (XSS attack) is an attack based on code injection into vulnerable web pages. The danger is a result of accepting unchecked input data and showing it in the browser. Suppose you have a comment form in your application that allows users to enter data, and on successful submission it shows all the comments. The user could possibly enter a comment that contains malicious JavaScript code in it. When the form is submitted, the data is sent to the server and stored into the database. Afterward, the comment is fetched from database and shown in the HTML page and the JavaScript code will run. The malicious JavaScript might redirect the user to a bad web page or a phishing website. To protect your application from these kinds of attacks, run the input data through strip_tags() to remove any tags present in it. When showing data in the browser, apply htmlentities()function on the data.

Guarding Against CSRF Attacks

In a Cross Site Request Forgery (CSRF) attack, the attacker tricks the victim into loading sensitive information or making a transaction without their knowledge. This mainly occurs in web applications that are badly coded to trigger business logic using GET requests. Ideally, GET requests are Idempotent in nature. Idempotency means the same page can be accessed multiple times without causing any side effects. Therefore, GET requests should be used only for accessing information and not for performing transactions. The following example shows a how a poorly coded application unknowingly supports CSRF attacks:
<?php
if (isset($_REQUEST["name"], $_REQUEST["amount"])) {
    // process the request and transfer the amount from
    // from the logged in user to the passed name.
}
Let’s assume Bob wants to perform a CSRF attack on Alice, and constructs a URL like the following and sends it to Alice in an email:
<a href="http://example.com/process.php?name=Bob&amount=1000">Visit My WebSite</a>
If Alice clicks on this link, and is logged into the website already, this request will deduct $1000 from her account and transfer it to Bob’s! Alternatively, Bob can create an image link whose src attribute points to the URL.
<img src="http://example.com/process.php?name=Bob&amount=1000" width="1" height="1"/>
The browser can’t display any image as expected, but it will still make the request using the URL which will make a transaction without notifying Alice. The solution is to process any function that changes the database state in POST request, and avoid using $_REQUEST. Use $_GET to retrieve GET parameters, and use $_POST to retrieve POST parameters. In addition, there should be a random token called a CSRF token associated with each POST request. When the user logins into his/her account, the application should generate a random token and store it in the session. Whenever any form is displayed to the user, the token should be present in the page as a hidden input field. Application logic must check for the token and ensure that it matches the token present in the session.

Preventing SQL Injection Attacks

To perform your database queries, you should be using PDO. With parameterized queries and prepared statements, you can prevent SQL injection. Take a look at the following example:
<?php
$sql = "SELECT * FROM users WHERE name=:name and age=:age";
$stmt = $db->prepare($sql);
$stmt->execute(array(":name" => $name, ":age" => $age));
In the above code we provide the named parameters :name and :age to prepare(), which informs the database engine to pre-compile the query and attach the values to the named parameters later. When the call to execute() is made, the query is executed with the actual values of the named parameters. If you code this way, the attacker can’t inject malicious SQL as the query is already compiled and your database will be secure.

Protecting the File System

As a developer you should always write your code in such a way that none of your operations put your file system at risk. Consider the following PHP that downloads a file according to a user supplied parameter:
<?php
if (isset($_GET['filename']) {
    $filename = $_GET['filename'];
    header('Content-Type: application/x-octet-stream');
    header('Content-Transfer-Encoding: binary');
    header('Content-Disposition: attachment; filename="' . $filename . '";');
    echo file_get_contents($filename);
}
The script is very dangerous since it can serve files from any directory that is accessible to it, such as the session directory and system directories. The solution is to ensure the script does not try to access files from arbitrary directories.

Protecting Session Data

By default, session information is written to a temp directory. In the case of a shared hosting server, someone other than you can write a script and read session data easily. Therefore, you should not keep sensitive information like passwords or credit card numbers in a session. A good way to guard your session data is to encrypt the information stored in the session. This does not solve the problem completely since the encrypted data is not completely safe, but at least the information is not readable. You should also consider keeping your session data stored somewhere else, such as a database. PHP provides a method called session_set_save_handler() which can be used to persist data in session in your own way. As of PHP 5.4 you can pass an object of type SessionHandlerInterface to session_set_save_handler(). Check out the PHP documentation to learn about implementing custom session persistence by implementing SessionHandlerInterface.

Proper Error Handling

It’s good to know about all the errors that occur while we’re developing an application, but when we make the application accessible to end users we should take care to hide the errors. If errors are shown to users, it may make our application vulnerable. So, the best approach is configuring your server differently for development and production environments. In production mode we need to turn off display_errors and display_start_up_errors
settings. error_reporting and log_errors should be on so that we can log errors while hiding those from end users. You can use set_error_handler to define custom error handlers. However, it has limitations. The custom error handler bypasses the standard error handling mechanism of PHP. It cannot catch errors like E_CORE_ERROR, E_STRICT or E_COMPILER_ERROR in the same file the error handler is defined in. Furthermore, it will fail to handle errors that might occur within the handler itself. To handle errors elegantly you should perform exception handling through try/catch blocks. Exceptions are represented by the Exception class and its subclasses. If any error occurs inside the try block you can throw an exception and process it in the catch block.

Guarding Included Files

PHP scripts often include other PHP files that contain code for things like connecting to a database, etc. Some developers give the included files an extension like .inc. Files with this extension are not parsed by PHP by default if called directly and will be served as plain text to the users. If an attacker directly accesses the include file that contains database credentials, he now has access to all of your application’s data. Always use the .php extension for included code files and keep them outside of directories directly accessible to users.

Summary

By keeping the above 8 points in mind it’s possible to secure a PHP application to a great extent. The best piece of advice by far is don’t trust user input, but also be sure to guard your file system and database as well. Image via Fotolia

Frequently Asked Questions (FAQs) on Securing Your Web App

What are some common security vulnerabilities in web applications?

Web applications are often susceptible to a variety of security vulnerabilities. These include Cross-Site Scripting (XSS), where an attacker injects malicious scripts into web pages viewed by other users, and SQL Injection, where an attacker can manipulate SQL queries to gain unauthorized access to data. Other common vulnerabilities include Cross-Site Request Forgery (CSRF), where an attacker tricks a victim into performing actions on their behalf, and Insecure Direct Object References, where an attacker can bypass authorization and access resources directly.

How can I prevent SQL Injection attacks?

SQL Injection attacks can be prevented by using parameterized queries or prepared statements, which separate SQL code from data. This prevents an attacker from manipulating the SQL query. Additionally, always validate and sanitize user input to ensure it does not contain malicious code.

What is Cross-Site Scripting (XSS) and how can it be prevented?

Cross-Site Scripting (XSS) is a type of attack where an attacker injects malicious scripts into web pages viewed by other users. This can be prevented by properly validating and escaping user input, implementing a Content Security Policy (CSP), and using HTTP-only cookies to prevent scripts from accessing sensitive data.

How can I secure user authentication in my web application?

User authentication can be secured by implementing strong password policies, using multi-factor authentication, and securely storing passwords using techniques like hashing and salting. Additionally, always use secure communication protocols like HTTPS to protect sensitive data during transmission.

What is Cross-Site Request Forgery (CSRF) and how can it be prevented?

Cross-Site Request Forgery (CSRF) is an attack where an attacker tricks a victim into performing actions on their behalf. This can be prevented by using anti-CSRF tokens, which are unique to each session and request, and implementing the SameSite cookie attribute to prevent cookies from being sent in cross-site requests.

How can I protect sensitive data in my web application?

Sensitive data can be protected by encrypting it both at rest and in transit, limiting access to it based on user roles and permissions, and regularly auditing your application for any potential security vulnerabilities. Additionally, always ensure that your application is up-to-date with the latest security patches and updates.

What is Insecure Direct Object References and how can it be prevented?

Insecure Direct Object References occur when an application provides direct access to objects based on user-supplied input. This can be prevented by using access control checks or indirect references to prevent unauthorized access to resources.

How can I ensure secure communication in my web application?

Secure communication can be ensured by using secure protocols like HTTPS, which encrypts data during transmission, and implementing HTTP Strict Transport Security (HSTS), which forces browsers to only use secure connections. Additionally, always validate and sanitize user input to prevent injection attacks.

What are some best practices for web application security?

Some best practices for web application security include regularly updating and patching your application, using secure coding practices, implementing strong access control measures, encrypting sensitive data, and regularly auditing your application for security vulnerabilities.

How can I monitor my web application for security threats?

Monitoring for security threats can be done by implementing intrusion detection systems, regularly auditing your application for security vulnerabilities, and monitoring application logs for any suspicious activity. Additionally, consider using a security incident and event management (SIEM) system to centralize and analyze security data.

Sandeep PandaSandeep Panda
View Author

Sandeep is the Co-Founder of Hashnode. He loves startups and web technologies.

Intermediate
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week