Adding a (specific) captcha to the reg screen Adding a (specific) captcha to the reg screen
 

News:

cpg1.5.48 Security release - upgrade mandatory!
The Coppermine development team is releasing a security update for Coppermine in order to counter a recently discovered vulnerability. It is important that all users who run version cpg1.5.46 or older update to this latest version as soon as possible.
[more]

Main Menu

Adding a (specific) captcha to the reg screen

Started by SpikeTheLobster, August 29, 2012, 03:08:48 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

SpikeTheLobster

Hi folks,

I'm getting a lot of spam registrations on my various Coppermine-based sites and I'd like to switch to a different Captcha system. Since I'm using the one from Solve Media on a WordPress site, that's what I'd like to implement on CPG.

Ideally, I'd like to put this on the disclaimer page, to stop the bots before they even fill in a form.

The setup has two parts: the call and the processing. Solve provides php for both parts which is simple enough but (given my lack of php knowledge), I'm struggling to find where to put the call and check.

The call's two lines - a "requireonce" for the library and an "echo" for the captcha.
The check is a pretty simple "if":

if (!$solvemedia_response->is_valid) {
//handle incorrect answer
print "Error: ".$solvemedia_response->error;
}
else {
//process form here
}


I would really appreciate it if someone could help me out with an idea of where in the register.php file to put the call and check so that it'll work. My apologies if that's too vague or more info is needed: I'm no php pro, though I can read very basic code.

I understand this would no doubt be better as a plugin but that's way above my level.  :'(

Thanks in advance for any help.

SpikeTheLobster

Update:

I've figured out the first part - where to put the captcha display.

In register.php, I added "require_once('include/solvemedialib.php');" at the start, just under "require('include/mailer.inc.php');" (and uploaded the php file to the include folder, of course!).

Then I changed the agreement display from this:

    echo str_replace('{SITE_NAME}', $CONFIG['gallery_name'], $lang_register_php['disclamer']);

    echo <<< EOT
        </td>
    </tr>
    <tr>
        <td colspan="2" align="center" class="tablef">
            <button type="submit" class="button" name="agree" id="agree" value="{$lang_register_php['i_agree']}">{$icon_array['ok']}{$lang_register_php['i_agree']}</button>
        </td>
    </tr>

EOT;


to this:


    echo str_replace('{SITE_NAME}', $CONFIG['gallery_name'], $lang_register_php['disclamer']);

    echo <<< EOT
        </td>
    </tr>
    <tr>
        <td colspan="2" align="left" class="tablef">
EOT;

echo solvemedia_get_html("my-challenge-key-here");

    echo <<< EOT
         </td>
    <tr>
        <td colspan="2" align="left" class="tablef">
            <button type="submit" class="button" name="agree" id="agree" value="{$lang_register_php['i_agree']}">{$icon_array['ok']}{$lang_register_php['i_agree']}</button>
        </td>
    </tr>
EOT;


That gives me the agreement, followed by the Solve Media captcha and an "I agree" button. I also edited the agreement text in lang/english.php to indicate that there's a captcha to complete, just for tidiness.

Now all I need to so is figure out where the bit goes to detect if they entered the captcha properly. Learning curve fun... ;)

Joe Carver

Quote from: SpikeTheLobster on August 29, 2012, 09:29:40 PM
Now all I need to so is figure out where the bit goes to detect if they entered the captcha properly. Learning curve fun... ;)

It is good to hear about someone having fun learning and modifying Coppermine.  :)

Look for the line starting with:
     // check captcha

You could also try looking at the reCaptcha plugin for hints too.
(Looking at the work of others is how I  started to learn)

By the way, reCaptcha stops more than a few registration and comment attempts a day for me.


SpikeTheLobster

Ahh, I hadn't noticed the "captcha code" bit. That's neater than messing with the first page, so I've moved the code there.

Still need to figure the confirmation part but, following on from that pointer, I see there's a "check captcha" bit. If I can figure out how that works, I should be able to set the same variable (assuming that's what it does).

Cool beans, thanks.

SpikeTheLobster

OK, this is driving me a little bit bonzo, here...!

I've got the captcha displaying in the place of the built-in one, no problem. I've adjusted the check part as below:

    // check captcha
    if ($CONFIG['registration_captcha'] != 0) {

require_once("solvemedialib.php");
$privkey="(big long key from Solve account)";
$hashkey="(big long key from Solve account)";
$solvemedia_response = solvemedia_check_answer($privkey,
$_SERVER["REMOTE_ADDR"],
$_POST["adcopy_challenge"],
$_POST["adcopy_response"],
$hashkey);
if (!$solvemedia_response->is_valid) {
//handle incorrect answer
$error .= '<li style="list-style-image:url(images/icons/stop.png)">' . $solvemedia_response->error . '</li>';
}
else {
            $error = CPGPluginAPI::filter('captcha_register_validate', $error);
}   
    }


The site displays the captcha and I can submit my registration details but I just get a blank page with a header, whatever I do. It's driving me nuts. So close and yet so far off...

Can anyone see something obviously amiss?

Joe Carver

With no experience and no time at the moment for Solve Media, the only immediate suggestions are:

Change:
$solvemedia_response->error

To:
($solvemedia_response->error)

And, as a start, see if they have a test script for your to try. That way you can test how your keys work, etc.

SpikeTheLobster

Thanks for the attempt - no luck.

I'm working on a testing site, so it's not a problem. The only help they have is the php code to put in and a description of the function. I'll keep fiddling by putting in straight text to see if that shows me what's going on, etc. :)

Jeff Bailey

Would you be able to give us the actual code Solve Media gives you to put on your site, or would it reveal private account information?

It's kind of hard to find a solution with bits and pieces.
Thinking is the hardest work there is, which is probably the reason why so few engage in it. - Henry Ford

SpikeTheLobster

There isn't actually any more than I've put here, unless you mean the content of the library file. It's designed to be simple but I'm confused because of the combination of their stuff and CPG (and I'm easily confused anyway, when it comes to code!).

Two lines to call the captcha:

require_once("solvemedialib.php");
echo solvemedia_get_html("your_challenge_key");


and the code bit to process it:

require_once("solvemedialib.php");
$privkey="your_private_key";
$hashkey="your_hash_key";
$solvemedia_response = solvemedia_check_answer($privkey,
$_SERVER["REMOTE_ADDR"],
$_POST["adcopy_challenge"],
$_POST["adcopy_response"],
$hashkey);
if (!$solvemedia_response->is_valid) {
//handle incorrect answer
print "Error: ".$solvemedia_response->error;
}
else {
//process form here
}


The only other info is the library itself and the documentation for the class:

Quoteclass SolveMediaResponse
An instance of the SolveMediaResponse class is the returned by solvemedia_check_answer. The attributes of this object indicate whether the user answered correctly.

Attributes:
$solvemedia_response->is_valid   True if the user answered correctly, false if not.
$solvemedia_response->error   If the $is_valid field is false, a short error message from Solve Media explaining why
function solvemedia_get_html
solvemedia_get_html returns the HTML necessary to embed the Solve Media widget into your form.

Parameters:
$pubkey   The public key Solve Media uses to retrieve your puzzle.
$error   An error message given by Solve Media, default is null
$use_ssl   Determines whether the request should be made over ssl, default is false
function solvemedia_check_answer
solvemedia_check_answer performs an HTTP POST to Solve Media's servers to check the veracity of the user's answer.

Parameters:
$privkey   The private verification key (V-Key) used by Solve Media
$remoteip   The IP address of the user
$challenge   The challenge identifier found in the adcopy_challenge field
$response   The user's response to the puzzle
$hashkey   The hash key (H-Key) used by Solve Media to verify the response.

Jeff Bailey

#9
Thank you that's all I wanted to know. Just a little difficult to piece together after reading the thread.
Try this.

Find

    // captcha code
    if ($CONFIG['registration_captcha'] != 0) {
   
        $help = cpg_display_help('f=empty.htm&amp;base=64&amp;h='.urlencode(base64_encode(serialize($lang_common['captcha_help_title']))).'&amp;t='.urlencode(base64_encode(serialize($lang_common['captcha_help']))), 470, 245);

        $captcha_print = <<< EOT
    <tr>
        <td align="right" class="tablef">
            {$lang_common['confirm']}&nbsp;{$help}
        </td>
        <td class="tablef">
            <input type="text" name="confirmCode" id="confirmCode" size="5" maxlength="5" class="textinput" />
            <img src="captcha.php" align="middle" border="0" alt="" />
        </td>
    </tr>
EOT;

        $captcha_print = CPGPluginAPI::filter('captcha_register_print', $captcha_print);
        echo $captcha_print;
    }

Replace with

    // captcha code
    if ($CONFIG['registration_captcha'] != 0) {
    require_once("solvemedialib.php");
    $solvemediahtml = solvemedia_get_html("your_challenge_key");
        $help = cpg_display_help('f=empty.htm&amp;base=64&amp;h='.urlencode(base64_encode(serialize($lang_common['captcha_help_title']))).'&amp;t='.urlencode(base64_encode(serialize($lang_common['captcha_help']))), 470, 245);

        $captcha_print = <<< EOT
    <tr>
        <td align="right" class="tablef">
            {$lang_common['confirm']}&nbsp;{$help}
        </td>
        <td class="tablef">
            {$solvemediahtml}
        </td>
    </tr>
EOT;

        $captcha_print = CPGPluginAPI::filter('captcha_register_print', $captcha_print);
        echo $captcha_print;
    }


Find

    // check captcha
    if ($CONFIG['registration_captcha'] != 0) {
   
        if (!captcha_plugin_enabled()) {
            require("include/captcha.inc.php");
            if (!PhpCaptcha::Validate($captcha_confirmation)) {
                $error .= '<li style="list-style-image:url(images/icons/stop.png)">' . $lang_errors['captcha_error'] . '</li>';
            }
        } else {
            $error = CPGPluginAPI::filter('captcha_register_validate', $error);
        }
    }

Replace with

    // check captcha
    if ($CONFIG['registration_captcha'] != 0) {
require_once("solvemedialib.php");
$privkey="your_private_key";
$hashkey="your_hash_key";
$solvemedia_response = solvemedia_check_answer($privkey,
$superCage->server->getRaw('REMOTE_ADDR'),
$superCage->post->getRaw('adcopy_challenge'),
$superCage->post->getRaw('adcopy_response'),
$hashkey);
if (!$solvemedia_response->is_valid) {
$error .= '<li style="list-style-image:url(images/icons/stop.png)">Error: ' . $solvemedia_response->error . '</li>';
}
    }


I of course have no way to test this, so there is probably something wrong with it.
Thinking is the hardest work there is, which is probably the reason why so few engage in it. - Henry Ford

Joe Carver

Quote from: SpikeTheLobster on August 30, 2012, 11:08:45 PM
...but I'm confused because of the combination of their stuff and CPG (and I'm easily confused anyway, when it comes to code!).

That problem can be broken down:
Try to learn how to create / copy / modify a simple php form. Something that has a submit button that returns / echos "hello" for example.
Next, test that form without the ant-spam code.
Next, add your anti-spam code.
Test it.

There are many great resources (php.net, w3schools.com, etc.) that can help you to learn quite easily.




SpikeTheLobster

@Jeff: Thanks again but no luck - form doesn't even display the captcha and, if I change it back to my code that got it displaying, the same thing happens when captcha entered: header, nothing else. Ah, well. Thanks very much for trying.

@Joe: Frankly (and with no offense intended) I don't have time to learn php from scratch just to make a form work. I'd hoped it would be a simple replace, using what I could figure out from my years-old programming knowledge... but apparently it isn't. I have quite enough on my plate already, so I'll live with the spam.  :-\

Jeff Bailey

What about this?

Add
require('include/solvemedialib.php');
under
require('include/mailer.inc.php');
in register.php

Find

    // captcha code
    if ($CONFIG['registration_captcha'] != 0) {
   
        $help = cpg_display_help('f=empty.htm&amp;base=64&amp;h='.urlencode(base64_encode(serialize($lang_common['captcha_help_title']))).'&amp;t='.urlencode(base64_encode(serialize($lang_common['captcha_help']))), 470, 245);

        $captcha_print = <<< EOT
    <tr>
        <td align="right" class="tablef">
            {$lang_common['confirm']}&nbsp;{$help}
        </td>
        <td class="tablef">
            <input type="text" name="confirmCode" id="confirmCode" size="5" maxlength="5" class="textinput" />
            <img src="captcha.php" align="middle" border="0" alt="" />
        </td>
    </tr>
EOT;

        $captcha_print = CPGPluginAPI::filter('captcha_register_print', $captcha_print);
        echo $captcha_print;
    }

Replace with

    // captcha code
    if ($CONFIG['registration_captcha'] != 0) {
   
        $help = cpg_display_help('f=empty.htm&amp;base=64&amp;h='.urlencode(base64_encode(serialize($lang_common['captcha_help_title']))).'&amp;t='.urlencode(base64_encode(serialize($lang_common['captcha_help']))), 470, 245);
        $solvemediahtml = solvemedia_get_html("your_challenge_key");
        $captcha_print = <<< EOT
    <tr>
        <td align="right" class="tablef">
            {$lang_common['confirm']}&nbsp;{$help}
        </td>
        <td class="tablef">
            {$solvemediahtml}
        </td>
    </tr>
EOT;

        $captcha_print = CPGPluginAPI::filter('captcha_register_print', $captcha_print);
        echo $captcha_print;
    }


Find

    // check captcha
    if ($CONFIG['registration_captcha'] != 0) {
   
        if (!captcha_plugin_enabled()) {
            require("include/captcha.inc.php");
            if (!PhpCaptcha::Validate($captcha_confirmation)) {
                $error .= '<li style="list-style-image:url(images/icons/stop.png)">' . $lang_errors['captcha_error'] . '</li>';
            }
        } else {
            $error = CPGPluginAPI::filter('captcha_register_validate', $error);
        }
    }

Replace with

    // check captcha
    if ($CONFIG['registration_captcha'] != 0) {
   
        if (!captcha_plugin_enabled()) {
            $privkey="your_private_key";
            $hashkey="your_hash_key";
            $solvemedia_response = solvemedia_check_answer($privkey,
                $superCage->server->getRaw('REMOTE_ADDR'),
                $superCage->post->getRaw('adcopy_challenge'),
                $superCage->post->getRaw('adcopy_response'),
                $hashkey);
            if (!$solvemedia_response->is_valid) {
                $error .= '<li style="list-style-image:url(images/icons/stop.png)">Error: ' . $solvemedia_response->error . '</li>';
            }
        } else {
            $error = CPGPluginAPI::filter('captcha_register_validate', $error);
        }
    }

Thinking is the hardest work there is, which is probably the reason why so few engage in it. - Henry Ford

SpikeTheLobster

Oh, you genius, you!  ;D

That did it. Errors aren't as obvious as the normal form ones (there's no background highlight) but they're clear enough and it works, which is absolutely freakin' brilliant. I tested it and got the activation mail, so all is well on the CPG side.

I just need to wait for the Solve dashboard to update to verify that the captcha displays and entries are registering properly but it all looks great. And to be honest, I can't see why their end of things would weird out when it's obviously working as intended on-site.

Thanks everso for not giving up. I really appreciate it.  8)

SpikeTheLobster

Teeny tiny update: yes, the Solve side of things updates. All is well in the best of all possible worlds. Thanks again! :)

Jeff Bailey

Glad it worked for you. Please resolve your thread.
http://forum.coppermine-gallery.net/index.php/topic,55415.msg270616.html#msg270616

If you want I can look into the error message display, but I won't spend the time on it if your happy with it.
Thinking is the hardest work there is, which is probably the reason why so few engage in it. - Henry Ford

SpikeTheLobster

No need for anything more, thanks. You'll be pleased to know that my spam registrations instantly dropped to zero and have remained there. :)