微博上传图片时只在前端进行验证, 服务器端没有进行安全过滤。: }. E3 ?$ u: s. g
! `7 j' O. C% K3 Y$ R e, u/ ?
6 }7 E. t6 A! X0 ]\api\StatusesApi.class.php
3 ~; _+ @9 @1 }) l 9 I+ Y. _0 \, W! k& ~3 g. A
function uploadpic(){4 j. P9 ]. `/ _+ s
if( $_FILES['pic'] ){2 J) N* E6 L$ Q* r4 i! c! k0 c2 F
//执行上传操作
3 r4 B" N7 R3 k3 \1 [ $savePath = $this->_getSaveTempPath();
( m+ J2 h) \5 ^9 J- B$ M+ i $filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);
9 M4 l; o) d7 Z' N! e, u0 R" v if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))( C9 N E# e% S$ o( B9 z2 P
{
' C" _9 a$ ?! C4 B $result['boolen'] = 1;
5 ?/ ~9 v1 H4 _/ d $result['type_data'] = 'temp/'.$filename;0 {* ?. d7 W( [) j7 m
$result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
- _1 ^3 g1 p6 @& C: F- l+ f } else {0 i0 y2 B' M* Q" Q7 i
$result['boolen'] = 0;7 ^) Y& D6 n' P# x7 \" r
$result['message'] = '上传失败';
1 J' d7 j8 R0 E# h+ M* ? }( O, e$ _6 @. ]; \( l
}else{) r4 n6 V" H0 N$ z& y9 C$ W/ r
$result['boolen'] = 0;+ k) Y, D1 f. N* e
$result['message'] = '上传失败';4 O: a/ A7 i5 o) V/ r6 X
}. N( V* g$ m, f5 r8 r! j
return $result;
# ~, b0 L( j- a! f6 Y) v }3 y: W& N* N. K" f3 I
unloadpic()方法没有对文件类型进行验证
* {; n$ d0 N5 E+ [4 Z: z: O* s 5 b' i; |' v# j6 j
可以构建表单, 选择任意文件, 提交到+ J0 w3 k! A0 p6 J r7 ^3 L9 t
/index.php?app=w3g&mod=Index&act=doPost: \' S& X9 ]; x! d# n
; D! ]6 Y( e: H
在新提交的微博上可以找到上传的文件地址(去掉small_、middle_ 前缀)
$ T9 G7 o+ U4 U( w" |% P# u+ Q
; W( Y; r0 l* @* c* C9 I" C& [8 e9 e* z" }! y7 q q
在登录thinksns官方微博后,, {6 k: c b! b' n. p' T$ v" O
构建以下表单:
1 j0 R# T" S7 S5 N
, r" [5 C8 h# a# @3 s0 U. _<form action="http://t.thinksns.com/index.php?app=w3g&mod=Index&act=doPost" method="post" enctype="multipart/form-data" />5 y+ r. q1 c2 b, u ?9 u3 Q
<textarea name="content">test</textarea>' c Z3 X1 p4 d
file: <input id="file" type="file" name="pic" />, m: Y+ k: a n0 c
<input type="submit" value="Post" />' b. I v* P) s6 ]6 J, Y
</form>, @& n* D, h; @7 R. w3 ^( v8 t
去掉缩略图的前缀(small_ )
S: u# f( c: a3 D修复方案:
% q! ^4 c1 X5 a& n( q9 T! D
2 ~6 D- |& O. P+ O0 B" `6 o& V. F
\api\StatusesApi.class.php6 e3 z6 o4 [# \5 H+ N5 A# i# \! T
2 ?6 N) v8 v/ g* k% L4 w2 m7 ^" nfunction uploadpic(){/ S) _# A# K/ E3 O5 F; N- [8 A4 P
/**. y# l* F( k9 L/ }
* 20121018 @yelo1 B4 o4 V! F/ a3 ?* z' w" q! O. K; p- C
* 增加上传类型验证6 l; C% M" ^- y0 W5 f( r
*/, F5 J: D1 H) w! d0 K
$pathinfo = pathinfo($_FILES['pic']['name']);: @5 c# }' A- u- a( y# U* h9 X# M- y) w
$ext = $pathinfo['extension'];9 ]; p& `- Q3 f
$allowExts = array('jpg', 'png', 'gif', 'jpeg');8 ^8 n6 f! T' i% c+ f: X1 q
( J3 x5 z) Y2 |! U$ o $uploadCondition = $_FILES['pic'] && in_array(strtolower($ext),$allowExts,true);
_' h1 ~% s4 H
1 A# z% U! R G1 H# {$ W if( $uploadCondition ){/ Z b' w/ x. ]* E
//执行上传操作
7 l: u, O% U5 y, L) g9 x $savePath = $this->_getSaveTempPath();
, _* R. [- B! |- U( ] $filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);6 {, Y9 b" P0 d. _
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))
$ |; ?/ R( r0 k1 x9 k- [3 V. V- V {5 _% T9 u! p3 }
$result['boolen'] = 1;9 K' b7 T: m$ [8 i! G3 n
$result['type_data'] = 'temp/'.$filename;
1 I7 ?/ @+ s( S# ?" b% i2 J- e $result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
/ a' f# X& |, @( j Z' Q } else { Z" R T7 {8 v
$result['boolen'] = 0;, o) r0 y* k I' g0 C. T
$result['message'] = '上传失败';: E1 b7 ~" ^3 C* W: t% B
}
+ w9 O: v/ j" q1 t( R6 r }else{& ~8 f5 [2 }8 z9 h R% \* z D; D
$result['boolen'] = 0;
5 b) N2 x) b4 T) N $result['message'] = '上传失败';. g# O6 O5 Q5 _5 K( |+ `
}$ H$ J1 a6 p, Q1 x
return $result;, L8 K2 c$ ]( a" u
}/ `. C& O1 Q) [1 }6 H$ M, J9 w
6 I- Z' w4 n& e. R/ b( i4 s& q0 i8 h/ S3 L4 d( y
|