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 %}