{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "rtGuJ4-Spcmy"
},
"source": [
"# SENG 4220\n",
"## Software Security\n",
"### Web Security and Code Injection Attacks and Defenses\n",
"\n",
"**Due - Mar 24, 2023 (11:59 pm)**"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "k5atZKDhpcm1"
},
"source": [
"## Objectives\n",
"This assignment aims to provide students with practical knowledge in the field of software security by exploring web security threats and SQL code injection attacks. By the end of the assignment, students will have a solid understanding of web security fundamentals and the vulnerabilities that exist in web applications, as well as the vulnerabilities present in SQL databases. Furthermore, they will gain hands-on experience in identifying and mitigating these vulnerabilities to improve the security of software systems.\n",
"
\n",
"Please complete the sections labeled \"# Your answer\"."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0USAK7kkpcm1"
},
"source": [
"## Section 1: A Simple Cross-Site Scripting (XSS) Attack"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "M8kgxJbqpcm1"
},
"source": [
"In this section, we will learn how a cross-site scripting attack (XSS) works. In particular, we will see a variety of attack scripts and learn how to defend against them. XSS attack is a powerful attack that can subvert the same-origin policy. To do so, the attacker injects malicious JavaScript onto a webpage. When the victim loads the webpage, the user’s browser will run the malicious JavaScript automatically.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5nbs-fPtpcm1"
},
"source": [
"### Setup\n",
"To begin with, open this file using Jupyter notebook. The assignment is divided into two parts - attacking a website and attacking a database. The main objective of this assignment is to learn about software security, and as a part of this assignment, we will be using Jupyter notebook as the running environment, Flask as the web server, and SQLite for database management. The source code to build these systems is provided, and you do not need any prior web programming knowledge to complete this assignment. However, if you have any questions, the instructor is available to help you. To run this assignment, you need to install the Flask package, which is a Python framework for building web servers. You can install this package by running the following command."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "85JnlKpbpcm2"
},
"outputs": [],
"source": [
"!pip3 install flask"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SS8rqU5Lpcm2"
},
"source": [
"Run the following code to import the package."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Be0d1pzIpcm2"
},
"outputs": [],
"source": [
"import logging\n",
"from flask import Flask, request\n",
"from multiprocessing import Process\n",
"\n",
"log = logging.getLogger('Werkzeug')\n",
"log.setLevel(logging.ERROR)\n",
"\n",
"p = None"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "m4IvZ31zpcm3"
},
"source": [
"Below we provide a template website that simulates a simple social networking site."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0iIxjrhBpcm3"
},
"outputs": [],
"source": [
"web_template = \"\"\"\n",
"\n",
"\n",
"
Mikhayla \" + comment + \"
\\n\" + \"\"\"\n", " \n", "input
variable, which will be used to construct the query
string later.\n",
"### Question 1.\n",
"Please fill in the input
variable so that the SQL command will select all the records in the transcripts table where the course is SENG4220. You can execute the following code block to see if your answer is correct."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "RgyGHGmYpcm_"
},
"outputs": [],
"source": [
"input = '' # Your answer (3 - 2 marks)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "nPTm1_Yvpcm_"
},
"outputs": [],
"source": [
"# Test your answer\n",
"query = \"SELECT * FROM transcripts WHERE course = '\" + input + \"'\";\n",
"res = exe_sql_script(query);\n",
"print(res)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "M_XNe2MUpcm_"
},
"source": [
"### Question 2.\n",
"Now we can see how SQL injection works. It seems users can only specify the course name; however, some input strings may result in undesirable SQL commands.\n",
"\n",
"Please fill in the input
variable so that the SQL command will select the password of admin from the users table. You can execute the following codes to see if your answer is correct."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "zTCMuLvdpcm_"
},
"outputs": [],
"source": [
"input = '' # Your answer (4 - 10 marks)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "pTV3Pzdbpcm_"
},
"outputs": [],
"source": [
"# Test your answer\n",
"query = \"SELECT * FROM transcripts WHERE course = '\" + input + \"'\";\n",
"res = exe_sql_script(query);\n",
"print(res)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fVzHT5XTpcm_"
},
"source": [
"### Question 3.\n",
"Consider the following login function. Given the username and password, it searches the database for any matching records. If (len(select_res) > 0
), the login attempt will succeed; otherwise, the login attempt will fail."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "LiRYo2qApcm_"
},
"outputs": [],
"source": [
"def login(username, password):\n",
" try:\n",
" select_res = exe_sql_script(\"SELECT username FROM users WHERE username = '\" + username + \"' AND password = '\" + password +\"'\");\n",
" except:\n",
" print(\"Failed to execute the sql script!\")\n",
" if len(select_res) > 0:\n",
" print(\"Login Successfully!\")\n",
" print(\"user: \" + username)\n",
" else:\n",
" print(\"Login Failed!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "sBR95J0ppcm_"
},
"source": [
"Please provide values for the username
and password
variables to login as admin. You can find out the password of admin in the setup script or question 2. Execute the following login
call to see the result."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "pEK-lnCSpcm_"
},
"outputs": [],
"source": [
"username = \"\" # Your answer (5 - 1 marks)\n",
"password = \"\" # Your answer (6 - 1 marks)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "7uXTn5D5pcm_"
},
"outputs": [],
"source": [
"# Test your answer\n",
"login(username, password)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SyeAS-lVpcm_"
},
"source": [
"### Question 4.\n",
"Suppose the attacker is not a user of this database and does not know the password of any users in the system. Please fill in the username
and password
variables to login without using passwords of any existing users in the setup script."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "unK1w04hpcm_"
},
"outputs": [],
"source": [
"username = \"\" # Your answer (7 - 4 marks)\n",
"password = \"\" # Your answer (8 - 4 marks)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "rrf5jIlKpcm_"
},
"outputs": [],
"source": [
"# Test your answer\n",
"login(username, password)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "n3FCvDDKpcm_"
},
"source": [
"### Question 5.\n",
"Suppose the attacker wants to add their username and password to the database by leveraging the vulnerability in the login
function. Please provide values for the username
and password
variables such that the attacker's credentials: (username) \"attacker\" and (password) \"password123\" are inserted into the users table. You can use the following login
call to perform the injection and the second login
call to see if the injection succeeds. Hint: the first login attempt might fail."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ig8pxSN3pcm_"
},
"outputs": [],
"source": [
"username = \"\" # Your answer (9 - 5 marks)\n",
"password = \"\" # Your answer (10 - 5 marks)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "AM_yAXY2pcm_"
},
"outputs": [],
"source": [
"# Perform the injection\n",
"login(username, password)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "bxewEK_Wpcm_"
},
"outputs": [],
"source": [
"# Test your anwser\n",
"login(\"attacker\", \"password123\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SHUYPVO2pcm_"
},
"source": [
"### Question 6.\n",
"The application developer is trying to limit the number of SQL commands used in the login function as a potential defense. The new login function is given below. Please fill in the username
and password
variables to bypass this defense (Suppose the attacker does not know password of any existing user). Hint: think about how to start a comment in SQL."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "CxUpxMhRpcnA"
},
"outputs": [],
"source": [
"def login_defense_attempt1(username, password):\n",
" select_res = []\n",
" try:\n",
" print(\"SELECT username FROM users WHERE username = '\" + username + \"' AND password = '\" + password +\"'\");\n",
" for row in cur.execute(\"SELECT username FROM users WHERE username = '\" + username + \"' AND password = '\" + password +\"'\"):\n",
" select_res.append(row)\n",
" except:\n",
" print(\"Failed to execute the sql script!\")\n",
" if len(select_res) > 0:\n",
" print(\"Login Successfully!\")\n",
" print(\"user: \" + username)\n",
" else:\n",
" print(\"Login Failed!\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ZRZ2EA5EpcnA"
},
"outputs": [],
"source": [
"username = \"\" # Your answer (11 - 5 marks)\n",
"password = \"\" # Your answer (12 - 5 marks)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "YkkarJAwpcnA"
},
"outputs": [],
"source": [
"# Test your answer\n",
"login_defense_attempt1(username, password)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yd-ThRfqpcnA"
},
"source": [
"### Question 7.\n",
"One way to defend against the attack in the question 6 is to sanitize the query string. For example, we may escape any potential input that could be used in an attack. Escaping a character means will treat characters as part of the string, not actual SQL syntax. Please implement a sanitizer in the following function to escape any potential symbol in the query string. You can test it using your answer in question 6."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "OlzZ_odrpcnA"
},
"outputs": [],
"source": [
"def login_defense_attempt2(username, password):\n",
" query = \"SELECT username FROM users WHERE username = '\" + username + \"' AND password = '\" + password +\"'\";\n",
" # -----------------------\n",
" # Your answer here (13 - 30 marks)\n",
"\n",
"\n",
" # ------------------------\n",
" select_res = []\n",
" try:\n",
" print(query);\n",
" for row in cur.execute(\"SELECT username FROM users WHERE username = '\" + username + \"' AND password = '\" + password +\"'\"):\n",
" select_res.append(row)\n",
" except:\n",
" print(\"Failed to execute the sql script!\")\n",
" if len(select_res) > 0:\n",
" print(\"Login Successfully!\")\n",
" print(\"user: \" + username)\n",
" else:\n",
" print(\"Login Failed!\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NaliJt_WpcnA"
},
"outputs": [],
"source": [
"username = \"\" # Your answer in question 6\n",
"password = \"\" # Your answer in question 6"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "dLa2e9X3pcnA"
},
"outputs": [],
"source": [
"# Test your answer; it is supposed to fail\n",
"login_defense_attempt2(username, password)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3gCVLOvApcnA"
},
"source": [
"## Finish\n",
"Run the following block of code to stop the database once you are finished."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "fHDJx89opcnA"
},
"outputs": [],
"source": [
"cur.execute(\"DROP TABLE transcripts\")\n",
"cur.execute(\"DROP TABLE users\")\n",
"con.commit()\n",
"con.close()"
]
}
],
"metadata": {
"interpreter": {
"hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.8"
},
"colab": {
"provenance": []
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Brendan\n", " Congratulations!
\n", "