微博上传图片时只在前端进行验证, 服务器端没有进行安全过滤。
1 I. D+ m4 y. D3 f7 E% ~. I: s) x% A& |4 N% C1 g' H
, g3 N4 u( Q" U3 [
\api\StatusesApi.class.php
6 g7 k& f. y3 R 3 Q: b# { o# [/ ~: @/ r
function uploadpic(){
: t7 |1 V4 n' x% k/ e, X if( $_FILES['pic'] ){0 _$ Y1 W% V. i+ E
//执行上传操作1 Q5 Z9 U# r& ^, p% S; l3 Q* U
$savePath = $this->_getSaveTempPath();
2 V, D% p, \( e5 m2 v8 V $filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);
* e( x ]2 t D8 ~ if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))8 X- j0 j' a4 t# z' q
{( W. t3 U4 v& \7 b: Y
$result['boolen'] = 1;$ f s# h O% A1 K
$result['type_data'] = 'temp/'.$filename;
d) v) b7 L4 ], w9 {2 _ $result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;0 | C/ S) O) b( ~
} else {
$ G# R+ U+ v" H3 w; `& _1 m $result['boolen'] = 0;
/ [; m" `7 T( q( B5 {" o j! P $result['message'] = '上传失败';" `) R+ N7 S2 e. ?6 g
}# G9 ~' o, N5 @- T. b4 C. Z
}else{; c; v/ v8 ~: O. H6 o! a2 u7 D
$result['boolen'] = 0;* L- V+ {& M9 W- P% W8 p, h+ U( [
$result['message'] = '上传失败';
7 {( u: i& ?# Q: M1 F) n2 ~- o6 a }" g% o' D" R. M1 E
return $result;
: |( v" s6 u; |2 O! Y }
+ \. w! q" W2 j- Vunloadpic()方法没有对文件类型进行验证
3 e4 F! l! [! N: Z( B( |5 T- O
1 k# R) E4 e8 Z可以构建表单, 选择任意文件, 提交到5 K/ B3 [: I( ]" A& M) M- C$ e
/index.php?app=w3g&mod=Index&act=doPost4 y: m& q. [( ]
& `/ E# }( y5 x4 U4 q
在新提交的微博上可以找到上传的文件地址(去掉small_、middle_ 前缀)/ v4 U3 n h0 E/ n* l( i+ b
% `+ G+ V+ `" S( _9 h
* X( S' C x- K9 n) S, u# c B* a6 W在登录thinksns官方微博后,
9 U5 n- c9 J2 Y( O( k/ |构建以下表单:4 U) B" W; }" ^# ~9 |+ _7 v( Z
9 \+ J' \+ V6 _$ y5 p& M- [<form action="http://t.thinksns.com/index.php?app=w3g&mod=Index&act=doPost" method="post" enctype="multipart/form-data" />7 C0 P+ Q- [" n/ J' |7 ?
<textarea name="content">test</textarea>( T. P q' p* w' n. r
file: <input id="file" type="file" name="pic" />: ` H4 v' m* z8 Q9 J. R
<input type="submit" value="Post" />
: O2 A* V- |9 [6 Z. G& R</form>( N( Z$ p) g7 [( L; Q
去掉缩略图的前缀(small_ )& I8 ?( s# D \2 [9 Y
修复方案:1 x5 c8 W f& k$ i$ O _
W. H9 M9 Q! r% X4 z: G _$ L( N
& }: _3 w2 f& ]; }, D5 ~
\api\StatusesApi.class.php
( a, ?! u& C+ _* f( N+ \, ]& @ + J/ Z1 q+ y' y% C
function uploadpic(){ U9 x7 `5 k6 S! h: I2 D
/**8 H7 z8 E+ z$ V1 G4 {6 w" t8 w3 Y! N
* 20121018 @yelo( Z/ d* o$ X E) o
* 增加上传类型验证
$ a6 c& q9 q9 I2 \. ]! F% g: Y */
1 f/ Z2 X% {$ L! m% i9 Z $pathinfo = pathinfo($_FILES['pic']['name']);
3 F6 j+ Y$ K. X7 J# \* k! b7 o; \ $ext = $pathinfo['extension'];- a+ N) o* x3 Q
$allowExts = array('jpg', 'png', 'gif', 'jpeg');
b9 p1 S* V: M% S
! A+ ^ _, }3 [ T! A $uploadCondition = $_FILES['pic'] && in_array(strtolower($ext),$allowExts,true);
7 J4 P9 m% S1 {. J }" `
( y1 M( w4 U2 f! Q; a if( $uploadCondition ){
% @# o: r( x8 R4 X# w I- x0 W( r //执行上传操作/ ^ Z# {9 d$ D; E- _
$savePath = $this->_getSaveTempPath();9 h- R3 Q. s$ W0 T; E
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);) N8 Q9 t* P8 R5 I4 w, o6 `
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))' C+ G' ~, n& k9 f# G5 y2 [( H0 Y* i
{
/ E- r; \! R7 `1 A8 v, l $result['boolen'] = 1;" {8 K7 n! @! [+ G4 f
$result['type_data'] = 'temp/'.$filename;
1 b$ _ O. i( g, J/ } $result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
* P" k' H, q& ~* }+ j6 J } else {5 f4 ^0 D2 {& p( }
$result['boolen'] = 0;
5 E$ Q* _; p+ o% d6 p8 X! | $result['message'] = '上传失败';6 i& d9 n6 f' m
}
4 g+ E( V+ r" ?4 p" n }else{
: S. D0 X# y9 \ $result['boolen'] = 0;
* [8 z! I. c2 S $result['message'] = '上传失败';4 ^" I0 j4 d" I0 ~6 f( g1 [
}9 ^6 ]( {9 ^0 F* y0 t; M/ U
return $result;
* v, Y3 |6 A' J1 O7 p0 u* O }/ ^! z5 d. Q M. f, H g
$ [5 ^8 \7 k, R2 ~# G$ [/ {, K
, k! Z5 Z% l; ~) C
|