PHP页面跳转与跨站提交伪造Referer地址来源
一、尝试过的URL跳转方法
代码如下 | 复制代码 |
echo '<meta http-equiv="refresh" content="0; URL='.$url.'">'; echo '<scrīpt language="Javascrīpt">window.location.href="'.$url.'";</scrīpt>'; echo '<script language="Javascrīpt">window.location.replace="'.$url.'";</ script>'; |
以上三种方法均无法传递REFERER地址。
二、使用PHP Socket函数伪造REFER
下面是PHP伪造REFERER代码部分,经过测试可以实现REFERER地址传递,其中$url是输入地址。
代码如下 | 复制代码 |
$uinfo = parse_url($url);//解析URL地址,比如http://111cn.net/archives/1.html if($uinfo['path']) // $data = $uinfo['path'];//这里得到/archives/1.html else $data = '/';//默认根 if(!$fsp = @fsockopen($uinfo['host'], (($uinfo['port']) ? $uinfo['port'] : "80"), $errno, $errstr, 12)){ echo "对不起对方网站暂时无法打开,请您稍后访问:".$uinfo['host']; exit; }else{ fputs($fsp, "GET “.$data .” HTTP/1.0rn");//如果是跨站POST提交,可使用POST方法 fputs($fsp, "Host: ".$uinfo['host']."rn"); fputs($fsp, "Referer: 111cn.netrn");//伪造REFERER地址 fputs($fsp, "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)rnrn"); $res=''; while(!feof($fsp)) { $res.=fgets($fsp, 128); if(strstr($res,"200 OK")) { header("Location:$url"); exit; } } } //如果是301或302状态码可以继续处理 //返回地址大概形式:HTTP/1.1 301 Moved PermanentlynContent-Length: 164nContent-Type: text/htmlnLocation: http://111cn.net/ $arr=explode("n",$res); $arr=explode(": ",$arr[3]);//Location后面是真实重定向地址 header("location:".$arr[0]);//跳转目标地址 exit; |
利用另一种方法 curl)伪造HTTP_REFERER
代码如下 | 复制代码 |
//PHP(前提是装了curl): //PHP(不装curl用sock) |
数据库设计
先准备两张表,pic表保存的是图片信息,包括图片对应的名称、路径以及图片“喜欢”总数,pic_ip则记录用户点击喜欢后的IP数据。
CREATE TABLE IF NOT EXISTS `pic` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pic_name` varchar(60) NOT NULL,
`pic_url` varchar(60) NOT NULL,
`love` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `pic_ip` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pic_id` int(11) NOT NULL,
`ip` varchar(40) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
index.php
在index.php中,我们通过PHP读取pic表中的图片信息并展示出来,结合CSS,提升页面展示效果。
代码如下 | 复制代码 |
<!DOCTYPE HTML> <body> <div id="main"> <ul class="list"> </div> </body> |
CSS中,我们将定义鼠标滑向和离开红心按钮的动态效果,并定位按钮的位置。
代码如下 | 复制代码 |
.list{width:760px; margin:20px auto} |
jQuery代码
当用户点击自己喜欢的图片上的红心按钮时,向后台love.php发送ajax请求,请求响应成功后,更新原有的数值。
代码如下 | 复制代码 |
$(function(){ |
love.php
后台love.php接收前端的ajax请求,根据提交的图片id值,查找IP表中是否已有该用户ip的点击记录,如果有则告诉用户已“喜欢过了”,反之,则进行一下操作:
1、更新图片表中对应的图片love字段值,将数值加1。
2、将该用户IP信息写入到pic_ip表中,用以防止用户重复点击。
3、获取更新后的love值,即喜欢该图片的用户总数,并将该总数输出给前端页面。
代码如下 | 复制代码 |
<?php $link=mysql_connect($host,$db_user,$db_pass);
<?php $ip = get_client_ip(); $ip_sql=mysql_query("select ip from pic_ip where pic_id='$id' and ip='$ip'"); //获取用户真实IP |
代码中get_client_ip()函数是用来获取用户的真实IP
测试程序如下:
//说明1:由于读数据库语句调用简单的封包函数两次,所以把读文件也改成连续调用两次,数据库记录ID为1就在第一条,并且唯一索引。
代码如下 | 复制代码 |
//说明2:测试两次一次是4K数据,一次是整形数据 set_time_limit(0); function fnGet($filename) function fnGetContent($filename) $begin=fnGetMicroTime(); $begin=fnGetMicroTime(); $dbcon->mydb_free_results(); fnWriteCache('test.txt',$content); echo '直接读文件测试结果:<br/>'; //--------------------------------- $begin=fnGetMicroTime(); |
4K大小数据的查询结果:
fetch_row 100000 次时间:16.737720012665秒
fetch_array 100000 次时间:16.661195993423秒
fetch_object 100000 次时间:16.775065898895秒
直接读文件测试结果:
file_get_contents直接读100000次时间:5.4631857872009秒
fopen直接读100000次时间:11.463611125946秒
整形ID查询结果:
fetch_row 100000 次时间:12.812072038651秒
fetch_array 100000 次时间:12.667390108109秒
fetch_object 100000 次时间:12.988099098206秒
直接读文件测试结果:
file_get_contents直接读100000次时间:5.6616430282593秒
fopen直接读100000次时间:11.542816877365秒
测试结论:
1、直接读文件相比数据库查询效率更胜一筹,而且文中还没算上连接和断开的时间。
2、一次读取的内容越大,直接读文件的优势会越明显(读文件时间都是小幅增长,这跟文件存储的连续性和簇大小等有关系),这个结果恰恰跟天缘预料的相反,说明MYSQL对更大文件读取可能又附加了某些操作(两次时间增长了近30%),如果只是单纯的赋值转换应该是差异偏小才对。
3、写文件和INSERT几乎不用测试就可以推测出,数据库效率只会更差。
4、很小的配置文件如果不需要使用到数据库特性,更加适合放到独立文件里存取,无需单独创建数据表或记录,很大的文件比如图片、音乐等采用文件存储更为方便,只把路径或缩略图等索引信息放到数据库里更合理一些。
5、PHP上如果只是读文件,file_get_contents比fopen、fclose更有效率,不包括判断存在这个函数时间会少3秒左右。
6、fetch_row和fetch_object应该是从fetch_array转换而来的,天缘没看过PHP的源码,单从执行上就可以说明fetch_array效率更高,这跟网上的说法似乎相反。
本文章给大家来总结几种实现下载短点续传程序功能,这些函数中主要是用到了php的header函数,有需要了解的朋友可进入参考。例如:下载时输出 下载文件大小,文件名等等
前提是.htaccess文件的配置需要添加一句
SetEnv no-gzip dont-vary
就是针对文件不进行压缩处理
例1
代码如下 | 复制代码 |
<?php |
例2
代码如下 | 复制代码 |
$fname = './MMLDZG.mp3'; $fp = fopen($fname,'rb'); $fsize = filesize($fname); if (isset($_SERVER['HTTP_RANGE']) && ($_SERVER['HTTP_RANGE'] != "") && preg_match("/^bytes=([0-9]+)-$/i", $_SERVER['HTTP_RANGE'], $match) && ($match[1] < $fsize)) { $start = $match[1]; } else { $start = 0; } @header("Cache-control: public"); @header("Pragma: public"); if ($star--> 0) { fseek($fp, $start); Header("HTTP/1.1 206 Partial Content"); Header("Content-Length: " . ($fsize - $start)); Header("Content-Ranges: bytes" . $start . "-" . ($fsize - 1) . "/" . $fsize); } else { header("Content-Length: $fsize"); Header("Accept-Ranges: bytes"); } @header("Content-Type: application/octet-stream"); @header("Content-Disposition: attachment;filename=mmdld.mp3"); fpassthru($fp); |
fpassthru() 函数输出文件指针处的所有剩余数据。
该函数将给定的文件指针从当前的位置读取到 EOF,并把结果写到输出缓冲区
上面两个实例对中文支持不好,下面这个函数很好的解决了这个问题
代码如下 | 复制代码 |
<?php /** * PHP-HTTP断点续传实现 * @param string $path: 文件所在路径 * @param string $file: 文件名 * @return void */ function download($path,$file) { $real = $path.'/'.$file; if(!file_exists($real)) { return false; } $size = filesize($real); $size2 = $size-1; $range = 0; if(isset($_SERVER['HTTP_RANGE'])) { header('HTTP /1.1 206 Partial Content'); $range = str_replace('=','-',$_SERVER['HTTP_RANGE']); $range = explode('-',$range); $range = trim($range[1]); header('Content-Length:'.$size); header('Content-Range: bytes '.$range.'-'.$size2.'/'.$size); } else { header('Content-Length:'.$size); header('Content-Range: bytes 0-'.$size2.'/'.$size); } header('Accenpt-Ranges: bytes'); header('application/octet-stream'); header("Cache-control: public"); header("Pragma: public"); //解决在IE中下载时中文乱码问题 $ua = $_SERVER['HTTP_USER_AGENT']; if(preg_match('/MSIE/',$ua)) { $ie_filename = str_replace('+','%20',urlencode($file)); header('Content-Dispositon:attachment; filename='.$ie_filename); } else { header('Content-Dispositon:attachment; filename='.$file); } $fp = fopen($real,'rb+'); fseek($fp,$range); while(!feof($fp)) { set_time_limit(0); print(fread($fp,1024)); flush(); ob_flush(); } fclose($fp); } /*End of PHP*/ |
最简单的实例如下
代码如下 | 复制代码 |
<form action="" method="post" enctype="multipart/form-data"> <?php
|
下面分享其它朋友的例子
例1
代码如下 | 复制代码 |
<? |
如果我们要动态不确定性的多文件上传怎么实现下面也有实例
文件上传代码
代码如下 | 复制代码 |
view plaincopy to clipboardprint? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>文档上传</title> </head> <body> <script language="javascript"><!-- 动态添加文件选择控件--> function AddRow() { var eNewRow = tblData.insertRow(); for (var i=0;i<1;i++) { var eNewCell = eNewRow.insertCell(); eNewCell.innerHTML = "<tr><td><input type='file' name='filelist[]' size='50'/></td></tr>"; } } // --></script> <form name="myform" method="post" action="uploadfile.php" enctype="multipart/form-data" > <table id="tblData" width="400" border="0"> <!-- 将上传文件必须用post的方法和enctype="multipart/form-data" --> <!-- 将本页的网址传给uploadfile.php--> <input name="postadd" type="hidden" value="<?php echo "http://".$_SERVER['HTTP_HOST'].$_SERVER["PHP_SELF"]; ?>" /> <tr><td>文件上传列表 <input type="button" name="addfile" onclick="AddRow()" value="添加列表" /></td></tr> <!-- filelist[]必须是一个数组--> <tr><td><input type="file" name="filelist[]" size="50" /></td></tr> </table> <input type="submit" name="submitfile" value="提交文件" /> </form> </body> </html> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>文档上传</title> </head> <body> <script language="javascript"><!-- 动态添加文件选择控件--> function AddRow() { var eNewRow = tblData.insertRow(); for (var i=0;i<1;i++) { var eNewCell = eNewRow.insertCell(); eNewCell.innerHTML = "<tr><td><input type='file' name='filelist[]' size='50'/></td></tr>"; } } // --></script> <form name="myform" method="post" action="uploadfile.php" enctype="multipart/form-data" > <table id="tblData" width="400" border="0"> <!-- 将上传文件必须用post的方法和enctype="multipart/form-data" --> <!-- 将本页的网址传给uploadfile.php--> <input name="postadd" type="hidden" value="<?php echo "http://".$_SERVER['HTTP_HOST'].$_SERVER["PHP_SELF"]; ?>" /> <tr><td>文件上传列表 <input type="button" name="addfile" onclick="AddRow()" value="添加列表" /></td></tr> <!-- filelist[]必须是一个数组--> <tr><td><input type="file" name="filelist[]" size="50" /></td></tr> </table> <input type="submit" name="submitfile" value="提交文件" /> </form> </body> </html> 提交文件代码 view plaincopy to clipboardprint? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>文件上传结果</title> </head> <body> <?php if ($_POST["submitfile"]!="") { $Path="./".date('Ym')."/"; if (!is_dir($Path))//创建路径 { mkdir($Path); } echo "<div>"; for ($i=0;$i<count($filelist);$i++) { //$_FILES["filelist"]["size"][$i]的排列顺序不可以变,因为fileist是一个二维数组 if ($_FILES["filelist"]["size"][$i]!=0) { $File=$Path.date('Ymdhm')."_".$_FILES["filelist"]["name"][$i]; if (move_uploaded_file($_FILES["filelist"]["tmp_name"][$i],$File)) { echo "文件上传成功 文件类型:".$_FILES["filelist"]["type"][$i]." "."文件名:" .$_FILES["filelist"]["name"][$i]."<br>"; } else { echo "文件名:".$_FILES["filelist"]["name"][$i]."上传失败</br>"; } } } echo "</div><br><a href="$postadd" href="$postadd">返回</a></div>"; } ?> </body> </html> |
另:错误信息说明
从 PHP 4.2.0 开始,PHP 将随文件信息数组一起返回一个对应的错误代码。该代码可以在文件上传时生成的文件数组中的 error 字段中被找到,也就是 $_FILES['userfile']['error']。
UPLOAD_ERR_OK
其值为 0,没有错误发生,文件上传成功。
UPLOAD_ERR_INI_SIZE
其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。
UPLOAD_ERR_FORM_SIZE
其值为 2,上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。 UPLOAD_ERR_PARTIAL
其值为 3,文件只有部分被上传。
UPLOAD_ERR_NO_FILE
其值为 4,没有文件被上传。
UPLOAD_ERR_NO_TMP_DIR
其值为 6,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。
UPLOAD_ERR_CANT_WRITE
其值为 7,文件写入失败。PHP 5.1.0 引进。
注意: 以上值在 PHP 4.3.0 之后变成了 PHP 常量。
相关文章
- 对于乱码这个问题php开发者几乎都会有碰到过,我们下面主要是介绍了php文件乱码和页面乱码。PHP页面转UTF-8编码问题 1.在代码开始出加入一行: header("Content-Type: text/html;charset=utf-8"); 2.PHP文件编码问题...2015-10-21
- 这篇文章主要介绍了微信小程序 页面跳转传递值几种方法详解的相关资料,需要的朋友可以参考下...2017-01-16
IE6中链接A的href为javascript协议时不在当前页面跳转
切页面时有时用链接A来替代按钮,这样做有几个好处 鼠标放上时默认有手状效果(不用添加cursor:pointer) 可以添加低版本IE都支持的伪类 如果点击时页面要整体刷新,即跳转,这时IE6则不尽人意,如下 复制代码 代码如下: <p>...2014-06-07- 对于单页应用,官方提供了vue-router进行路由跳转的处理,这篇文章主要给大家介绍了Vue.js实战之利用vue-router实现跳转页面的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。...2017-04-03
- 比如,我有一个开发一个黄页源码上转到了脚本之家。之前定了一个演示程序地址: http://www.jb51.net 而现在这个域名需要用来作其它的站,又不杀望原来的演示地址失效怎么办呢。那我就可以利用PHP REFERER来判断来源如果...2013-10-04
- 第一种: 复制代码 代码如下: <script language="javascript"type="text/javascript"> window.location.href="http://shanghepinpai.com"; </script> 第二种: 复制代码 代码如下: <script language="javascript"> aler...2014-05-31
- CSRF站外类型的漏洞其实就是传统意义上的外部提交数据问题,一般程序员会考虑给一些留言评论等的表单加上水印以防止SPAM问题,但是为了用户的体验性,一些操作可能没有做任...2016-11-25
- 这篇文章主要介绍了微信小程序 详解页面跳转与返回并回传数据的相关资料,需要的朋友可以参考下...2017-02-19
- <?php //fsocket模拟post提交 $purl = "http://localhost/netphp/test2.php?uu=rrrrrrrrrrrr"; print_r(parse_url($url)); sock_post($purl,"uu=5555555555555555...2016-11-25
- 今天我来给大家介绍在php中跨网站请求伪造的实现方法与最后我们些常用的防止伪造的具体操作方法,有需要了解的朋友可进入参考。 伪造跨站请求介绍 伪造跨站请求...2016-11-25
Ruby rails 页面跳转(render和redirect_to)
今天在做R.R.log的时候发现个问题,在修改密码的时候如果没有通过校验,没有显示校验错误的信息。...2020-06-30- 碰到页面程序执行超时时会提醒Fatal error: Maximum execution time of 300 seconds exceeded 是因为程序执行时间超过了最大允许执行时间,解决办法我总结了好几个大...2016-11-25
- 在php页面缓存主要用到的是ob系列函数,如ob_start(),ob_end_flush(),ob_get_contents(),但是更高级的缓存是不使用这些函数的,本文章最后一个实现就有讲到,大家可参考一...2016-11-25
- php是一种服务器的脚本语言,他也是现在最为流行的WEB开发语言,下面我们来讲述一下几种上在php开发应用中常用的四种页面之间传递参数的几种方法。 第一种: 使用客户...2016-11-25
- php定时跳转我们需要利用header函数输入html或js代码来实现定时跳转了,下面我来介绍一个简单的例子 php代码 代码如下 复制代码 header("ref...2016-11-25
- 这篇文章主要为大家详细介绍了如何使用SignalR发送页面跳转通知的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
- 静态化页面可以减少服务器的一个负载了,如果我们同样的一台机器如果有数据库连接只能负载100IP,那么用静态htm文件估计可以负载1000IP,所以我们很多站都是静态化的页面这...2016-11-25
- 伪造IP来源对于php来说是很简单的一件事情,我们只要利用了php curl即可实现伪造IP来源哦,IP地址你可以随便写哦。 实例 代码如下 复制代码 $c...2016-11-25
浅谈ASP.NET MVC 防止跨站请求伪造(CSRF)攻击的实现方法
下面小编就为大家分享一篇浅谈ASP.NET MVC 防止跨站请求伪造(CSRF)攻击的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-09-22- 查了下,CURL确实很强悍的可以伪造IP和来源,下面看实现有需要的朋友可以参考一下。 1.php教程 请求 2.php 。 1.php代码: $ch = curl_init(); curl_setopt($ch, CURLOP...2016-11-25