From b7e69d8b41cad77601cccd85d9d12bfb217b1708 Mon Sep 17 00:00:00 2001 From: Miraty Date: Sun, 22 May 2022 17:47:00 +0200 Subject: [PATCH] Check for CSRF at only one place in the code --- common/html.php | 34 ++++++------ form.ns.php | 109 ++++++++++++++++++------------------- less/main.less | 1 + ns.php | 7 +-- public/auth/login.php | 2 - public/auth/password.php | 2 - public/auth/register.php | 2 - public/ht/http-onion.php | 2 - public/ht/https-domain.php | 2 - public/ht/le.php | 2 - public/ns/caa.php | 2 +- public/ns/dnssec.php | 2 - public/ns/ip.php | 2 +- public/ns/loc.php | 2 +- public/ns/mx.php | 2 +- public/ns/ns.php | 2 +- public/ns/srv.php | 2 +- public/ns/sshfp.php | 2 +- public/ns/tlsa.php | 2 +- public/ns/txt.php | 2 +- public/ns/zone.php | 2 - public/reg/ds.php | 2 - public/reg/glue.php | 2 - public/reg/ns.php | 2 - public/reg/register.php | 2 - 25 files changed, 82 insertions(+), 111 deletions(-) diff --git a/common/html.php b/common/html.php index d54c703..c14d8bf 100644 --- a/common/html.php +++ b/common/html.php @@ -2,11 +2,6 @@ require "init.php"; -function antiCSRF() { - if (!isset($_SERVER['HTTP_SEC_FETCH_SITE']) OR $_SERVER['HTTP_SEC_FETCH_SITE'] !== "same-origin") - userError("Anti-CSRF verification failed ! (Wrong or unset Sec-Fetch-Site HTTP header)"); -} - // Session initialisation (with cookies) if ( isset($_COOKIE['niver-session-key']) // Resume session @@ -75,7 +70,7 @@ $cssFileName = Less_Cache::Get($absoluteLessFiles, $options, THEME); - + <?php if (isset($page['title']) AND $page['title'] != "Accueil") echo $page['title'] . " < "; @@ -85,26 +80,29 @@ $cssFileName = Less_Cache::Get($absoluteLessFiles, $options, THEME); <link type="text/css" rel="stylesheet" href="<?= CONF['common']['prefix'] ?>/css/<?= $cssFileName ?>"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> - <body> <header> - <nav> <a href="..">Niver</a><?php - if (isset($page['service'])) - echo ' > <a href=".">' . $page['service'] . '</a>'; - if (PAGE != "index") - echo ' > <a href="' . PAGE . '">' . $page['title'] . "</a>"; - ?> +if (isset($page['service'])) + echo ' > <a href=".">' . $page['service'] . '</a>'; +if (PAGE != "index") + echo ' > <a href="' . PAGE . '">' . $page['title'] . "</a>"; +?> + </nav> - - <?php if (isset($page['title'])) { ?> - <h1><?= $page['title'] ?></h1> - <?php } ?> - </header> <main> + <?php + +if (isset($page['title'])) + echo "<h1>" . $page['title'] . "</h1>"; + +// Protect against cross-site request forgery if a POST request is received +if (empty($_POST) === false AND (isset($_SERVER['HTTP_SEC_FETCH_SITE']) !== true OR $_SERVER['HTTP_SEC_FETCH_SITE'] !== "same-origin")) + userError("Anti-CSRF verification failed ! (Wrong or unset <code>Sec-Fetch-Site</code> HTTP header)"); + function closeHTML() { ?> </main> diff --git a/form.ns.php b/form.ns.php index ab301c7..7a7b5f0 100644 --- a/form.ns.php +++ b/form.ns.php @@ -1,59 +1,58 @@ -<label for="action">Action</label> -<select name="action" id="action"> - <option value="add">Ajouter</option> - <option value="delete">Retirer</option> -</select> -<br> + <label for="action">Action</label> + <select name="action" id="action"> + <option value="add">Ajouter</option> + <option value="delete">Retirer</option> + </select> + <br> -<fieldset> - <legend>Domaine</legend> - <div> - <label for="subdomain">Sous-domaine</label> - <br> - <input id="subdomain" size="16" placeholder="www" pattern="^(([a-z0-9_-]{1,63}\.?){1,127})|(@){1}$" name="subdomain" type="text"> - </div> - <div> - <label for="zone">Zone</label> - <br> - <select required="" name="zone" id="zone"> - <option value="" disabled="" selected="">-</option> + <fieldset> + <legend>Domaine</legend> + <div> + <label for="subdomain">Sous-domaine</label> + <br> + <input id="subdomain" size="16" placeholder="www" pattern="^(([a-z0-9_-]{1,63}\.?){1,127})|(@){1}$" name="subdomain" type="text"> + </div> + <div> + <label for="zone">Zone</label> + <br> + <select required="" name="zone" id="zone"> + <option value="" disabled="" selected="">-</option> + <?php + $zones = nsListUserZones($_SESSION['username']); - <?php - $zones = nsListUserZones($_SESSION['username']); + if (!empty($zones)) + foreach ($zones as $zone) + echo "<option value='" . $zone . "'>" . $zone . "</option>"; + ?> - if (!empty($zones)) { - foreach ($zones as $zone) - echo "<option value='" . $zone . "'>" . $zone . "</option>"; - } - ?> - </select> - </div> -</fieldset> + </select> + </div> + </fieldset> -<fieldset> - <legend><abbr title="Time To Live">TTL</abbr></legend> - <div> - <label for="ttl-value">Valeur</label> - <br> - <input required="" id="ttl-value" list="ttls" name="ttl-value" size="6" type="number" min="1" max="432000" value="10800" placeholder="10800"> - <datalist id="ttls"> - <option value="900"> - <option value="1800"> - <option value="3600"> - <option value="10800"> - <option value="21600"> - <option value="86400"> - <option value="432000"> - </datalist> - </div> - <div> - <label for="ttl-multiplier">Unité</label> - <br> - <select required="" name="ttl-multiplier" id="ttl-multiplier"> - <option value="1">seconde</option> - <option value="60">minute</option> - <option value="3600">heure</option> - <option value="86400">jour</option> - </select> - </div> -</fieldset> + <fieldset> + <legend><abbr title="Time To Live">TTL</abbr></legend> + <div> + <label for="ttl-value">Valeur</label> + <br> + <input required="" id="ttl-value" list="ttls" name="ttl-value" size="6" type="number" min="1" max="432000" value="10800" placeholder="10800"> + <datalist id="ttls"> + <option value="900"> + <option value="1800"> + <option value="3600"> + <option value="10800"> + <option value="21600"> + <option value="86400"> + <option value="432000"> + </datalist> + </div> + <div> + <label for="ttl-multiplier">Unité</label> + <br> + <select required="" name="ttl-multiplier" id="ttl-multiplier"> + <option value="1">seconde</option> + <option value="60">minute</option> + <option value="3600">heure</option> + <option value="86400">jour</option> + </select> + </div> + </fieldset> diff --git a/less/main.less b/less/main.less index dfd0b2c..d4461f2 100644 --- a/less/main.less +++ b/less/main.less @@ -9,6 +9,7 @@ html { } h1 { + text-align: center; font-size: @fontSize + 25px; line-height: @fontSize + 30px } diff --git a/ns.php b/ns.php index 7409a0f..f807390 100644 --- a/ns.php +++ b/ns.php @@ -1,15 +1,12 @@ <?php function nsCommonRequirements() { - if (isset($_POST['action']) + return (isset($_POST['action']) AND isset($_POST['zone']) AND isset($_POST['ttl-value']) AND isset($_POST['ttl-multiplier']) AND isset($_SESSION['username']) - ) { - antiCSRF(); - return true; - } + ); } function nsParseCommonRequirements() { diff --git a/public/auth/login.php b/public/auth/login.php index c835581..2346308 100644 --- a/public/auth/login.php +++ b/public/auth/login.php @@ -18,8 +18,6 @@ Pas de compte ? <a class="authButton" href="register">En créer un</a> if (isset($_POST['username']) AND isset($_POST['password'])) { - antiCSRF(); - checkPasswordFormat($_POST['password']); checkUsernameFormat($_POST['username']); diff --git a/public/auth/password.php b/public/auth/password.php index b601308..a55e681 100644 --- a/public/auth/password.php +++ b/public/auth/password.php @@ -18,8 +18,6 @@ if (isset($_SESSION['username']) AND isset($_POST['newPassword']) AND isset($_POST['currentPassword'])) { - antiCSRF(); - checkPasswordFormat($_POST['newPassword']); if (checkPassword($_SESSION['username'], $_POST['currentPassword']) !== true) diff --git a/public/auth/register.php b/public/auth/register.php index 7e61ee6..64c711e 100644 --- a/public/auth/register.php +++ b/public/auth/register.php @@ -4,8 +4,6 @@ if (isset($_POST['username']) AND isset($_POST['password'])) { - antiCSRF(); - checkPasswordFormat($_POST['password']); checkUsernameFormat($_POST['username']); diff --git a/public/ht/http-onion.php b/public/ht/http-onion.php index 778a243..cb208a7 100644 --- a/public/ht/http-onion.php +++ b/public/ht/http-onion.php @@ -30,8 +30,6 @@ if (isset($_SESSION['username'])) { if (isset($_POST['dir']) AND isset($_SESSION['username'])) { - antiCSRF(); - if ($dirsStatuses[$_POST['dir']] !== false) userError("Wrong value for <code>dir</code>."); diff --git a/public/ht/https-domain.php b/public/ht/https-domain.php index 492bd35..23caaf9 100644 --- a/public/ht/https-domain.php +++ b/public/ht/https-domain.php @@ -36,8 +36,6 @@ if (isset($_SESSION['username'])) { if (isset($_POST['domain']) AND isset($_POST['dir']) AND isset($_SESSION['username'])) { - antiCSRF(); - checkDomainFormat($_POST['domain']); if ($dirsStatuses[$_POST['dir']] !== false) diff --git a/public/ht/le.php b/public/ht/le.php index f37c933..75784ec 100644 --- a/public/ht/le.php +++ b/public/ht/le.php @@ -22,8 +22,6 @@ if (isset($_POST['domain']) AND isset($_SESSION['username'])) { - antiCSRF(); - exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['certbot_path'] . " certonly --dry-run --test-cert --webroot --webroot-path /srv/acme --register-unsafely-without-email --agree-tos --domain " . $_POST['domain'], $output, $returnCode); // Log Certbot response diff --git a/public/ns/caa.php b/public/ns/caa.php index a4f9238..043b2cf 100644 --- a/public/ns/caa.php +++ b/public/ns/caa.php @@ -2,7 +2,7 @@ <form method="post"> - <?php require "../../form.ns.php"; ?> +<?php require "../../form.ns.php"; ?> <br> <label for="flag">Flag</label> diff --git a/public/ns/dnssec.php b/public/ns/dnssec.php index d1e2256..2d363bc 100644 --- a/public/ns/dnssec.php +++ b/public/ns/dnssec.php @@ -27,8 +27,6 @@ Afin d'activer DNSSEC, vous devez indiquer un enregistrement DS à la zone paren if (isset($_POST['zone']) AND isset($_SESSION['username'])) { - antiCSRF(); - nsCheckZonePossession($_POST['zone']); $zoneContent = file_get_contents(CONF['ns']['knot_zones_path'] . "/" . $_POST['zone'] . "zone"); diff --git a/public/ns/ip.php b/public/ns/ip.php index 5e9d10d..b63f9d4 100644 --- a/public/ns/ip.php +++ b/public/ns/ip.php @@ -6,7 +6,7 @@ </p> <form method="post"> - <?php require "../../form.ns.php"; ?> +<?php require "../../form.ns.php"; ?> <label for="ip">Adresse IP</label><br> <input required="" pattern="^[a-f0-9:.]+$" id="ip" name="ip" minlength="7" maxlength="39" size="40" type="text" placeholder="<?= CONF['common']['ipv6_example'] ?> ou <?= CONF['common']['ipv4_example'] ?>"><br> <input value="Valider" type="submit"> diff --git a/public/ns/loc.php b/public/ns/loc.php index a4f9238..043b2cf 100644 --- a/public/ns/loc.php +++ b/public/ns/loc.php @@ -2,7 +2,7 @@ <form method="post"> - <?php require "../../form.ns.php"; ?> +<?php require "../../form.ns.php"; ?> <br> <label for="flag">Flag</label> diff --git a/public/ns/mx.php b/public/ns/mx.php index bd2a5a7..c36cc7c 100644 --- a/public/ns/mx.php +++ b/public/ns/mx.php @@ -2,7 +2,7 @@ <form method="post"> - <?php require "../../form.ns.php"; ?> +<?php require "../../form.ns.php"; ?> <br> diff --git a/public/ns/ns.php b/public/ns/ns.php index c40db7c..d1da018 100644 --- a/public/ns/ns.php +++ b/public/ns/ns.php @@ -1,7 +1,7 @@ <?php require "../../common/html.php"; ?> <form method="post"> - <?php require "../../form.ns.php"; ?> +<?php require "../../form.ns.php"; ?> <br> <label for="ns">Serveur de nom</label> <br> diff --git a/public/ns/srv.php b/public/ns/srv.php index 93761b1..32b5d9f 100644 --- a/public/ns/srv.php +++ b/public/ns/srv.php @@ -2,7 +2,7 @@ <form method="post"> - <?php require "../../form.ns.php"; ?> +<?php require "../../form.ns.php"; ?> <br> diff --git a/public/ns/sshfp.php b/public/ns/sshfp.php index 0a2a0a6..5ceb662 100644 --- a/public/ns/sshfp.php +++ b/public/ns/sshfp.php @@ -2,7 +2,7 @@ <form method="post"> - <?php require "../../form.ns.php"; ?> +<?php require "../../form.ns.php"; ?> <br> diff --git a/public/ns/tlsa.php b/public/ns/tlsa.php index 9df26bf..9f24bdd 100644 --- a/public/ns/tlsa.php +++ b/public/ns/tlsa.php @@ -2,7 +2,7 @@ <form method="post"> - <?php require "../../form.ns.php"; ?> +<?php require "../../form.ns.php"; ?> <br> <label for="use">Utilisation</label> diff --git a/public/ns/txt.php b/public/ns/txt.php index dab1fd4..374f5bf 100644 --- a/public/ns/txt.php +++ b/public/ns/txt.php @@ -1,7 +1,7 @@ <?php require "../../common/html.php"; ?> <form method="post"> - <?php require "../../form.ns.php"; ?> +<?php require "../../form.ns.php"; ?> <br> <label for="txt">Texte</label> <br> diff --git a/public/ns/zone.php b/public/ns/zone.php index 7f6d874..b0486ee 100644 --- a/public/ns/zone.php +++ b/public/ns/zone.php @@ -11,8 +11,6 @@ if (isset($_POST['domain']) AND isset($_SESSION['username'])) { - antiCSRF(); - checkAbsoluteDomainFormat($_POST['domain']); $db = new PDO('sqlite:' . DB_PATH); diff --git a/public/reg/ds.php b/public/reg/ds.php index cd6c2d4..907a319 100644 --- a/public/reg/ds.php +++ b/public/reg/ds.php @@ -70,8 +70,6 @@ if (isset($_POST['zone']) AND isset($_POST['keytag']) AND isset($_POST['algo']) AND isset($_POST['key']) AND isset($_SESSION['username'])) { - antiCSRF(); - if (!($_POST['algo'] === "8") AND !($_POST['algo'] === "13") AND !($_POST['algo'] === "14") diff --git a/public/reg/glue.php b/public/reg/glue.php index 6dc4e47..faa512a 100644 --- a/public/reg/glue.php +++ b/public/reg/glue.php @@ -43,8 +43,6 @@ if (isset($_POST['action']) AND isset($_POST['subdomain']) AND isset($_POST['suffix']) AND isset($_POST['ip']) AND isset($_SESSION['username'])) { - antiCSRF(); - if (in_array($_POST['suffix'], $suffixes) !== true) userError("You don't own this domain."); diff --git a/public/reg/ns.php b/public/reg/ns.php index 1a1dbd8..04cfa36 100644 --- a/public/reg/ns.php +++ b/public/reg/ns.php @@ -36,8 +36,6 @@ if (isset($_POST['domain']) AND isset($_POST['action']) AND isset($_POST['ns']) AND isset($_SESSION['username'])) { - antiCSRF(); - regCheckDomainPossession($_POST['domain']); checkAbsoluteDomainFormat($_POST['ns']); diff --git a/public/reg/register.php b/public/reg/register.php index cdc2680..7d2fdaf 100644 --- a/public/reg/register.php +++ b/public/reg/register.php @@ -17,8 +17,6 @@ Ce domaine doit être composé uniquement d'au moins 4 lettres latines non accen if (isset($_POST['subdomain']) AND isset($_SESSION['username'])) { - antiCSRF(); - if (preg_match("/" . CONF['reg']['subdomain_regex'] . "/", $_POST['subdomain']) !== 1) userError("Erreur : Le nom de domaine doit être composé uniquement d'entre 4 et 63 lettres minuscules (a-z)");