From a3dc72bddb24248fc3b6ec625e907cd8dfd42415 Mon Sep 17 00:00:00 2001 From: h00j Date: Sat, 13 Nov 2021 01:24:34 +0100 Subject: [PATCH] securimage captcha --- composer.json | 3 +- composer.lock | 85 ++++++++++++++++++++++++++++++++------- js/captcha.js | 4 +- post.php | 16 ++++++-- securimage.php | 72 +++++++++++++++++++++++++++++++++ static/clickme.gif | Bin 0 -> 3096 bytes templates/post_form.html | 12 ++++++ 7 files changed, 172 insertions(+), 20 deletions(-) create mode 100644 securimage.php create mode 100644 static/clickme.gif diff --git a/composer.json b/composer.json index e699b250..0ba98be6 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "lifo/ip": "^1.0", "gettext/gettext": "^1.0", "mrclay/minify": "^2.1.6", - "geoip/geoip": "^1.17" + "geoip/geoip": "^1.17", + "dapphp/securimage": "^4.0" }, "autoload": { "classmap": ["inc/"], diff --git a/composer.lock b/composer.lock index 631964dd..3012c9e0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,65 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e78104dfc51d725ae15a17e7a70e7ca3", + "content-hash": "1e3723687369c82eea457d2dded76b74", "packages": [ + { + "name": "dapphp/securimage", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/dapphp/securimage.git", + "reference": "aabde76d839d75a238970661187f83312c2eeda7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dapphp/securimage/zipball/aabde76d839d75a238970661187f83312c2eeda7", + "reference": "aabde76d839d75a238970661187f83312c2eeda7", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "php": ">=5.4" + }, + "suggest": { + "ext-pdo": "For database storage support", + "ext-pdo_mysql": "For MySQL database support", + "ext-pdo_sqlite": "For SQLite3 database support" + }, + "type": "library", + "autoload": { + "classmap": [ + "securimage.php" + ], + "psr-4": { + "Securimage\\": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Drew Phillips", + "email": "drew@drew-phillips.com" + } + ], + "description": "PHP CAPTCHA Library", + "homepage": "https://www.phpcaptcha.org", + "keywords": [ + "Forms", + "anti-spam", + "captcha", + "security" + ], + "support": { + "issues": "https://github.com/dapphp/securimage/issues", + "source": "https://github.com/dapphp/securimage/tree/4.0.2" + }, + "abandoned": true, + "time": "2020-05-30T10:05:48+00:00" + }, { "name": "geoip/geoip", "version": "v1.17", @@ -212,16 +269,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.22.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "shasum": "" }, "require": { @@ -233,7 +290,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -271,7 +328,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" }, "funding": [ { @@ -287,20 +344,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "twig/twig", - "version": "v1.44.2", + "version": "v1.44.5", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "138c493c5b8ee7cff3821f80b8896d371366b5fe" + "reference": "dd4353357c5a116322e92a00d16043a31881a81e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/138c493c5b8ee7cff3821f80b8896d371366b5fe", - "reference": "138c493c5b8ee7cff3821f80b8896d371366b5fe", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/dd4353357c5a116322e92a00d16043a31881a81e", + "reference": "dd4353357c5a116322e92a00d16043a31881a81e", "shasum": "" }, "require": { @@ -353,7 +410,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v1.44.2" + "source": "https://github.com/twigphp/Twig/tree/v1.44.5" }, "funding": [ { @@ -365,7 +422,7 @@ "type": "tidelift" } ], - "time": "2021-01-05T10:10:05+00:00" + "time": "2021-09-17T08:35:19+00:00" } ], "packages-dev": [], diff --git a/js/captcha.js b/js/captcha.js index 018588b7..5e0bcf53 100644 --- a/js/captcha.js +++ b/js/captcha.js @@ -25,7 +25,7 @@ function load_captcha(provider, extra) { $(function() { $(".captcha>td").html(""+ ""+ - "
"); + "
"); $("#quick-reply .captcha .captcha_text").prop("placeholder", _("Verification")); @@ -40,4 +40,4 @@ function load_captcha(provider, extra) { $("#quick-reply .captcha .captcha_html").on("click", function() { actually_load_captcha(provider, extra); }); }); }); -} \ No newline at end of file +} diff --git a/post.php b/post.php index be155e84..9db60af8 100644 --- a/post.php +++ b/post.php @@ -169,6 +169,11 @@ elseif (isset($_GET['Newsgroups'])) { error("NNTPChan: NNTPChan support is disabled"); } +session_start(); +if (!isset($_POST['captcha_cookie']) && isset($_SESSION['captcha_cookie'])) { + $_POST['captcha_cookie'] = $_SESSION['captcha_cookie']; +} + if (isset($_POST['delete'])) { // Delete @@ -298,12 +303,14 @@ if (isset($_POST['delete'])) { } if ($config['report_captcha']) { - $resp = file_get_contents($config['captcha']['provider_check'] . "?" . http_build_query([ + $ch = curl_init($config['domain'].'/'.$config['captcha']['provider_check'] . "?" . http_build_query([ 'mode' => 'check', 'text' => $_POST['captcha_text'], 'extra' => $config['captcha']['extra'], 'cookie' => $_POST['captcha_cookie'] ])); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + $resp = curl_exec($ch); if ($resp !== '1') { error($config['error']['captcha']); @@ -402,20 +409,23 @@ if (isset($_POST['delete'])) { if (!$resp['success']) { error($config['error']['captcha']); } + } // Same, but now with our custom captcha provider if (($config['captcha']['enabled']) || (($post['op']) && ($config['new_thread_capt'])) ) { - $resp = file_get_contents($config['captcha']['provider_check'] . "?" . http_build_query([ + $ch = curl_init($config['domain'].'/'.$config['captcha']['provider_check'] . "?" . http_build_query([ 'mode' => 'check', 'text' => $_POST['captcha_text'], 'extra' => $config['captcha']['extra'], 'cookie' => $_POST['captcha_cookie'] ])); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + $resp = curl_exec($ch); + if ($resp !== '1') { error($config['error']['captcha'] . ''); } } -} if (!(($post['op'] && $_POST['post'] == $config['button_newtopic']) || (!$post['op'] && $_POST['post'] == $config['button_reply']))) diff --git a/securimage.php b/securimage.php new file mode 100644 index 00000000..3e50e02d --- /dev/null +++ b/securimage.php @@ -0,0 +1,72 @@ +execute([time() - $expires_in]); +} + + +$mode = @$_GET['mode']; +switch ($mode) { + case 'get': + if (!isset ($_GET['extra'])) { + $_GET['extra'] = $config['captcha']['extra']; + } + + header("Content-type: application/json"); + $extra = $_GET['extra']; + $cookie = rand_string(20, "abcdefghijklmnopqrstuvwxyz"); + $i = new Securimage(['send_headers' => false, 'no_exit' => true]); + $i->createCode(); + ob_start(); + $i->show(); + $rawimg = ob_get_contents(); + $b64img = 'data:image/png;base64,'.base64_encode($rawimg); + $html = ''; + ob_end_clean(); + $cdata = $i->getCode(); + $query = prepare("INSERT INTO `captchas` (`cookie`, `extra`, `text`, `created_at`) VALUES (?, ?, ?, ?)"); + $query->execute([$cookie, $extra, $cdata->code_display, $cdata->creationTime]); + if (isset($_GET['raw'])) { + $_SESSION['captcha_cookie'] = $cookie; + header('Content-Type: image/png'); + echo $rawimg; + } else { + echo json_encode(["cookie" => $cookie, "captchahtml" => $html, "expires_in" => $expires_in]); + } + break; + case 'check': + cleanup(); + if (!isset ($_GET['mode']) || !isset ($_GET['cookie']) || !isset ($_GET['extra']) || !isset ($_GET['text'])) { + die(); + } + + $query = prepare("SELECT * FROM `captchas` WHERE `cookie` = ? AND `extra` = ?"); + $query->execute([$_GET['cookie'], $_GET['extra']]); + + $ary = $query->fetchAll(); + + if (!$ary) { + echo "0"; + } else { + $query = prepare("DELETE FROM `captchas` WHERE `cookie` = ? AND `extra` = ?"); + $query->execute([$_GET['cookie'], $_GET['extra']]); + } + + if ($ary[0]['text'] !== $_GET['text']) { + echo "0"; + } else { + echo "1"; + } + break; +} diff --git a/static/clickme.gif b/static/clickme.gif new file mode 100644 index 0000000000000000000000000000000000000000..d408bc869936879584d5e5198f68cca268af2d32 GIT binary patch literal 3096 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 literal 0 HcmV?d00001 diff --git a/templates/post_form.html b/templates/post_form.html index 6facf749..e6d77314 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -86,6 +86,12 @@ + {% elseif config.new_thread_capt %} @@ -96,6 +102,12 @@ + {% endif %}