Rate-limit most form processings

This commit is contained in:
Miraty 2023-04-28 15:39:05 +02:00
parent 2ecc520dae
commit 9f5f8958c5
21 changed files with 60 additions and 0 deletions

View file

@ -31,14 +31,17 @@ define('PAGES', [
'approval' => [
'title' => _('Switch to an approved account'),
'description' => _('Switch to an approved account using an approval key'),
'tokens_account_cost' => 300,
],
'password' => [
'title' => _('Change password'),
'description' => _('Change the character string used to authenticate yourself'),
'tokens_account_cost' => 300,
],
'username' => [
'title' => _('Change username'),
'description' => _('Change the name used to identify your account when logging in and displayed at the start of every page'),
'tokens_account_cost' => 300,
],
],
'reg' => [
@ -58,22 +61,27 @@ define('PAGES', [
'print' => [
'title' => _('Display domain records'),
'description' => _('Print every record related to a domain and served by the registry'),
'tokens_account_cost' => 60,
],
'ns' => [
'title' => sprintf(_('%s records'), '<abbr title="Name Server">NS</abbr>'),
'description' => sprintf(_('Indicate the name servers of a %s subdomain'), '<code>' . key(CONF['reg']['suffixes']) . '</code>'),
'tokens_account_cost' => 300,
],
'ds' => [
'title' => sprintf(_('%s records'), '<abbr title="Delegation Signer">DS</abbr>'),
'description' => _('Delegate <abbr title="Domain Name System Security Extensions">DNSSEC</abbr> trust'),
'tokens_account_cost' => 300,
],
'transfer' => [
'title' => _('Receive a domain transfer'),
'description' => _('Transfer a domain owned by another account to the current account'),
'tokens_account_cost' => 300,
],
'glue' => [
'title' => _('Glue records'),
'description' => _('Advanced: store the IP address of a name server whose domain is inside the domain it serves'),
'tokens_account_cost' => 300,
],
],
'ns' => [
@ -93,6 +101,7 @@ define('PAGES', [
'print' => [
'title' => _('Display zone'),
'description' => _('Print zonefile content'),
'tokens_account_cost' => 60,
],
'edit' => [
'title' => _('Edit zone'),
@ -102,46 +111,57 @@ define('PAGES', [
'ip' => [
'title' => _('AAAA and A records'),
'description' => _('Store domain\'s IP address'),
'tokens_account_cost' => 120,
],
'ns' => [
'title' => sprintf(_('%s records'), '<abbr title="Name Server">NS</abbr>'),
'description' => _('Store zone\'s name server'),
'tokens_account_cost' => 120,
],
'txt' => [
'title' => sprintf(_('%s records'), '<abbr title="TeXT">TXT</abbr>'),
'description' => _('Associate text to domain'),
'tokens_account_cost' => 120,
],
'caa' => [
'title' => sprintf(_('%s records'), '<abbr title="Certification Authority Authorization">CAA</abbr>'),
'description' => _('Limit the certificate authorities allowed to certify the domain'),
'tokens_account_cost' => 120,
],
'srv' => [
'title' => sprintf(_('%s records'), '<abbr title="SeRVice">SRV</abbr>'),
'description' => _('Store the location of a domain\'s service'),
'tokens_account_cost' => 120,
],
'mx' => [
'title' => sprintf(_('%s records'), '<abbr title="Mail eXchanger">MX</abbr>'),
'description' => _('Store the email server\'s address'),
'tokens_account_cost' => 120,
],
'sshfp' => [
'title' => sprintf(_('%s records'), '<abbr title="Secure SHell FingerPrint">SSHFP</abbr>'),
'description' => _('Store <abbr title="Secure SHell">SSH</abbr> public keys fingerprints'),
'tokens_account_cost' => 120,
],
'tlsa' => [
'title' => sprintf(_('%s records'), '<abbr title="Transport Layer Security Association">TLSA</abbr>'),
'description' => _('Setup <abbr title="DNS-based Authentication of Named Entities">DANE</abbr> by publishing the <abbr title="Transport Layer Security">TLS</abbr> certificate fingerprint'),
'tokens_account_cost' => 120,
],
'cname' => [
'title' => sprintf(_('%s records'), '<abbr title="Canonical NAME">CNAME</abbr>'),
'description' => _('Define a domain as an alias of another'),
'tokens_account_cost' => 120,
],
'dname' => [
'title' => sprintf(_('%s records'), '<abbr title="Delegation NAME">DNAME</abbr>'),
'description' => _('Define all subdomains of a domain as aliases of subdomains of another domain'),
'tokens_account_cost' => 120,
],
'loc' => [
'title' => sprintf(_('%s records'), '<abbr title="LOCation">LOC</abbr>'),
'description' => _('Store geographic coordinates'),
'tokens_account_cost' => 120,
],
],
'ht' => [

View file

@ -3,6 +3,8 @@
if ($_SESSION['type'] !== 'testing')
output(403, _('This account is already approved.'));
rateLimit();
if (isset(query('select', 'approval-keys', ['key' => $_POST['key']], 'key')[0]) !== true)
output(403, _('This approval key is not available. It has been mistyped, used for another account, or has expired.'));

View file

@ -5,6 +5,8 @@ checkPasswordFormat($_POST['new-password']);
if (checkPassword($_SESSION['id'], $_POST['current-password']) !== true)
output(403, _('Wrong current password.'));
rateLimit();
changePassword($_SESSION['id'], $_POST['new-password']);
output(200, _('Password updated.'));

View file

@ -10,6 +10,8 @@ $username = hashUsername($_POST['new-username']);
if (usernameExists($username) !== false)
output(403, _('This username is already taken.'));
rateLimit();
DB->prepare('UPDATE users SET username = :username WHERE id = :id')
->execute([':username' => $username, ':id' => $_SESSION['id']]);

View file

@ -11,6 +11,8 @@ if (!(preg_match('/^[a-z]{1,127}$/D', $_POST['tag'])))
if (!(preg_match('/^[a-z0-9.-]{1,255}$/D', $_POST['value'])))
output(403, 'Wrong value for <code>value</code>.');
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -4,6 +4,8 @@ $values = nsParseCommonRequirements();
$_POST['cname'] = formatAbsoluteDomain($_POST['cname']);
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -4,6 +4,8 @@ $values = nsParseCommonRequirements();
$_POST['dname'] = formatAbsoluteDomain($_POST['dname']);
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -4,6 +4,8 @@ $values = nsParseCommonRequirements();
$record = checkIpFormat($_POST['ip']);
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -49,6 +49,8 @@ if (!($_POST['hp'] >= 0 AND $_POST['hp'] <= 90000000))
if (!($_POST['vp'] >= 0 AND $_POST['vp'] <= 90000000))
output(403, 'Wrong value for <code>vp</code>.');
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -7,6 +7,8 @@ if (!($_POST['priority'] >= 0 AND $_POST['priority'] <= 255))
$_POST['host'] = formatAbsoluteDomain($_POST['host']);
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -4,6 +4,8 @@ $values = nsParseCommonRequirements();
$_POST['ns'] = formatAbsoluteDomain($_POST['ns']);
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -4,6 +4,8 @@ nsCheckZonePossession($_POST['zone']);
$data['zone_name'] = $_POST['zone'];
rateLimit();
$zone_content = file_get_contents(CONF['ns']['knot_zones_path'] . '/' . $data['zone_name'] . 'zone');
if ($zone_content === false)
output(500, 'Unable to read zone file.');

View file

@ -13,6 +13,8 @@ if (!($_POST['port'] >= 0 AND $_POST['port'] <= 65535))
$_POST['target'] = formatAbsoluteDomain($_POST['target']);
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -11,6 +11,8 @@ if (!($_POST['type'] === '2'))
if (!(preg_match('/^[a-z0-9]{64}$/D', $_POST['fp'])))
output(403, 'Wrong value for <code>fp</code>.');
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -14,6 +14,8 @@ if (!($_POST['type'] >= 0 AND $_POST['type'] <= 2))
if (!(preg_match('/^[a-zA-Z0-9.-]{1,1024}$/D', $_POST['content'])))
output(403, 'Wrong value for <code>content</code>.');
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -5,6 +5,8 @@ $values = nsParseCommonRequirements();
if (!(preg_match('/^[a-zA-Z0-9 .@=:!%$+\/\()[\]_-]{5,8192}$/D', $_POST['txt'])))
output(403, 'Wrong value for <code>txt</code>.');
rateLimit();
knotcZoneExec($_POST['zone'], [
$values['domain'],
$values['ttl'],

View file

@ -17,6 +17,8 @@ if ($_POST['dt'] !== '2' AND $_POST['dt'] !== '4')
regCheckDomainPossession($_POST['zone']);
rateLimit();
knotcZoneExec(regParseDomain($_POST['zone'])['suffix'], [
$_POST['zone'],
CONF['reg']['ttl'],

View file

@ -2,6 +2,8 @@
regCheckDomainPossession($_POST['suffix']);
rateLimit();
knotcZoneExec(regParseDomain($_POST['suffix'])['suffix'], [
formatAbsoluteDomain(formatEndWithDot($_POST['subdomain']) . $_POST['suffix']),
CONF['reg']['ttl'],

View file

@ -2,6 +2,8 @@
regCheckDomainPossession($_POST['domain']);
rateLimit();
knotcZoneExec(regParseDomain($_POST['domain'])['suffix'], [
$_POST['domain'],
CONF['reg']['ttl'],

View file

@ -2,6 +2,8 @@
regCheckDomainPossession($_POST['domain']);
rateLimit();
$zone_content = file_get_contents(CONF['reg']['suffixes_path'] . '/' . regParseDomain($_POST['domain'])['suffix'] . 'zone');
if ($zone_content === false)
output(500, 'Unable to read registry file.');

View file

@ -19,6 +19,8 @@ if (preg_match('/^' . preg_quote($domain, '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+
checkAuthToken($matches['salt'], $matches['hash']);
rateLimit();
DB->prepare('UPDATE registry SET username = :username WHERE domain = :domain')
->execute([':username' => $_SESSION['id'], ':domain' => $domain]);