|
| 1 | +# Fixing your security layer |
| 2 | + |
| 3 | +In this assignment you will analyze the bugs in your security layer from [Part |
| 4 | +One](./DefaultPartOne.md) |
| 5 | +and fix them. You may want to use test cases from [Part |
| 6 | +Two](./DefaultPartTwo.md) |
| 7 | +to help identify these bugs. |
| 8 | + |
| 9 | + |
| 10 | +## Overview |
| 11 | + |
| 12 | +In this assignment you are fixing your reference monitor. You have been given a |
| 13 | +bunch of test programs that try to compromise your reference monitor. Your job |
| 14 | +will be to determine where your reference monitor failed, and fix it to ensure |
| 15 | +an attacker cannot circumvent the security layer. |
| 16 | + |
| 17 | +## Code Analysis |
| 18 | + |
| 19 | +Given below is a section taken from the sample reference monitor given |
| 20 | +in [Part One](./DefaultPartOne.md#a-basic-and-inadequate-defense). |
| 21 | + |
| 22 | +```py |
| 23 | +class LPFile(): |
| 24 | + def __init__(self, filename, create): |
| 25 | + # globals |
| 26 | + mycontext['debug'] = False |
| 27 | + |
| 28 | + if create == False and 'default' in listfiles(): |
| 29 | + # bug ? |
| 30 | + default_file = openfile('default', False) |
| 31 | + content = default_file.readat(None, 0) |
| 32 | + self.LPfile = openfile(filename, True) |
| 33 | + self.LPfile.writeat(content, 0) |
| 34 | + default_file.close() |
| 35 | + else: |
| 36 | + # bug ? |
| 37 | + self.LPfile = openfile(filename, create) |
| 38 | + |
| 39 | + def readat(self, num_bytes, offset): |
| 40 | + return self.LPfile.readat(num_bytes, offset) |
| 41 | + |
| 42 | + def writeat(self, data, offset): |
| 43 | + # bug ? |
| 44 | + self.LPfile.writeat(data, offset) |
| 45 | + |
| 46 | + def close(self): |
| 47 | + # bug ? |
| 48 | + self.LPfile.close() |
| 49 | + |
| 50 | +def LPopenfile(filename, create): |
| 51 | + return LPFile(filename, create) |
| 52 | + |
| 53 | +def LPremovefile(filename): |
| 54 | + # bug ? |
| 55 | + removefile(filename) |
| 56 | +``` |
| 57 | + |
| 58 | +Let's analyze some of the bugs in this implementation (not in any specific order). |
| 59 | + |
| 60 | +1. As outlined in the specifications in [PartOne](./DefaultPartOne.md), if the `default` file is absent, |
| 61 | +and we try to open a non-existent file with create=False, then the relevant |
| 62 | +error (`FileNotFoundError`) must be thrown. This scenario is not correctly handled in the sample implementation. |
| 63 | + |
| 64 | +2. Similarly, if the `default` file is modified (created/written to/deleted), then we need to delete all files that were created |
| 65 | +during the run and are not open at the moment of modification. To achieve this, the state of all (open) files created during the |
| 66 | +run should be tracked. You can use the global variable `mycontext` to store this state. For efficiency, only filenames or |
| 67 | +file handles should be stored, rather than the actual file contents. |
| 68 | + |
| 69 | +3. One common edge case often overlooked by students occurs when attempting to open a non-existent file with |
| 70 | +create=False while default is already open. If it's not handled correctly, this will cause a FileInUseError, which |
| 71 | +shouldn't happen. To prevent this, the reference monitor should maintain a reference to the file handle of default, |
| 72 | +whenever default is open (so that it can be used to create new templates). Also note that storing the contents of default |
| 73 | +in memory at all times is not an optimal solution due to efficiency concerns. |
| 74 | + |
| 75 | +4. Finally, this example doesn't use locks, which can lead to race conditions, thus allowing various types of multi-threading attacks. |
| 76 | + |
| 77 | + |
| 78 | +## What to turn in? |
| 79 | + |
| 80 | +* Submit 2 files: |
| 81 | + 1. 1 r2py file: Your reference monitor should be named as `reference_monitor_[netid].r2py` with all |
| 82 | +letters in lowercase . For example, if your netid is `abc123`, the file should be named: `reference_monitor_abc123.r2py`. |
| 83 | + 2. 1 pdf file: Write up a 1 page report explaining the rationale behind the vulnerabilities and how you fixed them. Name it `[netid].pdf`. |
| 84 | + |
| 85 | +* **Never raise unexpected errors or produce any output.** Your reference monitor must |
| 86 | +produce no output when run normally, with a valid attack case. Make sure that you remove any `log()` statements used for debugging before submission. |
| 87 | + |
| 88 | +* You are required to modify your reference monitor so that it generates no output (logs or errors) when any valid attack case (from Part 2.2, after invalid attack cases have been identified and excluded) is executed against it. |
0 commit comments