Starting from:
$30

$24

Cross Site Request Forgery Vulnerability with JSONP Solution

1. Introduction
A Cross Site Request Forgery (CSRF) vulnerability is a cross site mechanism that can force a victim's browser to send an unintended authenticated web request. In a successful attack, the victim's browser sends a malicious request (crafted by the attacker) to a web site and the web site handles it as if the victim requested it directly. This vulnerability is similar to cross site scripting because it involves exploiting the trust between web sites and web browsers. However, CSRF exploits a web site's trust of an authenticated user's browsing session, whereas cross site scripting exploits the trust a user has for a web site's content.

JSON, or JavaScript Object Notation, is a well known data format for web applications. JSONP stands for JSON with Padding, where the "padding" is a specified JavaScript callback function. Developers decided to use JSONP to get around web browsers' Same Origin Policy, which specifies that requests for data cannot be made to URLs of a different domain, protocol, or port. For example, a browser rendering https://foo.com cannot make a request to https://api.foo.com because they have different origins. The workaround to this is to wrap the desired JSON in a JavaScript function, and then have the browser render a <script tag where the src attribute is the URI. The returned JSON and JavaScript function are then rendered by the client's browser, bypassing the Same Origin Policy.

1.1 Exercise Description
Before we get into details, let's take a look at a valid use of JSONP, and get a little bit of history about why it was used. In the early 2000s, there were no protections against cross origin data requests. This meant that you could grab information from any server with XMLHttpRequests, which was a much desired feature for developing websites. This let you shift getting data from external APIs to the front end, instead of having to set up a backend service to fetch it. This was a form of shifting work onto the client, reducing the server costs for hosts.

Developers soon discovered that it is a security risk to allow fetching data from other web servers was dangerous in the front end, so all browsers implemented a Same Origin Policy (SOP). This blocked browsers from rendering content from websites that make requests to URIs that are not of the same origin (domain, port, and protocol).

In response, developers decided to circumnavigate the SOP by inserting the desired return data as an argument to a function call, and returning that to the user. This meant that developers could sneak their data in through a script tag. Here's an example of a legitimate use of JSONP.





Let's walk through the diagram.

The user first authenticates with a web page from an external web server.
The server returns the requested web page to the user. The returned web page contains a JSONP <script tag that points to an external web server requesting data. Script tags pointing to URIs, for example <script
src="https://bar.com/baz.js", cause a GET request to fetch the contents of baz.js. The requested Javascript file, baz.js is then available for the rest of the page to use. In our diagram, the author of the web page requested by the user cleverly embeds a query and callback function for data on an external web server to run when the request returns. The URI would look like <script
src="https://bar.com/?queryParam=whatever&callback=foo". The returned object is JSONP: a Javascript function where the argument to the function is the requested JSON data.
The client's web browser begins processing the HTML and makes a GET request to the provided JSONP <script tag.
The web server that is called by the JSONP script tag has an external facing API for clients to request data. The JSONP script tag mentioned in step 3, and made a request. The web server then processes the request, finds the desired data, and wraps it in the callback function.
The client's browser calls the function returned by the JSONP object and processes the JSON.
This is an diagram of a real JSONP attack. For this project, however, we are using a contrived example. We do not have an authenticated web server the user is in contact with. The objective of this exercise is to craft an page that a client would click on, which would then make a call to another server, collect data, and return it to the malicious server.





Above is a diagram representing the attack. Let's walk through this diagram step by step.

The user first visits a web page. As we are not using an authenticated server, we will be skipping this step
The web server returns credentials. As we are not using an authenticated server, we will be skipping this step
Later, the user clicks on a malicious link.
The evil HTML is returned to the user, which then processes the JSONP embedded <script. The JSONP URI needs to be the same URI that the vulnerable page would use. The data is then returned to the evil actor.
Using cached credentials in the browser, the web server begins processing the evil request. The server returning JSONP has no authentication, so there are no credentials to use.
A command is issued to fetch data from a JSONP serving web server.
The data wrapped in a callback function is returned to the client.
The evil actor now has a control of execution with user data and decides to POST the data to their own web server.
In this exercise, we provide a two small HTTP servers developed using Flask, a python HTTP microframework. The first server, vulnerable.py, returns static JSON wrapped in a provided callback function to anyone who makes a GET request to it. The second server, evil.py, provides an evil HTML file that will send data through a POST request made by a fetch() command from the user's browser to the evil web server (you will need to implement this). For simplicity of the exercise, these naive servers do not have any form of authentication or support querying data, so you should not consider these issues. Instead, we will focus on the potential for cross site request forgery. Your objective is to craft a request forgery that will act on behalf of the client to send data from the vulnerable web server to malicious web server.

The program has five source files:

Filename
URL Path
Description
vulnerable.py
localhost:5000
Returns JSONP to a calling client. You will need to change this file to complete the mitigation.
evil.py
localhost:5001
Returns to the client a malicious HTML page that will exploit a vulnerable JSONP serving server. You will need to change this file to complete the exploit.
templates/evil.html
localhost:5001
This is the malicious HTML returned to the client when evil.py's root route is visited. You will need to change this file to complete the exploit.
mitigated.py
localhost:5002
Server to be used to demonstate the mitigation of a JSONP attack. You will need to modify this file to complete the mitigation.
templates/mitigated.html
localhost:5002
Webpage rendered by mitigated.py, which accesses data from localhost:5000 without JSONP. You will need to modify this file to complete the mitigation.
1.2 Vulnerability Mitigation
The goal of JSONP is to render data from a different origin. Our goal is to maintain the same end result, but doing so securely. To do this, we will set up a proxy to fetch the desired data in the backend within the same origin, and then return that to the front end. Thus, we are shifting the load of getting data from the client onto our web server.

2. Exercise Instructions
This exercise will be completed in the web browser and on the command line terminal of the provided virtual machine. To open the terminal, right-click on the EXERCISES directory and select Open
in Terminal. Then open one more terminal window with ctrl+alt+t. Enter the following command in each window to change into the exercise directory:

$ cd 3.9.3_JSONP
Compile the Program
Python interprets your code at runtime, so there is no compilation step.

Run the Program
You will need to run one server in one terminal window, and another in the other terminal window. In the first terminal window, enter the following:

$ python3 vulnerable.py
You should then see the following:

* Serving Flask app "<name of server" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:500<0, 1, or 2 depending on which server you're running/ (Press CTRL+C to quit)
In the second terminal window, run the other server the same way:

$ python3 evil.py
You will again see similar output.

To stop either server, type ctrl+c in the command line interface. The vulnerable.py web server does not have a web interface (it doesn't render any HTML templates) as it just returns JSONP data that the browser will render. If you visit localhost:5000 in your web browser, in the top left corner of your screen, you will see the returned JSONP callback function and data. The vulnerable.py server was designed to simply return JSONP as a contrived example of what a production web server may do.

However, the evil web server, evil.py has a web interface that you can visit by going to localhost:5001 in your browser. If you go visit the malicious web page, it won't do much of anything without the vulnerable vulnerable.py server running. The malicious server needs data to steal, which vulnerable.py provides. To view the web site, open Firefox by clicking the globe icon in the bottom left hand corner of the screen. The malicious server is attached to http://localhost:5001.

Note: A simple but valuable tool is Firefox's Web Developer tools. You can access these tools by pressing Ctrl+Shift+E when in the Firefox browser. In particular, the Network tab will provide some more insight as to how the application works. Every time you load a page, you will see the HTTP requests that were sent to get there. Try this while clicking the link after logging into the site. You should see two requests, one directed at the "action" url and one directed at the "view" url.

Inspect the Program Code
Now that you understand the basic behavior of the program, it's time to look at the implementation. As mentioned above, this program is implemented in five files. Use your favorite text editor to open them. Enter the following command to open each file in vim:

$ vim vulnerable.py $ vim evil.py $ vim templates/evil.html
As you look through the code and trace the diagram, consider the following two questions

What could I do if I had access to specify a callback function and write that function's code?
What could a malicious user do if this attack used session tokens as cookies?
Exploit the Vulnerability
You will have a successful exploit if you can have a user visit the malicious page, which will trigger the data from vulnerable.py to appear in stdout of the terminal window running evil.py. To complete this exploit, you will need to modify evil.py and templates/evil.html

To test this exploit, you will need three things: (1) the vulnerable server, (2) the malicious web server, and (3) a malicious web page. First, run the server as we did in Run the Program. Next, edit templates/evil.html to include your malicious src URI (this should include the URI to the vulnerable web server, as well as a callback parameter ?callback=<function
you'd like to run). Showing you have access to specify a callback function is cool, but what nasty things can we do with it? Try using the fetch API to POST data to the malicious web server. Now, make sure you can see the evil.py server command line interface while you open localhost:5001 in one browser tab.

Congratulations! You've exploited JSONP on a vulnerable server!

Mitigate the Vulnerability
A successful mitigation of this exploit will have a web page that will be able to render the data from localhost:5000 (vulnerable.py) without using JSONP. You will need to modify vulnerable.py, templates/mitigated.html, and mitigated.py.

To mitigate this attack, we will have to restructure the architecture of our application. We need to restrict front end requests to a web server in the same origin. This means that we will have to set up an endpoint to access an external API. In mitigated.py, lets access the data returned byvulnerable.py without using JSONP. All that is needed to change in vulnerable.py is removing the @jsonp annotation. Simply returning the JSON will suffice for the test() function. In mitigated.py, use the requests library to implement an API call to localhost:5000(vulnerable.py), and then return that to the front end for Flask to render. To communicate data from the backend to the front end, you will need to use the render_template method from Flask. Here is an example of communicating data from the backend to the front end:

# this is the Flask backend from flask import Flask, render_template ... ... def run(): ... return render_template('mitigated.html', dataToTheFrontEnd=<data you'd like to return to front end)
From mitigated.html, you can access the returned data like so:

<!-- This is the front end HTML. Flask will use a templating engine (jinja2) to render the HTML and serve it to the front end. -- <p Your data is: {{ dataToTheFrontEnd }} </p
The key is that the named return variable, dataToTheFrontEnd, is referenced in between the {{
}} brackets.

Congratulations! You have mitigated the JSONP vulnerability!

3. Delivery Instructions
Deadline: March 28 at 11am.

You will deliver a short report containing:

Your commented code for the attack.
Screenshots or printouts showing the inputs used for the attack, and the outputs you got from the system.
Your commented code for the mitigation.
Screenshots or printouts showing the inputs and outputs after fixing the vulnerability.
A short explanation on your attack and your mitigations, and the conclusions.

More products