為什麼我加了驗證碼,別人還是可以刷票呢?

來源:互聯網
上載者:User
為什麼我加了驗證碼,別人還是可以刷票呢?下面是擷取驗證碼的代碼,是不是驗證碼太簡單了,應該怎麼弄複雜一點?

/**
* 驗證碼圖片類
*/

if (!defined('IN_FDYU'))
{
die('Hacking attempt');
}

class captcha
{
/**
* 背景圖片所在目錄
*
* @var string $folder
*/

//var $folder = ROOT_PATH . 'includes/captcha/';

var $folder = '';

/**
* 圖片的檔案類型
*
* @var string $img_type
*/
var $img_type = 'png';

/*------------------------------------------------------ */
//-- 存在session中的名稱
/*------------------------------------------------------ */
var $session_word = 'captcha_word';

/**
* 背景圖片以及背景顏色
*
* 0 => 背景圖片的檔案名稱
* 1 => Red, 2 => Green, 3 => Blue
* @var array $themes
*/
var $themes_jpg = array(
1 => array('captcha_bg1.jpg', 255, 255, 255),
2 => array('captcha_bg2.jpg', 0, 0, 0),
3 => array('captcha_bg3.jpg', 0, 0, 0),
4 => array('captcha_bg4.jpg', 255, 255, 255),
5 => array('captcha_bg5.jpg', 255, 255, 255),
);

var $themes_gif = array(
1 => array('captcha_bg1.gif', 255, 255, 255),
2 => array('captcha_bg2.gif', 0, 0, 0),
3 => array('captcha_bg3.gif', 0, 0, 0),
4 => array('captcha_bg4.gif', 255, 255, 255),
5 => array('captcha_bg5.gif', 255, 255, 255),
);

/**
* 圖片的寬度
*
* @var integer $width
*/
var $width = 38;

/**
* 圖片的高度
*
* @var integer $height
*/
var $height = 16;

/**
* 建構函式
*
* @access public
* @param
*
* @return void
*/
function __construct($folder = '', $width = 38, $height = 16)
{
$this->captcha($folder, $width, $height);
}

/**
* 建構函式
*
* @access public
* @param string $folder 背景圖片所在目錄
* @param integer $width 圖片寬度
* @param integer $height 圖片高度
* @return bool
*/
function captcha($folder = '', $width = 38, $height = 16)
{
$folder = ROOT_PATH . 'includes/captcha/';

if (!empty($folder))
{
$this->folder = $folder;
}

$this->width = $width;
$this->height = $height;

/* 檢查是否支援 GD */
if (PHP_VERSION >= '4.3')
{

return (function_exists('imagecreatetruecolor') || function_exists('imagecreate'));
}
else
{

return (((imagetypes() & IMG_GIF) > 0) || ((imagetypes() & IMG_JPG)) > 0 );
}
}




/**
* 檢查給出的驗證碼是否和session中的一致
*
* @access public
* @param string $word 驗證碼
* @return bool
*/
function check_word($word)
{
$recorded = isset($_SESSION[$this->session_word]) ? base64_decode($_SESSION[$this->session_word]) : '';
$given = $this->encrypts_word(strtoupper($word));

return (preg_match("/$given/", $recorded));
}

/**
* 產生圖片並輸出到瀏覽器
*
* @access public
* @param string $word 驗證碼
* @return mix
*/
function generate_image($word = false)
{
if (!$word)
{
$word = $this->generate_word();
}

/* 記錄驗證碼到session */
$this->record_word($word);

/* 驗證碼長度 */
$letters = strlen($word);

/* 選擇一個隨機的方案 */
mt_srand((double) microtime() * 1000000);

if (function_exists('imagecreatefromjpeg') && ((imagetypes() & IMG_JPG) > 0))
{
$theme = $this->themes_jpg[mt_rand(1, count($this->themes_jpg))];
}
else
{
$theme = $this->themes_gif[mt_rand(1, count($this->themes_gif))];
}

if (!file_exists($this->folder . $theme[0]))
{
return false;
}
else
{
$img_bg = (function_exists('imagecreatefromjpeg') && ((imagetypes() & IMG_JPG) > 0)) ?
imagecreatefromjpeg($this->folder . $theme[0]) : imagecreatefromgif($this->folder . $theme[0]);
$bg_width = imagesx($img_bg);
$bg_height = imagesy($img_bg);

$img_org = ((function_exists('imagecreatetruecolor')) && PHP_VERSION >= '4.3') ?
imagecreatetruecolor($this->width, $this->height) : imagecreate($this->width, $this->height);

/* 將背景圖象複製原始圖象並調整大小 */
if (function_exists('imagecopyresampled') && PHP_VERSION >= '4.3') // GD 2.x
{
imagecopyresampled($img_org, $img_bg, 0, 0, 0, 0, $this->width, $this->height, $bg_width, $bg_height);
}
else // GD 1.x
{
imagecopyresized($img_org, $img_bg, 0, 0, 0, 0, $this->width, $this->height, $bg_width, $bg_height);
}
imagedestroy($img_bg);

$clr = imagecolorallocate($img_org, $theme[1], $theme[2], $theme[3]);

/* 繪製邊框 */
//imagerectangle($img_org, 0, 0, $this->width - 1, $this->height - 1, $clr);

/* 獲得驗證碼的高度和寬度 */
$x = ($this->width - (imagefontwidth(5) * $letters)) / 2;
$y = ($this->height - imagefontheight(5)) / 2;
imagestring($img_org, 5, $x, $y, $word, $clr);

header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');

// HTTP/1.1
header('Cache-Control: private, no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0, max-age=0', false);

// HTTP/1.0
header('Pragma: no-cache');
if ($this->img_type == 'jpeg' && function_exists('imagecreatefromjpeg'))
{
header('Content-type: image/jpeg');
imageinterlace($img_org, 1);
imagejpeg($img_org, false, 95);
}
else
{
header('Content-type: image/png');
imagepng($img_org);
}

imagedestroy($img_org);

return true;
}
}

/*------------------------------------------------------ */
//-- PRIVATE METHODs
/*------------------------------------------------------ */

/**
* 對需要記錄的串進行加密
*
* @access private
* @param string $word 原始字串
* @return string
*/
function encrypts_word($word)
{
return substr(md5($word), 1, 10);
}

/**
* 將驗證碼儲存到session
*
* @access private
* @param string $word 原始字串
* @return void
*/
function record_word($word)
{
$_SESSION[$this->session_word] = base64_encode($this->encrypts_word($word));
}

/**
* 產生隨機的驗證碼
*
* @access private
* @param integer $length 驗證碼長度
* @return string
*/
function generate_word($length = 4)
{
$chars = '1234567890ABCDEFGHJKLMNPQRSTUVWXYZ';

for ($i = 0, $count = strlen($chars); $i < $count; $i++)
{
$arr[$i] = $chars[$i];
}

mt_srand((double) microtime() * 1000000);
shuffle($arr);

return substr(implode('', $arr), 5, $length);
}
}

?>


回複討論(解決方案)

只看到 check_word 的定義,沒看到 check_word 的調用
也沒看到 session_start

在提交頁面裡有調用的:
include_once('includes/cls_captcha.php');
$validator = new captcha();
if (!$validator->check_word($t_captcha))
{
$ajax['record']['all_tp'] = 9;
echo json_encode($ajax);
exit;
}

那 session_start(); 在哪裡?

好像是沒有,那怎麼弄?

session_start(); 這個也有的,在另一個檔案裡

require(ROOT_PATH . 'includes/init.php');每個頁面都有這個檔案,session_start(); 就在這個檔案裡

你傳入的 驗證碼在哪裡?怎麼沒傳給 $validator










js:
function get_toupiao(tp_id,all_toupiao,hd_id,tp_star_time,tp_end_time)
{
if($.trim($("input[name=captcha]").val()) == '1')
{
if($.trim($("input[name=t_captcha]").val()) == '')
{
alert("驗證碼不可為空!");
$("input[name=t_captcha]").focus();
return false;
}
}
var t_captcha=$.trim($("input[name=t_captcha]").val());
var captcha=$.trim($("input[name=captcha]").val());
var originator=$.trim($("input[name=originator]").val());
$.get("/show.php?act=get_toupiao",{
tp_id:tp_id,
all_toupiao:all_toupiao,
hd_id:hd_id,
tp_star_time:tp_star_time,
tp_end_time:tp_end_time,
t_captcha:t_captcha,
captcha:captcha,
originator:originator,
async:false,
rand: Math.random()
},function(data){
if(data.record.all_tp=="9")
{
alert("驗證碼輸入錯誤^_^!");
return false;
}
/*if(data.record.all_tp=="8")
{
alert("請進行有效投票哦^_^!");
return false;
}
if(data.record.all_tp=="7")
{
alert("同時投票的人太多,請稍候重試^_^!");
return false;
}*/
if(data.record.all_tp=="5")
{
alert("今天您已經投票,請明天再投吧!");
return false;
}
if(data.record.all_tp=="6")
{
alert("今天您已經投票,請明天再投吧!");
return false;
}
if(data.record.all_tp=="3")
{
alert("投票時間已過,不能投票");
return false;
}
if(data.record.all_tp=="4")
{
alert("投票時間還沒到,不能投票");
return false;
}
if(data.record.all_tp=="1")
{
alert("該活動您已投票,不能重複投票");
return false;
}
if(data.record.all_tp=="2")
{
alert("該項目您已投票,不能重複投票");
return false;
}
if(data.status.code=="1")
{
//成功
$("#tp_"+tp_id+"").empty();
$("#tp_"+tp_id+"").append(""+data.record.tp_count+"");
$("#captcha_"+tp_id+"").empty();
$("#captcha_"+tp_id+"").append(""+data.status.captcha+"");
alert("投票成功!");
return false;
}
},"json");
}

PHP:
elseif($action == 'get_toupiao')
{
global $fdyu,$db;
$tp_id = intval($_GET['tp_id']);
$hd_id = intval($_GET['hd_id']);
$all_toupiao = $_GET['all_toupiao'];
$tp_star_time = $_GET['tp_star_time'];
$tp_end_time = $_GET['tp_end_time'];
$t_captcha = $_GET['t_captcha'];
$captcha = intval($_GET['captcha']);
$ip=getClientIP();
$ajax = array();

//是否需要驗證碼
if($captcha==1)
{
include_once('includes/cls_captcha.php');
$validator = new captcha();
if (!$validator->check_word($t_captcha))
{
$ajax['record']['all_tp'] = 9;
echo json_encode($ajax);
exit;
}
}

提供檢查思路:
1.如果輸入為空白是否可以通過
2.把輸入的驗證碼和session的驗證碼列印出來看看
3.驗證通過後,需要把舊的驗證碼刪除,否則使用者可以不重新整理頁面,一直用這個驗證碼提交不同的資料

可以參考: http://blog.csdn.net/fdipzone/article/details/7295496

以前刷Yii哥文章時發現csdn就有樓上說的第3個bug,不過刷完轉天他們就修複了
驗證碼防刷票是個很不靠譜的東西,如果投票數牽扯到利益,那使用者完全可以去買付費的驗證碼識別
我覺得歸根到底還是得IP去重

IP限了,但也沒用,刷票軟體可以刷不同的IP

10樓,我發現確實是像你說的第三點,因為我在資料庫裡記錄了驗證碼,發現有重複的驗證碼!那怎麼刪除舊的驗證碼呢?

if($action == 'get_toupiao')
{
。。。。。。省略
if ($_SESSION['code_1']!=$t_captcha)
{
$ajax['record']['all_tp'] = 9;
echo json_encode($ajax);
exit;
}
。。。。。省略
$ajax['status']['code'] = 1; //成功
echo json_encode($ajax);
exit;
}

是在$ajax['status']['code'] = 1; //成功這個上面加unset($_SESSION['code_1']);這個嗎?

就是通過驗證後,把session的驗證碼清空就可以了。
保證令牌只能用一次

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.