Web Security

Security of web- sites, applications and services


02 Jul 2016 View Comments
#websecurity #web #security #computer #sql #injection #crosssite #scripting #csrf #http

web_security

For being in a company where security is the most important piece of work: maintained and truly valued in my company. I naturally gained knowledge in most of security surrounding web development, not only to follow Owasp Top10, but also things that are not list in top 10 list. In my opinion, anyone working in a secure web application environment should know at least the Owasp Top10 list. Anyway I will include some of the items that just come to my mind in the world of web security. Note below content is not everything, they are just reference of some of security that we need to enforce in areas of web technology which i find important:

SQL Injection

I am not sure if there would be any web developers out there who let their code vulnerable to this. I believe no one would do this intentionally, however, people sometimes forget to make the right protection. Injection happens when attacker sends an "code" (ex. SQL query) that would change the course of execution in the program.

For example, say we have a piece of code:

my $query = "SELECT * FROM accounts WHERE custID='" . $cgi->param("id") . "'";

which takes in direct input of parameter from cgi object. And let’s have $cgi->param("id") = ' or '1'='1.

Then above query becomes:

my $query = "SELECT * FROM accounts WHERE custID='' or '1'='1'";

For sake of argument, there is no data type check in custID in Database. This above will query for everything in accounts table. Or let’s make a slight variation. Let’s say this time we replace $cgi->param("id") with something like 123'; DELETE FROM accounts; SELECT '1'='1.

Then this is how query becomes at the end:

my $query = "SELECT * FROM accounts WHERE custID='123'; DELETE FROM accounts; SELECT '1'='1';";

Seriously, are we going to let the attacker delete entire records from accounts table? It is a very serious security hole if this were to happen. Anyway, we can fix this simply by separating the commands and queries. Carefully escape characters that is being feed to the query.

So above statement can be cleaned to something like this:

my $query = "SELECT * FROM accounts WHERE custID=" . $dbh->quote($cgi->param("id"));

When above param is replaced with 123'; DELETE FROM accounts; SELECT '1'='1 this piece of input will be escaped and produce smething like below query:

my $query = "SELECT * FROM accounts WHERE custID='123''; DELETE FROM accounts; SELECT ''1''=''1'";

which is just a plain invalid SQL query at this point. So severity of this vulnerability is pretty high and dangerous that you can delete an entire table if this was allowed! This has been well-known to developers these days so it is common to have this all protected, however, I remember it was literally broken in almost all personal web sites around 2005ish. Imagine one morning you got up to check subscribers and all of them had been deleted from database! These days modern programming already places some protection around this so developers can get away with it. Anyway, this is definitely an important concept every developer must know.

XSS (Cross-site scripting)

This attack is similar to SQL injection described above, except this injection is happening with a client’s browser which results in executing unexpected behavior such as publishing some of the user’s sensitive information, such as cookies, from the client’s browser. This can be easily achieved by passing in some sort of javascript code as part of text field submit which will eventually be executed at the client side as the content entered in being rendered and displayed on the client’s browser.

Hackers will find most creative and easy method to hack into your information or other needs. So how do we prevent all these? The responsibility to create a secure web application is really who is implementing/serving the website. The one thing if they are really afraid of this attack can disable the entire scripts from the browser, but who wants to do that? The job of the server is quite easy. Make sure all characters entered by the user are escaped properly. Note this does not prevent 100% either, but just a baseline of the hacking method is explained here.

As a side-note, attacks come not only in the browser but from the desktop as well. Keylogging is another problem, where the attacker can execute a piece of scripts command easily from either comment section or attacker can even send you a piece of a link via email and record to get your sensitive information such as passwords and credit card numbers. These are some examples.

Encrypted Password

This is really a common sense but I thought I would place this here as it is important to note for web security. First, you have to understand the scope of encryption. So if your website requires authentication (or dealing with any sensitive data) then it is probably a good idea to wrap your website with SSL protection to protect the data being transmitted between client and server. With SSL it gives that minimum protection of when data is being hijacked in the middle unless the hacker has the private key, the hacker will have very hard time to decrypt the context.

Well, the physical system can also be compromised (of data storage such as DB, disk, etc). We do not want the hackers visibly see plain text of credit card #. Also, this number is something that even server owners should not see. So we can make an encryption on the card # by giving each different # a key associated where we can decrypt to either make a transaction or something when it is absolutely needed. This is another reason separating out the data storage vs application can be helpful since stolen data storage can still be protected with encrypted data.

For passwords, which typically is encrypted as well. There are many websites that do just a basic md5/sha1 hash applied to it. This is called “hashing”, not encrypting any password. But this doesn’t matter as it’s good enough to just hash for the password since we would like to visually mask the passwords. However, remember to add the SALT into the hash to the password. If you do not add SALT to this string, hackers can use dictionary attach to get the characters that match the hash value, but this is not gonna be possible with SALT added to the string.

HttpOnly and Secure

A secure cookie can only be transmitted over an encrypted connection (i.e. HTTPS over SSL). It won’t be transmitted over non-encrypted connections. This means if cookie got stolen, they won’t be able to easily decrypt the content. Another security measure we can impose on HTTP header is a “HttpOnly” cookie. These HTTP defined headered cookies cannot be accessed by client-side APIs, such as JavaScript. This limits ability for hackers to various XSS activity against you. However, they are still vulnerable to XST (Cross Site Tracing) or CSRF (Cross-Site Request Forgery).

HTTP Strict Transport Security

This is an HTTP Response Header that will prevent such as cookie hijacking. This response header is notifying the browsers or handlers to prevent any communications from being sent over HTTP to the specified domain and will instead send all communications over HTTPS. It also prevents HTTPS click through prompts on browsers. Here is how you would use it typically:

Strict-Transport-Security: max-age=31536000

which is a basic setting where it would set the security for the time of 1 year. It’s not quite safe as it is missing includeSubDomains.

Here is more strict version than above, which makes sure HSTS Policy applies to this HSTS Host as well as any subdomains of the host’s domain name:

Strict-Transport-Security: max-age=31536000; includeSubDomains

This directive started its support on major browsers from 2013-ish

Insecure Direct Object Reference

This is one of those items where you can be careless with the handling of such object, others might get an easy access to it. So say in an environment, you can get an information using simple GET request like this:

https://example.com/app/getAccount?accountID=<notyouraccountid>

As you can see, without a proper check of the session or other security measures, you are exposing access to another person’s account. The protection around this quite simple: surround web page with proper sessions OR make sure you have some sort of keys when you are accessing the objects.

X-Frame-Options, Strict-Transport-Security and Public-Key-Pins

These are the HTTP headers to be added as part of HTTP Response to protect the client from attackers. There are few more that does extra protections. I picked these 3 since I consider them the most important out of them. If you would like to explore the full list, here is the link. X-Frame-Options is a header to specify the browser to not render page within a frame. There are options to choose from where you can deny displaying this content in a frame, you can allow content in a frame for the same origin. Last option is all but listed allowed from the domain is denied. This header is explicitly for protecting the clients against clickjacking. Clickjacking is basically using the frame manipulating the clients to react on some actions such as voting/posts/comments/follow etc. OK, let’s talk about HTTP Strict-Transport-Security. This is the header of HTTP response saying only process this response in secure HTTPS connections. It is communicated via HTTP response header via an HTTP header field named “Strict-Transport-Security”. Lastly, for the HTTP response header protection, I’d like to talk about HTTP Public-Key-Pins. This is basically pinning the SSL certificate so attackers cannot replace the certificate with fraudulent certificates. HPKP contains a value which is basically a SHA-256 hash of the actual certificate which then the browser will verify whether the certificate is valid.

Input Validation and Error Handling

This item is not directly related to Web Security, but it is important to mention as part of it since it could prevent a lot of attack measures from applying these. Input validation is nothing but to validate inputs as they come in. Data validation would check the data are valid, reasonable, and secure before they are even being processed. For example, it could be as simple as checking for inputs of allowed characters, checking for limits, allowed range of values, etc. This ultimately will protect attackers from entering malformed data into input box so overall it does the prevention. When you have a text field that you can enter only digits, it is not possible to enter in any piece of javascript codes or SQL injection. Anyway, it is very important to do the input validation as it protects and filters out any invalid inputs.

Insecurity around sensitive data

I’ve mentioned on this topic briefly above which I’d like to elaborate further more here. Securing data like SIN #, credit card #, password etc need an extra layer of security. We never want to store them as plain text. We need to apply strong security encryption surrounding it. Think about when the hacker stealing the whole entire database, now he has all of those sensitive data. With the right encryption applied on those stolen data, the hackers won’t be able to decrypt them into a plain text. So data is not entirely stolen at that point. Data could also be protected from being hijacked between HTTP transfer. Even if the hackers got this information, they won’t easily be able to turn them back to plain text. So that extra layer of security is always required for those sensitive data. What are some ways to encrypt these data safely? I would use card holder’s plaintext password to encrypt and store inside the database then to access the info, it would require the user to type in the password again.

CSRF (Cross Site Reference Forgery)

I have put this here because our company recently patched a protection around this. An example of CSRF can be when an attacker sends a link that makes an action of something like changing the password of a “user” or modifying someone’s status. When the victim already has the session opened to the website with enough privileges to make this kind of changes, by clicking the link from the attacker, the attacker would automatically update the password of the “user” attacker intends to change the password. To fix this, we ended up implementing a md5 hash string tied to a session so if an attacker sends a link and it wouldn’t have the same session as the victim logged in with. Since they are the different hash, it would give a warning page to indicate me to make sure I know what I am doing. This confirmation box is an additional step so the attacker isn’t getting the job done just by sending the link.

XXE - Billion Laughs

This interesting topic was thoroughly discussed with my teammates when we literally had someone try to attack us with LOL Billion Laughs attack. The symptoms are generally high load on the server as XML parsers are recursively parsing embedded entities. Here is a sample XML that triggers an infinite entity mappings which cause denial-of-service attack that targets XML parsers. It is also known as XML bomb.

<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

Basically, as you see from this example, there are 10 different entities, lol to lol9. The first lol = String "lol", then each of other entities becomes chains of other entities. So when you expand all of this, there are 100,000,000 instances of the string of "lol" which brings us to the name, billion laughs.

Below is an example of XXE:

<?xml version="1.0" encoding="ISO-8859-1"?>
 <!DOCTYPE foo [  
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///dev/random" >]><foo>&xxe;</foo>

Similarly, this test could crash the web server (on a UNIX system), if the XML parser attempts to substitute the entity with the contents of the /dev/random file.

Transport Layer Security

Well, obviously everyone probably knows what https (SSL) is. It is basically providing a secure layer for privacy and data integrity between two communicating applications. SSLs (v1, v2 and v3) have been found vulnerable (Read Here if interested) and it is recommended to use anything greater than TLS1.1. Modern browsers support at least TLS 1.0 as TLS1.0 is still widely used as the ‘best’ protocol by a lot of browsers that are not patched to the latest version. It suffers from CBC Chaining attacks and Padding Oracle attacks. PCI DSS 3.1 prohibits the use of TLS 1.0 after June 30, 2016. TLS 1.2 is the latest available transport layer security and all of SSLv1, SSLv2, SSLv3 are deprecated as of the year 2015.

Share this post

Me

I am a passionate software developer working in Downtown, Vancouver. I strongly believe in art of algorithms and together with it to write clean and efficient software to build awesome products. If you would like to connect with me, choose one from below options :) You can also send me an email at