diff options
author | Jonas Kohl | 2024-11-07 16:19:33 +0100 |
---|---|---|
committer | Jonas Kohl | 2024-11-07 16:19:33 +0100 |
commit | c6ec81174ce04edc2a8ac396e1ef2489e809130a (patch) | |
tree | 8b7a9df0073277677329705f568bdddec32199da | |
parent | 428124f6ce1e67a8405882d7cf8f396486b059f2 (diff) |
CSRF tokens
-rw-r--r-- | public/index.php | 101 | ||||
-rw-r--r-- | public/site.js | 80 |
2 files changed, 107 insertions, 74 deletions
diff --git a/public/index.php b/public/index.php index 6e0a8fb..0b3cabc 100644 --- a/public/index.php +++ b/public/index.php @@ -1,5 +1,12 @@ <?php +session_name("a3e0f0ee-9f5a-4be2-88cb-3b7ceb626d00"); +session_start(); + +function csrf_token(): string { + return $_SESSION["csrf-token"] = base64_encode(random_bytes(30)); +} + function getid(): string { return str_pad(bin2hex(random_bytes(16)), 32, "0", STR_PAD_LEFT); } @@ -32,7 +39,19 @@ $result = null; if (isset($_POST["code"]) && strlen($_POST["code"]) <= 16383) { $id = getid(); + header("Content-Type: application/json"); + $code = $_POST["code"]; + $csrf = $_POST["csrf"] ?? null; + + if ($csrf === null || $csrf !== $_SESSION["csrf-token"]) { + echo json_encode([ + "ok" => false, + "message" => "CSRF token mismatch", + "csrf" => csrf_token(), + ]); + exit; + } $srcDir = __DIR__ . "/../_runners/$id/src"; @@ -44,17 +63,21 @@ if (isset($_POST["code"]) && strlen($_POST["code"]) <= 16383) { $resultStr = shell_exec("./compile-and-run.sh '$id' Program 2>/dev/null"); chdir(__DIR__); + $csrf = csrf_token(); + if (is_string($resultStr)) { $result = json_decode($resultStr, true); $result["runner"] = $id; + $result["ok"] = true; + $result["csrf"] = $csrf; } - - header("Content-Type: application/json"); echo json_encode($result); exit; } +$csrf = csrf_token(); + ?> <!DOCTYPE html> <html lang="en"> @@ -68,6 +91,7 @@ if (isset($_POST["code"]) && strlen($_POST["code"]) <= 16383) { <script src="jquery-1.12.4.min.js"></script> <script src="codemirror.js"></script> <script src="clike.js"></script> + <script src="site.js"></script> </head> <body> <div id="loader" style="display: none;"> @@ -76,83 +100,12 @@ if (isset($_POST["code"]) && strlen($_POST["code"]) <= 16383) { <h1>☕️ Java Compiler</h1> <p>Powered by Eclipse Temurin</p> <form method="POST"> + <input name="csrf" id="csrf-token" type="hidden" value="<?= htmlentities($csrf) ?>"> <textarea maxlength="16383" id="editor" name="code" rows="20"><?= htmlentities($code ?? $defaultCode) ?></textarea> <div id="toolbar"> <button type="submit">▶ Compile & run</button> </div> </form> <div id="output" style="display: none;"></div> - - <script> - $(function() { - var editor = CodeMirror.fromTextArea($("#editor")[0], { - lineNumbers: true, - mode: "text/x-java", - theme: "eclipse", - tabSize: 4, - indentWithTabs: false, - smartIndent: true, - indentUnit: 4 - }); - editor.setSize(898, 500); - - $("form").on("submit", function(e) { - e.preventDefault(); - - $("#loader").show(); - $("#output").empty().hide(); - - $.ajax({ - type: "POST", - url: location.href, - data: { - code: editor.getValue() - }, - dataType: "json", - success: function(data) { - $("#loader").hide(); - - if (data.compile.status == 0) { - if (data.run.status != null) { - // program was executed - $("#output").append( - $("<h4></h4>").text(data.run.status == 0 ? "Executed successfully" : "Execution failed").css("color", data.run.status == 0 ? "green" : "red"), - ); - - if (data.run.stdout) { - $("#output").append( - $("<p></p>").text("Program output:"), - $("<pre></pre>").append( - $("<code></code>").text(data.run.stdout) - ) - ); - } - - if (data.run.stderr) { - $("#output").append( - $("<p></p>").text("Error output:"), - $("<pre></pre>").append( - $("<code></code>").text(data.run.stderr) - ) - ); - } - } - } else { - // compilation failed, stderr will contain compiler errors - $("#output").append( - $("<h4></h4>").text("Compilation failed").css("color", "red"), - $("<p></p>").text("Compiler errors:"), - $("<pre></pre>").append( - $("<code></code>").text(data.compile.stderr) - ) - ); - } - - $("#output").slideDown(400); - } - }) - }); - }); - </script> </body> </html> diff --git a/public/site.js b/public/site.js new file mode 100644 index 0000000..21d51a7 --- /dev/null +++ b/public/site.js @@ -0,0 +1,80 @@ +$(function() { + var csrf = $("#csrf-token").val(); + var editor = CodeMirror.fromTextArea($("#editor")[0], { + lineNumbers: true, + mode: "text/x-java", + theme: "eclipse", + tabSize: 4, + indentWithTabs: false, + smartIndent: true, + indentUnit: 4 + }); + editor.setSize(898, 500); + + $("form").on("submit", function(e) { + e.preventDefault(); + + $("#loader").show(); + $("#output").empty().hide(); + + $.ajax({ + type: "POST", + url: location.href, + data: { + code: editor.getValue(), + csrf: csrf + }, + dataType: "json", + success: function(data) { + $("#loader").hide(); + + if (!data.ok) { + alert("Error: " + data.message); + if (data.csrf) + csrf = data.csrf; + return; + } + + csrf = data.csrf; + + if (data.compile.status == 0) { + if (data.run.status != null) { + // program was executed + $("#output").append( + $("<h4></h4>").text(data.run.status == 0 ? "Executed successfully" : "Execution failed").css("color", data.run.status == 0 ? "green" : "red"), + ); + + if (data.run.stdout) { + $("#output").append( + $("<p></p>").text("Program output:"), + $("<pre></pre>").append( + $("<code></code>").text(data.run.stdout) + ) + ); + } + + if (data.run.stderr) { + $("#output").append( + $("<p></p>").text("Error output:"), + $("<pre></pre>").append( + $("<code></code>").text(data.run.stderr) + ) + ); + } + } + } else { + // compilation failed, stderr will contain compiler errors + $("#output").append( + $("<h4></h4>").text("Compilation failed").css("color", "red"), + $("<p></p>").text("Compiler errors:"), + $("<pre></pre>").append( + $("<code></code>").text(data.compile.stderr) + ) + ); + } + + $("#output").slideDown(400); + } + }) + }); +}); |