WEBSITE: App submit form reCapatcha Patch
[email protected] (Paul) Sat, 10 Jul 2010 21:34:32 +0100
| Newsgroups | php.gtk.dev |
|---|---|
| Organization | Original Webware Ltd |
| Message-ID | <1278794072.24693.22.camel@paul-laptop> |
Hiya, noticed a sign when trying to add a php-gtk application saying the form was down untill it was protected from spammers, so heres a patch that adds the reCapatcha service. the only thing that needs tobe done is to add a private and public key from google to include/apps.inc which can be done using a google account here: https://www.google.com/recaptcha/admin/create also made very slight change to remove register_globals usage from the app adding part with really basic mysql query string sanitising (an improvement but not compleate) hope the patch is ok -- Paul Lashbrook Systems Architect Original Webware Limited Freephone : 0800 5200 560 T : +44 (0)1884 30 80 20 F : +44 (0)1884 30 80 21 Skype : paul.lashbrook Follow Me on twitter! - http://twitter.com/paullashbrook Follow Original Webware on twitter! - http://twitter.com/owltd Original Webware Limited is Registered in England no 6681968. Registered Office: Unit 9 Langlands Business Park, Uffculme, Devon, EX15 3DA
recapacthaAddAppForm
(text/x-patch, 15.7 KB)
Index: apps/form.php
===================================================================
--- apps/form.php (revision 297709)
+++ apps/form.php (working copy)
@@ -9,9 +9,9 @@
// $form_submit - what the submit button should say
//
-print('The submission form has been turned off until we modify the form to prevent spammers.');
+//print('The submission form has been turned off until we modify the form to prevent spammers.');
-/*
+
?>
<script language='JavaScript'>
<!--
@@ -119,8 +119,14 @@
<td align=right nowrap>Screen Shot:</td>
<td><input type=file name='screenshot'><br><small>(JPEG or PNG only, please)</small></td>
</tr>
-<?php } ?>
+<?php }
+
+
+?>
+
+<tr><td align=right nowrap colspan=2><? echo $capatcha_html; ?></td></tr>
<tr valign=top>
+
<td align=right nowrap colspan=2>
<input type=reset value='Reset'>
<input type=submit value='<?php print($form_submit) ?>'>
@@ -129,5 +135,6 @@
</table>
</form>
<?
+
/* */
?>
Index: apps/add.php
===================================================================
--- apps/add.php (revision 297709)
+++ apps/add.php (working copy)
@@ -5,21 +5,41 @@
//
require_once("apps.inc");
+require_once("recapatchalib.php");
+$capatcha = new recapatcha();
commonHeader('Add an Application', false);
appHeader();
print("<h1>Add a PHPGTK Application</h1>");
+# was there a reCAPTCHA response?
+ if ($_POST['recaptcha_response_field']) {
+ $resp = $capatcha->recaptcha_check_answer ( $recapatcha_privatekey, $_SERVER ["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST['recaptcha_response_field'] );
+
+ if ($resp->is_valid) {
+ $cap_error = false;
+ } else {
+ # set the error code so that we can display it
+ $cap_error = $resp->error;
+ }
+ }else{
+ $cap_error = true;
+ }
+
//
// if the form was submitted add it to the databas
//
-if( $action == "add" ) {
+if(isset( $_POST['action']) && $cap_error === false && $_POST['action'] == "add" ) {
-/*
- if( !empty($_FILES[screenshot][name])
- && ereg("^image/", $_FILES[screenshot][type])
- && !ereg("gif", $_FILES[screenshot][type])
+
+
+
+
+
+ if( !empty($_FILES['screenshot']['name'])
+ && ereg("^image/", $_FILES['screenshot']['type'])
+ && !ereg("gif", $_FILES['screenshot']['type'])
) {
$has_screenshot = 'Y';
}else {
@@ -27,11 +47,18 @@
}
+$cat_id = mysql_real_escape_string($_POST['cat_id']);
+$name = mysql_real_escape_string($_POST['name']);
+$has_screenshot = mysql_real_escape_string($_POST['has_screenshot']);
+$homepage_url = mysql_real_escape_string($_POST['homepage_url'] );
+$submitter = mysql_real_escape_string($_POST['submitter']);
+$blurb = mysql_real_escape_string($_POST['blurb']);
+
$res = mysql_query("
INSERT INTO app
- (id, status, cat_id, date_added, name, has_screenshot, homepage_url, submitter, blurb)
+ (status, cat_id, date_added, name, has_screenshot, homepage_url, submitter, blurb)
VALUES
- (0, 'P', $cat_id, NOW(), '$name', '$has_screenshot', '$homepage_url', '$submitter', '$blurb')
+ ( 'P', $cat_id, NOW(), '$name', '$has_screenshot', '$homepage_url', '$submitter', '$blurb')
");
if( $res == true ) {
@@ -41,10 +68,12 @@
if( $has_screenshot == 'Y' ) {
$app_id = mysql_insert_id();
- handleAppImage($_FILES[screenshot][tmp_name], $app_id);
+ handleAppImage($_FILES['screenshot']['tmp_name'], $app_id);
- $screen_shot_link = "Screenshot : http://$_SERVER[SERVER_NAME]/apps/screenshot.php/$app_id.jpg\n";
+ $screen_shot_link = "Screenshot : http://{$_SERVER['SERVER_NAME']}/apps/screenshot.php/$app_id.jpg\n";
+ }else{
+ $screen_shot_link = 'N/A';
}
mail($mailto, "app '$name' submitted for approval.",
@@ -58,10 +87,10 @@
"\n" .
"Administrative Actions\n" .
"----------------------\n" .
- "Approve: http://$_SERVER[SERVER_NAME]/apps/admin-apps.php?action=approve&app_id=$app_id\n" .
- "Edit: http://$_SERVER[SERVER_NAME]/apps/admin-apps.php?action=edit&app_id=$app_id\n" .
- "Reject: http://$_SERVER[SERVER_NAME]/apps/admin-apps.php?action=reject&app_id=$app_id\n" .
- "Delete: http://$_SERVER[SERVER_NAME]/apps/admin-apps.php?action=delete&app_id=$app_id\n" .
+ "Approve: http://{$_SERVER['SERVER_NAME']}/apps/admin-apps.php?action=approve&app_id=$app_id\n" .
+ "Edit: http://{$_SERVER['SERVER_NAME']}/apps/admin-apps.php?action=edit&app_id=$app_id\n" .
+ "Reject: http://{$_SERVER['SERVER_NAME']}/apps/admin-apps.php?action=reject&app_id=$app_id\n" .
+ "Delete: http://{$_SERVER['SERVER_NAME']}/apps/admin-apps.php?action=delete&app_id=$app_id\n" .
"",
"From: $mailto");
@@ -71,9 +100,13 @@
print("<br>");
print("Error: (" . mysql_errno() . ") " . mysql_error() );
}
-*/
- print('Submissions have been disabled until the form is safe from spammers.');
+
+ // print('Submissions have been disabled until the form is safe from spammers.');
}else {
+
+ $capatcha_html = $capatcha->recaptcha_get_html ( $recapatcha_publickey, $cap_error );
+
+
$form_app = (object) 0;
if( !empty($cat_id) ) {
$form_app->cat_id = $cat_id;
Index: include/recapatchalib.php
===================================================================
--- include/recapatchalib.php (revision 0)
+++ include/recapatchalib.php (revision 0)
@@ -0,0 +1,263 @@
+<?php
+/*
+ * This is a PHP library that handles calling reCAPTCHA.
+ * - Documentation and latest version
+ * http://recaptcha.net/plugins/php/
+ * - Get a reCAPTCHA API Key
+ * https://www.google.com/recaptcha/admin/create
+ * - Discussion group
+ * http://groups.google.com/group/recaptcha
+ *
+ * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
+ * AUTHORS:
+ * Mike Crawford
+ * Ben Maurer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * The reCAPTCHA server URL's
+ */
+define ( "RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api" );
+define ( "RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api" );
+define ( "RECAPTCHA_VERIFY_SERVER", "www.google.com" );
+
+
+class recapatcha {
+
+ /**
+ * Encodes the given data into a query string format
+ * @param $data - array of string elements to be encoded
+ * @return string - encoded request
+ */
+ function _recaptcha_qsencode($data) {
+ $req = "";
+ foreach ( $data as $key => $value )
+ $req .= $key . '=' . urlencode ( stripslashes ( $value ) ) . '&';
+
+ // Cut the last '&'
+ $req = substr ( $req, 0, strlen ( $req ) - 1 );
+ return $req;
+ }
+
+ /**
+ * Submits an HTTP POST to a reCAPTCHA server
+ * @param string $host
+ * @param string $path
+ * @param array $data
+ * @param int port
+ * @return array response
+ */
+ function _recaptcha_http_post($host, $path, $data, $port = 80) {
+
+ $req = self::_recaptcha_qsencode ( $data );
+
+ $http_request = "POST $path HTTP/1.0\r\n";
+ $http_request .= "Host: $host\r\n";
+ $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
+ $http_request .= "Content-Length: " . strlen ( $req ) . "\r\n";
+ $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
+ $http_request .= "\r\n";
+ $http_request .= $req;
+
+ $response = '';
+ if (false == ($fs = @fsockopen ( $host, $port, $errno, $errstr, 10 ))) {
+ die ( 'Could not open socket' );
+ }
+
+ fwrite ( $fs, $http_request );
+
+ while ( ! feof ( $fs ) )
+ $response .= fgets ( $fs, 1160 ); // One TCP-IP packet
+ fclose ( $fs );
+ $response = explode ( "\r\n\r\n", $response, 2 );
+
+ return $response;
+ }
+
+ /**
+ * Gets the challenge HTML (javascript and non-javascript version).
+ * This is called from the browser, and the resulting reCAPTCHA HTML widget
+ * is embedded within the HTML form it was called from.
+ * @param string $pubkey A public key for reCAPTCHA
+ * @param string $error The error given by reCAPTCHA (optional, default is null)
+ * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)
+
+ * @return string - The HTML to be embedded in the user's form.
+ */
+ function recaptcha_get_html($pubkey, $error = null, $use_ssl = false) {
+ if ($pubkey == null || $pubkey == '') {
+ die ( "To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>" );
+ }
+
+ if ($use_ssl) {
+ $server = RECAPTCHA_API_SECURE_SERVER;
+ } else {
+ $server = RECAPTCHA_API_SERVER;
+ }
+
+ $errorpart = "";
+ if ($error) {
+ $errorpart = "&error=" . $error;
+ }
+ return '<script type="text/javascript" src="' . $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>
+
+ <noscript>
+ <iframe src="' . $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
+ <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
+ <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
+ </noscript>';
+ }
+
+ /**
+ * Calls an HTTP POST function to verify if the user's guess was correct
+ * @param string $privkey
+ * @param string $remoteip
+ * @param string $challenge
+ * @param string $response
+ * @param array $extra_params an array of extra variables to post to the server
+ * @return ReCaptchaResponse
+ */
+ function recaptcha_check_answer($privkey, $remoteip, $challenge, $response, $extra_params = array()) {
+ if ($privkey == null || $privkey == '') {
+ die ( "To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>" );
+ }
+
+ if ($remoteip == null || $remoteip == '') {
+ die ( "For security reasons, you must pass the remote ip to reCAPTCHA" );
+ }
+
+ //discard spam submissions
+ if ($challenge == null || strlen ( $challenge ) == 0 || $response == null || strlen ( $response ) == 0) {
+ $recaptcha_response = new ReCaptchaResponse ();
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = 'incorrect-captcha-sol';
+ return $recaptcha_response;
+ }
+
+ $response = self::_recaptcha_http_post ( RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", array (
+ 'privatekey' => $privkey,
+ 'remoteip' => $remoteip,
+ 'challenge' => $challenge,
+ 'response' => $response ) + $extra_params );
+
+ $answers = explode ( "\n", $response [1] );
+ $recaptcha_response = new ReCaptchaResponse ();
+
+ if (trim ( $answers [0] ) == 'true') {
+ $recaptcha_response->is_valid = true;
+ } else {
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = $answers [1];
+ }
+ return $recaptcha_response;
+
+ }
+
+ /**
+ * gets a URL where the user can sign up for reCAPTCHA. If your application
+ * has a configuration page where you enter a key, you should provide a link
+ * using this function.
+ * @param string $domain The domain where the page is hosted
+ * @param string $appname The name of your application
+ */
+ function recaptcha_get_signup_url($domain = null, $appname = null) {
+ return "https://www.google.com/recaptcha/admin/create?" . self::_recaptcha_qsencode ( array (
+ 'domains' => $domain,
+ 'app' => $appname ) );
+ }
+
+ function _recaptcha_aes_pad($val) {
+ $block_size = 16;
+ $numpad = $block_size - (strlen ( $val ) % $block_size);
+ return str_pad ( $val, strlen ( $val ) + $numpad, chr ( $numpad ) );
+ }
+
+ /* Mailhide related code */
+
+ function _recaptcha_aes_encrypt($val, $ky) {
+ if (! function_exists ( "mcrypt_encrypt" )) {
+ die ( "To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed." );
+ }
+ $mode = MCRYPT_MODE_CBC;
+ $enc = MCRYPT_RIJNDAEL_128;
+ $val = self::_recaptcha_aes_pad ( $val );
+ return mcrypt_encrypt ( $enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" );
+ }
+
+ function _recaptcha_mailhide_urlbase64($x) {
+ return strtr ( base64_encode ( $x ), '+/', '-_' );
+ }
+
+ /* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
+ function recaptcha_mailhide_url($pubkey, $privkey, $email) {
+ if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
+ die ( "To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . "you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>" );
+ }
+
+ $ky = pack ( 'H*', $privkey );
+ $cryptmail = self::_recaptcha_aes_encrypt ( $email, $ky );
+
+ return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . self::_recaptcha_mailhide_urlbase64 ( $cryptmail );
+ }
+
+ /**
+ * gets the parts of the email to expose to the user.
+ * eg, given johndoe@example,com return ["john", "example.com"].
+ * the email is then displayed as [email protected]
+ */
+ function _recaptcha_mailhide_email_parts($email) {
+ $arr = preg_split ( "/@/", $email );
+
+ if (strlen ( $arr [0] ) <= 4) {
+ $arr [0] = substr ( $arr [0], 0, 1 );
+ } else if (strlen ( $arr [0] ) <= 6) {
+ $arr [0] = substr ( $arr [0], 0, 3 );
+ } else {
+ $arr [0] = substr ( $arr [0], 0, 4 );
+ }
+ return $arr;
+ }
+
+ /**
+ * Gets html to display an email address given a public an private key.
+ * to get a key, go to:
+ *
+ * http://www.google.com/recaptcha/mailhide/apikey
+ */
+ function recaptcha_mailhide_html($pubkey, $privkey, $email) {
+ $emailparts = self::_recaptcha_mailhide_email_parts ( $email );
+ $url = self::recaptcha_mailhide_url ( $pubkey, $privkey, $email );
+
+ return htmlentities ( $emailparts [0] ) . "<a href='" . htmlentities ( $url ) . "' onclick=\"window.open('" . htmlentities ( $url ) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ( $emailparts [1] );
+
+ }
+
+}
+/**
+ * A ReCaptchaResponse is returned from recaptcha_check_answer()
+ */
+class ReCaptchaResponse {
+ var $is_valid;
+ var $error;
+}
+
+?>
+
Index: include/apps.inc
===================================================================
--- include/apps.inc (revision 297709)
+++ include/apps.inc (working copy)
@@ -13,6 +13,10 @@
//$mailto = '[email protected]';
+// recapacha keys
+$recapatcha_publickey = "ENTER_THE_KEY_PROVIDED_BY_www.google.com/recaptcha";
+$recapatcha_privatekey = "ENTER_THE_KEY_PROVIDED_BY_www.google.com/recaptcha";
+
//
// this directory must exist and must be writable by the user the webserver runs as
//
signature.asc
(application/pgp-signature, 836 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQIcBAABAgAGBQJMONlSAAoJEL2ZvilcQTG0uYkP/RiYoOiYzu67GiDqfd5Pjr9b fvG/5YiEGYNC69hiUvtusbLygevocs0LFKuC2G8N5mqF4vMf5Gpom5062X0UmVW+ /cKngPze+OR+bN75RwKvU1MNEWLfVmMAYVc5+BEma/JdJZCz3rBW77q7neHhR+eR Ukc6ok+XWoh86rCC/GPGXYbGCVEUSoRDLm7/XcuD0kX3UzRT391Z51tHQoJNE47f U0IpCTyZxFHY7QcVDXTD3U1LXyBD3e4Reou8BmhrpOLc+vQYB2wmow99iMnUjjlp g17zYoYsZmLeSCDDAo7xPo+9HqS8YbxXbueDA4gUBaVsxRBgrGdSIkH6hlqFEx1k rmcD2s+Dk3YQEbkPwsJ6IDrTEIGpM74DzBq8+Hv7vC1s2sBubtsIBDKIhZYKR5Ry p4p5PQvXI93AMDBK7QDhF0mgWLUz0ejujGTv5kJBKYwnBnIAI/MkTDlujw/HUq51 RmjcJ7poFkkaXq9trFBDz+jPXWY7tH1ENcxEEH2EcgM6SdeoICHHCHDJ493qzFmu I0Rq8M5w/9N/3wHsdGLM2GEOOSrOXtUwSjfKKySMYlTsxeE92cGR/DpcZEiJCbxF 12a/JUOlURnzW4KMfURLM+A9B0F0nKxex4grKfVCQedAV9N8u+tsTUdPAqyE9Lgm NAFVENKiOF8Rtw6VBoBZ =U6+r -----END PGP SIGNATURE-----