diff options
author | Lukas Fleischer <lfleischer@archlinux.org> | 2019-09-06 20:34:38 +0200 |
---|---|---|
committer | Lukas Fleischer <lfleischer@archlinux.org> | 2019-10-05 19:44:00 +0200 |
commit | d6ae970785092124adbe48eb9a759c8c804b13a6 (patch) | |
tree | b0845b1633e9228dbbd4fed35169bf990c1e292f | |
parent | a66c7fa6156b9babb81cd6a1143737a2a193634b (diff) | |
download | aur-d6ae970785092124adbe48eb9a759c8c804b13a6.tar.gz aur-d6ae970785092124adbe48eb9a759c8c804b13a6.tar.xz |
Add a simple CAPTCHA to the sign up form
Add a CAPTCHA to protect against automated account creation. The CAPTCHA
changes whenever three new accounts are registered.
Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
-rw-r--r-- | web/html/register.php | 14 | ||||
-rw-r--r-- | web/lib/acctfuncs.inc.php | 74 | ||||
-rw-r--r-- | web/template/account_edit_form.php | 11 |
3 files changed, 95 insertions, 4 deletions
diff --git a/web/html/register.php b/web/html/register.php index 368999a5..a4264829 100644 --- a/web/html/register.php +++ b/web/html/register.php @@ -36,7 +36,12 @@ if (in_request("Action") == "NewAccount") { 0, in_request("CN"), in_request("UN"), - in_request("ON")); + in_request("ON"), + 0, + "", + in_request("captcha_salt"), + in_request("captcha"), + ); print $message; @@ -59,7 +64,12 @@ if (in_request("Action") == "NewAccount") { 0, in_request("CN"), in_request("UN"), - in_request("ON")); + in_request("ON"), + 0, + "", + in_request("captcha_salt"), + in_request("captcha") + ); } } else { print '<p>' . __("Use this form to create an account.") . '</p>'; diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index dc444842..f9378fed 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -62,17 +62,25 @@ function html_format_pgp_fingerprint($fingerprint) { * @param string $ON Whether to notify of ownership changes * @param string $UID The user ID of the displayed user * @param string $N The username as present in the database + * @param string $captcha_salt The salt used for the CAPTCHA. + * @param string $captcha The CAPTCHA answer. * * @return void */ function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R="", - $L="",$TZ="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") { + $L="",$TZ="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="",$captcha_salt="",$captcha="") { global $SUPPORTED_LANGS; if ($TZ == "") { $TZ = config_get("options", "default_timezone"); } + if ($captcha_salt != get_captcha_salt()) { + $captcha_salt = get_captcha_salt(); + $captcha = ""; + } + $captcha_challenge = get_captcha_challenge($captcha_salt); + include("account_edit_form.php"); return; } @@ -103,11 +111,13 @@ function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R="" * @param string $ON Whether to notify of ownership changes * @param string $UID The user ID of the modified account * @param string $N The username as present in the database + * @param string $captcha_salt The salt used for the CAPTCHA. + * @param string $captcha The CAPTCHA answer. * * @return array Boolean indicating success and message to be printed */ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C="", - $R="",$L="",$TZ="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") { + $R="",$L="",$TZ="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="",$captcha_salt="",$captcha="") { global $SUPPORTED_LANGS; $error = ''; @@ -269,6 +279,18 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C="" } } + if (!$error && $TYPE == "new" && empty($captcha)) { + $error = __("The CAPTCHA is missing."); + } + + if (!$error && $TYPE == "new" && $captcha_salt != get_captcha_salt()) { + $error = __("This CAPTCHA has expired. Please try again."); + } + + if (!$error && $TYPE == "new" && $captcha != get_captcha_answer($captcha_salt)) { + $error = __("The entered CAPTCHA answer is invalid."); + } + if ($error) { $message = "<ul class='errorlist'><li>".$error."</li></ul>\n"; return array(false, $message); @@ -1445,3 +1467,51 @@ function account_comments_count($uid) { $result = $dbh->query($q); return $result->fetchColumn(); } + +/* + * Compute the CAPTCHA salt. The salt changes based on the number of registered + * users. This ensures that new users always use a different salt. + * + * @return string The current salt. + */ +function get_captcha_salt() { + $dbh = DB::connect(); + $q = "SELECT count(*) FROM Users"; + $result = $dbh->query($q); + $user_count = $result->fetchColumn(); + return 'aurweb-' . floor($user_count / 3); +} + +/* + * Return the CAPTCHA challenge for a given salt. + * + * @param string $salt The salt to be used for the CAPTCHA computation. + * + * @return string The challenge as a string. + */ +function get_captcha_challenge($salt) { + $token = substr(md5($salt), 0, 3); + return "LC_ALL=C pacman -V|sed -r 's#[0-9]+#" . $token . "#g'|md5sum|cut -c1-6"; +} + +/* + * Compute CAPTCHA answer for a given salt. + * + * @param string $salt The salt to be used for the CAPTCHA computation. + * + * @return string The correct answer as a string. + */ +function get_captcha_answer($salt) { + $token = substr(md5($salt), 0, 3); + $text = <<<EOD + + .--. Pacman v$token.$token.$token - libalpm v$token.$token.$token +/ _.-' .-. .-. .-. Copyright (C) $token-$token Pacman Development Team +\ '-. '-' '-' '-' Copyright (C) $token-$token Judd Vinet + '--' + This program may be freely redistributed under + the terms of the GNU General Public License. + +EOD; + return substr(md5($text . "\n"), 0, 6); +} diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php index 38d5274c..5e84aa71 100644 --- a/web/template/account_edit_form.php +++ b/web/template/account_edit_form.php @@ -174,6 +174,17 @@ </p> </fieldset> + <?php if ($A != "UpdateAccount"): ?> + <fieldset> + <legend><?= __("To protect the AUR against automated account creation, we kindly ask you to provide the output of the following command:") ?> <code><?= htmlspecialchars($captcha_challenge) ?></code></legend> + <p> + <label for="id_captcha"><?= __("Answer") ?>:</label> + <input type="text" size="30" maxlength="6" name="captcha" id="id_captcha" value="<?= htmlspecialchars($captcha, ENT_QUOTES) ?>" /> (<?= __("required") ?>) + <input type="hidden" name="captcha_salt" value="<?= htmlspecialchars($captcha_salt) ?>" /> + </p> + </fieldset> + <?php endif; ?> + <fieldset> <p> <label></label> |