소스 검색

Rate-limit most form processings

Miraty 2 년 전
부모
커밋
9f5f8958c5

+ 20 - 0
pages.php

@@ -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' => [

+ 2 - 0
pg-act/auth/approval.php

@@ -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.'));
 

+ 2 - 0
pg-act/auth/password.php

@@ -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.'));

+ 2 - 0
pg-act/auth/username.php

@@ -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']]);
 

+ 2 - 0
pg-act/ns/caa.php

@@ -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'],

+ 2 - 0
pg-act/ns/cname.php

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

+ 2 - 0
pg-act/ns/dname.php

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

+ 2 - 0
pg-act/ns/ip.php

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

+ 2 - 0
pg-act/ns/loc.php

@@ -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'],

+ 2 - 0
pg-act/ns/mx.php

@@ -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'],

+ 2 - 0
pg-act/ns/ns.php

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

+ 2 - 0
pg-act/ns/print.php

@@ -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.');

+ 2 - 0
pg-act/ns/srv.php

@@ -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'],

+ 2 - 0
pg-act/ns/sshfp.php

@@ -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'],

+ 2 - 0
pg-act/ns/tlsa.php

@@ -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'],

+ 2 - 0
pg-act/ns/txt.php

@@ -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'],

+ 2 - 0
pg-act/reg/ds.php

@@ -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'],

+ 2 - 0
pg-act/reg/glue.php

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

+ 2 - 0
pg-act/reg/ns.php

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

+ 2 - 0
pg-act/reg/print.php

@@ -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.');

+ 2 - 0
pg-act/reg/transfer.php

@@ -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]);