|
1 | | -import os |
| 1 | +# Model solution follows |
2 | 2 |
|
3 | | -# Example of a secure function that doesn't suffer from path traversal |
4 | | -def safe_path(path): |
5 | | - base_dir = os.path.dirname(os.path.abspath(__file__)) |
6 | | - filepath = os.path.normpath(os.path.join(base_dir, path)) |
7 | | - if base_dir != os.path.commonpath([base_dir, filepath]): |
8 | | - return None |
9 | | - return filepath |
10 | | - |
11 | | -# Following the above, this is the secure version of the respective function on code.py |
12 | | -def get_prof_picture(self, path=None): |
13 | | - # setting a profile picture is optional |
14 | | - if not path: |
15 | | - pass |
16 | | - |
17 | | - # defends against path traversal attacks |
18 | | - if path.startswith('/') or path.startswith('..'): |
19 | | - return None |
20 | | - |
21 | | - # builds path |
22 | | - base_dir = os.path.dirname(os.path.abspath(__file__)) |
23 | | - prof_picture_path = os.path.normpath(os.path.join(base_dir, path)) |
24 | | - if base_dir != os.path.commonpath([base_dir, prof_picture_path]): |
25 | | - return None |
26 | | - |
27 | | - with open(prof_picture_path, 'rb') as pic: |
28 | | - picture = bytearray(pic.read()) |
29 | | - |
30 | | - # assume that image is returned on screen after this |
31 | | - return prof_picture_path |
| 3 | +import os |
| 4 | +from flask import Flask, request |
| 5 | + |
| 6 | +### Unrelated to the exercise -- Starts here -- Please ignore |
| 7 | +app = Flask(__name__) |
| 8 | +@app.route("/") |
| 9 | +def source(): |
| 10 | + TaxPayer('foo', 'bar').get_tax_form_attachment(request.args["input"]) |
| 11 | + TaxPayer('foo', 'bar').get_prof_picture(request.args["input"]) |
| 12 | +### Unrelated to the exercise -- Ends here -- Please ignore |
| 13 | + |
| 14 | +class TaxPayer: |
| 15 | + |
| 16 | + def __init__(self, username, password): |
| 17 | + self.username = username |
| 18 | + self.password = password |
| 19 | + self.prof_picture = None |
| 20 | + self.tax_form_attachment = None |
| 21 | + |
| 22 | + # returns the path of an optional profile picture that users can set |
| 23 | + def get_prof_picture(self, path=None): |
| 24 | + # setting a profile picture is optional |
| 25 | + if not path: |
| 26 | + pass |
| 27 | + |
| 28 | + # builds path |
| 29 | + base_dir = os.path.dirname(os.path.abspath(__file__)) |
| 30 | + prof_picture_path = os.path.normpath(os.path.join(base_dir, path)) |
| 31 | + if not prof_picture_path.startswith(base_dir): |
| 32 | + return None |
| 33 | + |
| 34 | + with open(prof_picture_path, 'rb') as pic: |
| 35 | + picture = bytearray(pic.read()) |
| 36 | + |
| 37 | + # assume that image is returned on screen after this |
| 38 | + return prof_picture_path |
| 39 | + |
| 40 | + # returns the path of an attached tax form that every user should submit |
| 41 | + def get_tax_form_attachment(self, path=None): |
| 42 | + tax_data = None |
| 43 | + |
| 44 | + # A tax form is required |
| 45 | + if not path: |
| 46 | + raise Exception("Error: Tax form is required for all users") |
| 47 | + |
| 48 | + # Validate the path to prevent path traversal attacks |
| 49 | + base_dir = os.path.dirname(os.path.abspath(__file__)) |
| 50 | + tax_form_path = os.path.normpath(os.path.join(base_dir, path)) |
| 51 | + if not tax_form_path.startswith(base_dir): |
| 52 | + return None |
| 53 | + |
| 54 | + with open(tax_form_path, 'rb') as form: |
| 55 | + tax_data = bytearray(form.read()) |
| 56 | + |
| 57 | + # assume that tax data is returned on screen after this |
| 58 | + return tax_form_path |
32 | 59 |
|
33 | 60 |
|
34 | 61 | # Solution explanation |
|
0 commit comments