Browse Source

securimage captcha

main
h00j 2 years ago
parent
commit
a3dc72bddb
  1. 3
      composer.json
  2. 85
      composer.lock
  3. 4
      js/captcha.js
  4. 16
      post.php
  5. 72
      securimage.php
  6. BIN
      static/clickme.gif
  7. 12
      templates/post_form.html

3
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/"],

85
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": "[email protected]"
}
],
"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": [],

4
js/captcha.js

@ -25,7 +25,7 @@ function load_captcha(provider, extra) {
$(function() {
$(".captcha>td").html("<input class='captcha_text' type='text' name='captcha_text' size='32' maxlength='6' autocomplete='off'>"+
"<input class='captcha_cookie' name='captcha_cookie' type='hidden'>"+
"<div class='captcha_html'></div>");
"<div class='captcha_html'><img src='/static/clickme.gif'></div>");
$("#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); });
});
});
}
}

16
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'] .
'<script>if (actually_load_captcha !== undefined) actually_load_captcha("'.$config['captcha']['provider_get'].'", "'.$config['captcha']['extra'].'");</script>');
}
}
}
if (!(($post['op'] && $_POST['post'] == $config['button_newtopic']) ||
(!$post['op'] && $_POST['post'] == $config['button_reply'])))

72
securimage.php

@ -0,0 +1,72 @@
<?php
require_once('inc/bootstrap.php');
$expires_in = 120;
function rand_string($length, $charset) {
$ret = "";
while ($length--) {
$ret .= mb_substr($charset, rand(0, mb_strlen($charset, 'utf-8')-1), 1, 'utf-8');
}
return $ret;
}
function cleanup() {
global $expires_in;
prepare("DELETE FROM `captchas` WHERE `created_at` < ?")->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 = '<img src="'.$b64img.'">';
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;
}

BIN
static/clickme.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

12
templates/post_form.html

@ -86,6 +86,12 @@
</th>
<td>
<script>load_captcha("{{ config.captcha.provider_get }}", "{{ config.captcha.extra }}");</script>
<noscript>
<input class='captcha_text' type='text' name='captcha_text' size='32' maxlength='6' autocomplete='off'>
<div class="captcha_html">
<img src="/{{ config.captcha.provider_get }}?mode=get&raw=1">
</div>
</noscript>
</td>
</tr>
{% elseif config.new_thread_capt %}
@ -96,6 +102,12 @@
</th>
<td>
<script>load_captcha("{{ config.captcha.provider_get }}", "{{ config.captcha.extra }}");</script>
<noscript>
<input class='captcha_text' type='text' name='captcha_text' size='32' maxlength='6' autocomplete='off'>
<div class="captcha_html">
<img src="/{{ config.captcha.provider_get }}?mode=get&raw=1">
</div>
</noscript>
</td>
</tr>
{% endif %}

Loading…
Cancel
Save