From dbfb58a502c9ac8bf7e0fab71a38b2b00aacb31d Mon Sep 17 00:00:00 2001 From: Marius Lindvall Date: Mon, 9 Dec 2019 00:00:54 +0100 Subject: [PATCH] Add different link styles; fixes #73 --- backend-php/include/config-sample.php | 45 ++++++++++++++ backend-php/include/inc.php | 85 ++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 2 deletions(-) diff --git a/backend-php/include/config-sample.php b/backend-php/include/config-sample.php index ca09537..104a151 100644 --- a/backend-php/include/config-sample.php +++ b/backend-php/include/config-sample.php @@ -132,6 +132,51 @@ // not be honored. "reserve_whitelist" => false, +// The type of links to generate when making new links for shares. Can be any +// of the following: +// +// | Link style | Example | No. of combinations | Avg. bruteforce time | +// +----------------------------+---------------------------------------+-----------------------+-------------------------------+ +// | LINK_4_PLUS_4_UPPER_CASE | EIRG-0CYE | 2.82 * 10^12 (36^8) | 44.7 years | +// | LINK_4_PLUS_4_LOWER_CASE | qae3-ulna | 2.82 * 10^12 (36^8) | 44.7 years | +// | LINK_4_PLUS_4_MIXED_CASE | WRho-uHLG | 1.68 * 10^14 (60^8) | 2663 years | +// | LINK_UUID_V4 | 09c8a3b1-e78f-48b1-a604-0da49e99cb5d | 5.32 * 10^36 (2^122) | 84.2 septillion years | +// | LINK_16_HEX | 6cde14c4c6551b41 | 1.84 * 10^19 (2^64) | 292 million years | +// | LINK_16_UPPER_CASE | 49OFGRK6SGPU93KV | 7.95 * 10^24 (36^16) | 126 trillion years | +// | LINK_16_LOWER_CASE | bdyslxszs14cj359 | 7.95 * 10^24 (36^16) | 126 trillion years | +// | LINK_16_MIXED_CASE | NTHX2HDsTn0kS3aj | 2.82 * 10^28 (60^16) | 447 quadrillion years | +// | LINK_32_HEX | 22adf21f11491ae8f3ae128e23a6782f | 3.40 * 10^38 (2^128) | 5.39 octillion years | +// | LINK_32_UPPER_CASE | MG42MW2DKIMHM87B4AO0WAB2PIY26TR1 | 6.33 * 10^49 (36^32) | 1 duodecillion years | +// | LINK_32_LOWER_CASE | itgbolrbq1c02eot5o46c5wixhdrdb5m | 6.33 * 10^49 (36^32) | 1 duodecillion years | +// | LINK_32_MIXED_CASE | cTK82MJ7rUOP138WNVznQR0Ck3BwZp6b | 7.96 * 10^57 (60^32) | 12.6 quattuordecillion years | +// +// For any MIXED_CASE variants, upper-case I and lower-case L will not appear +// because they are visually very similar and are easily confused. +// +// The default value is LINK_4_PLUS_4_UPPER_CASE, which is still considered very +// secure. The bruteforce times in the table below are the average time it would +// take to find a valid sharing link, when there is one link active, at 1000 +// guesses per second. For the default setting, this means it would take almost +// 45 years to find the link. +// +// This is assuming that the link is active 24/7 for that entire time. If you +// only have a link active 2% of the time, it would take over 2200 years. +// +// At 1000 guesses per second, you will likely notice that your server is +// noticeably slower and rapidly filling up with access logs. +// +// Very long links are also time-consuming to type, should you find yourself +// in need of typing in a link manually on another computer. This is the reason +// that short links are default. +// +// ---- PLEASE NOTE ---- +// This option is provided to you only because several people have requested it +// as a convenience. You are free to change it, but you should know that +// changing the default here gives you, for all intents and purposes, no +// security advantage in practice. +// +"link_style" => LINK_4_PLUS_4_UPPER_CASE, + // Leaflet tile URI template for the map frontend. Here are some examples: // // - OpenStreetMap directly: diff --git a/backend-php/include/inc.php b/backend-php/include/inc.php index 308ef7c..8ef49e5 100644 --- a/backend-php/include/inc.php +++ b/backend-php/include/inc.php @@ -29,6 +29,20 @@ const REDIS = 1; const PASSWORD = 0; const HTPASSWD = 1; +// Share link types. +const LINK_4_PLUS_4_UPPER_CASE = 0; +const LINK_4_PLUS_4_LOWER_CASE = 1; +const LINK_4_PLUS_4_MIXED_CASE = 2; +const LINK_UUID_V4 = 3; +const LINK_16_HEX = 4; +const LINK_16_UPPER_CASE = 5; +const LINK_16_LOWER_CASE = 6; +const LINK_16_MIXED_CASE = 7; +const LINK_32_HEX = 8; +const LINK_32_UPPER_CASE = 9; +const LINK_32_LOWER_CASE = 10; +const LINK_32_MIXED_CASE = 11; + const KILOMETERS_PER_HOUR = array( // Relative distance per second multiplied by number of seconds per hour. "mpsMultiplier" => 3.6, @@ -114,6 +128,7 @@ const DEFAULTS = array( "allow_link_req" => true, "reserved_links" => [], "reserve_whitelist" => false, + "link_style" => LINK_4_PLUS_4_UPPER_CASE, "map_tile_uri" => 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', "map_attribution" => 'Map data © OpenStreetMap contributors, CC-BY-SA', "default_zoom" => 14, @@ -300,8 +315,74 @@ class Share { protected function generateLinkID() { $s = ""; do { - $s = strtoupper(base_convert(hash("sha256", openssl_random_pseudo_bytes(LINK_ID_RAND_BYTES)), 16, 36)); - $s = substr($s, 0, 4)."-".substr($s, -4); + switch (getConfig("link_style")) { + case LINK_UUID_V4: + // UUID version 4. + $uuid = openssl_random_pseudo_bytes(16); + $uuid[6] = chr(ord($uuid[6]) & 0x0f | 0x40); + $uuid[8] = chr(ord($uuid[8]) & 0x3f | 0x80); + $s = vsprintf("%s%s-%s-%s-%s-%s%s%s", str_split(bin2hex($uuid), 4)); + break; + case LINK_16_HEX: + // 16-char (8-byte) hexadecimal string. + $s = bin2hex(openssl_random_pseudo_bytes(8)); + break; + case LINK_16_LOWER_CASE: + // 16-char lower-case alphanumeric string. + $alpha = "0123456789abcdefghijklmnopqrstuvwxyz"; + for ($i = 0; $i < 16; $i++) $s .= $alpha[random_int(0, strlen($alpha)-1)]; + break; + case LINK_16_MIXED_CASE: + // 16-char mixed-case alphanumeric string. + $alpha = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + for ($i = 0; $i < 16; $i++) $s .= $alpha[random_int(0, strlen($alpha)-1)]; + break; + case LINK_16_UPPER_CASE: + // 16-char upper-case alphanumeric string. + $alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + for ($i = 0; $i < 16; $i++) $s .= $alpha[random_int(0, strlen($alpha)-1)]; + break; + case LINK_32_HEX: + // 32-char (16-byte) hexadecimal string. + $s = bin2hex(openssl_random_pseudo_bytes(16)); + break; + case LINK_32_LOWER_CASE: + // 32-char lower-case alphanumeric string. + $alpha = "0123456789abcdefghijklmnopqrstuvwxyz"; + for ($i = 0; $i < 32; $i++) $s .= $alpha[random_int(0, strlen($alpha)-1)]; + break; + case LINK_32_MIXED_CASE: + // 32-char mixed-case alphanumeric string. + // 'l' and 'I' not included because of visual similarity. + $alpha = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + for ($i = 0; $i < 32; $i++) $s .= $alpha[random_int(0, strlen($alpha)-1)]; + break; + case LINK_32_UPPER_CASE: + // 32-char upper-case alphanumeric string. + $alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + for ($i = 0; $i < 32; $i++) $s .= $alpha[random_int(0, strlen($alpha)-1)]; + break; + case LINK_4_PLUS_4_LOWER_CASE: + // 4+4-char lower-case alphanumeric string. + $alpha = "0123456789abcdefghijklmnopqrstuvwxyz"; + for ($i = 0; $i < 8; $i++) $s .= $alpha[random_int(0, strlen($alpha)-1)]; + $s = substr($s, 0, 4)."-".substr($s, -4); + break; + case LINK_4_PLUS_4_MIXED_CASE: + // 4+4-char mixed-case alphanumeric string. + // 'l' and 'I' not included because of visual similarity. + $alpha = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + for ($i = 0; $i < 8; $i++) $s .= $alpha[random_int(0, strlen($alpha)-1)]; + $s = substr($s, 0, 4)."-".substr($s, -4); + break; + case LINK_4_PLUS_4_UPPER_CASE: + default: + // 4+4-char upper-case alphanumeric string. + $alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + for ($i = 0; $i < 8; $i++) $s .= $alpha[random_int(0, strlen($alpha)-1)]; + $s = substr($s, 0, 4)."-".substr($s, -4); + break; + } } while ($this->memcache->get(PREFIX_LOCDATA.$s) !== false); return $s; }