Simple Ways to Add Security to Web Development

Session Handling

As soon as legitimate users log in to a site with their credentials, a session is started and maintained until they log out. The problem begins when someone impersonating a genuine user tries to sneak in. Obviously, the results can be very severe—users' money or even their identities can be stolen. Let's explore how you can change your coding style so that the session is handled safely.

Session management implementation: you always should use the built-in session management feature that comes out of the box with your Web development framework. Not only does this save critical development time and cost, it generally is safer as well, because many people are using and testing it.

Another thing to take care of while implementing session management is keeping track of what method the application uses to send/receive the session ID. It may be a cookie or URL rewriting or a mixture of both, but you generally should limit it and accept the session ID only via the mechanism you chose in the first place.

Cookie management: whenever you plan to use cookies, be aware that you are sending out data about the user/session, which potentially can be intercepted and misused. So, you need to be extra careful while handling cookies. Always add the cookie attributes securely with HttpOnly, because this ensures that the cookie always is sent only via an HTTPS connection and doesn't allow scripts to access the cookie. These two attributes will reduce the chances of cookies being intercepted.

Other attributes like domain and path always should be set to indicate to the browser where exactly the cookie should be sent, so that it reaches only the exact destination and not anywhere else.

Last but definitely not least, the expire and max age attributes should be set in order to make the cookie nonpersistent, so it is wiped off once the browser instance is closed.

Session expiry management: a timeout should be enforced over and above the idle time out, so that if users intend to stay longer, they should authenticate themselves again. This generates a new session ID, so attackers have less time to crack the session ID.

Also, when the session is being invalidated, special care should be taken to clear the browser data and cookie, if used. To invalidate a cookie, set the session ID to empty and the expires date to a past date. Similarly, the server side also should close and invalidate the session by calling proper session handling methods, for example session_destroy()/unset() in PHP.

Web Service Security

In layman's terms, a Web service can be defined as a software system designed to support communication between two electronic devices over the Internet. In real-life scenarios, however, things are not that simple. As the Internet grows, the threat of misuse of these services grows. Let's look at some important tips you should keep in mind while developing Web services.

Schema validation: whatever SOAP payloads you expect your Web service to handle, they should be validated against the associated XML schema definition. The XSD should at least define the maximum length and character set of every parameter allowed in the Web service. Also, if you expect a fixed-format parameter, such as e-mail ID, phone numbers and so on, define the validation pattern in the XSD.

XML denial of service prevention: denial of service attacks try flooding the Web server with a large number of requests so that it eventually crashes. To protect your Web service from such attacks, be sure to optimize the configuration for maximum message throughput and limit SOAP message size. Also, validate the requests against recursive or oversized payloads, because such payloads generally can be malicious.

Safe URL Redirects

Many times you will need to redirect to a new page based on user input. But, the redirects can take a dangerous turn if not done properly. For example, if attackers get to redirect the application to a URL of their choice, they then can launch a phishing attack and compromise user data. A safe URL redirect is one where you have hard-coded the URL in the code like this:

<?php header("Location:") ?>

Cases like the following where you have to go to a URL passed by the user should be avoided:

<?php $url = $_GET['inputURL'];
header("Location: " . $url); ?>

If you can't avoid this, keep reading.

Don't use the URL as the input: even if you want to redirect to a URL based on user input, it is better not to allow the user to enter the URL. Instead, you can use other input mechanisms like a button or a direct link. This way you can prevent users from entering any random link.

Validate the input before the redirect: in cases where you simply can't avoid user input, make sure you validate the input against exactly the same site or a list of hosts or a regex. Also notify users with an indication of the site they are being redirected to.

Cross-Site Scripting

Such attacks are targeted to the end user's browser. A common way to attack is to inject a malicious script, in the form of JavaScript, Flash or even HTML to a genuine Web site. When the user accesses that site, the browser has no clue whether script is genuine and just executes it. Such scripts, once executed, can access the cookies, session data or other sensitive information stored in the browser, because they are sent via a genuine Web site that the user tried to access.

To counter such attacks/injections in your Web site, OWASP suggests treating the Web pages as templates with certain slots for the untrusted data. For example, say you are creating a home page, and on the top left, you have a slot for the user name, which is retrieved by the application and displayed to the user while the Web page renders. These slots can be for one of several components—for example, JavaScript, HTML or CSS. For each component, there are preventive measures that help make sure others can't inject their code. Let's look at all the rules.

First, you need to define the slots that should be present in the Web page. Then, make sure you don't allow any untrusted data into the document, unless it is within one of the slots you already defined.

Untrusted data in HTML tags and attributes: when you need to insert untrusted data in HTML tags like div, p, b, td and so on, make sure it is escaped before being used. This way, even if attackers somehow manage to send in their code, escaping the untrusted data will ensure that the code doesn't cause much harm. For example, characters like <, >, & and so on should be changed to &lt, &gt and &amp, respectively. Also attribute fields in HTML tags like name, id, width and so on sometimes can be required to take variable values, so you may need to pass untrusted data to such fields. In this case, make sure to escape the data before using it as well. Take a look at the ESAPI reference implementation of HTML entity escaping and un-escaping. Here is a sample usage of the API:

String safe = ESAPI.encoder().encodeForHTMLAttribute( 
 ↪request.getParameter("input" ) );

Untrusted data in CSS: in situations where you need to put untrusted data in CSS, it is important to take care that it is done only in a property value and nowhere else. Especially when you need to pass a URL, check if it starts with "http". Then, except for alphanumeric characters, escape all the other characters with an ASCII value less than 256 (the ESAPI also supports CSS escaping and un-escaping):

String safe = ESAPI.encoder().encodeForCSS( 
 ↪request.getParameter( "input" ) );

Untrusted data in an HTTP GET parameter: URLs like "" can be possible targets of attack if the GET parameter is not being escaped before execution. In such cases, make sure to escape all characters with an ASCII value less than 256 with the %HH escaping format. The ESAPI for URL validation looks like this:

String safe = ESAPI.encoder().encodeForURL( 
 ↪request.getParameter( "input" ) );

Untrusted data in JavaScript data values: if you want to place untrusted data in JavaScript, the only safe place is inside the quoted data value. Because otherwise it is very easy to change the execution context and execute the statement, which actually is meant to be data. Again, the escaping mechanism to follow is the same as in previous cases—that is, escape all the characters with an ASCII value less than 256. The ESAPI for this is:

String safe = ESAPI.encoder().encodeForJavaScript( 
 ↪request.getParameter("input" ) );


Finally, it is best to acquaint yourself with the OWASP security guidelines if you are a Web developer or plan to become one. This not only will save you a lot of work in design changes and security hardening, but it also makes sure your end users' data and identity are safe.