微博上传图片时只在前端进行验证, 服务器端没有进行安全过滤。
, |$ ?+ `9 |) F# W! i9 M; k7 Z0 [; s( i# A7 {2 x
" T6 B8 J4 h! X [: T9 _: o- |
\api\StatusesApi.class.php7 r% N" c/ z6 M3 f1 |
3 i" \9 G/ u' {" _) B1 A7 B
function uploadpic(){
. H% z! m# e. w6 W if( $_FILES['pic'] ){
7 i" A" N0 T* P* c! w) L //执行上传操作4 P- l$ s' H0 H6 q Y K) Q
$savePath = $this->_getSaveTempPath();" Z' ~. f$ V) ]/ i. v9 X% P
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);: F2 H, |; `# a; r
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))7 N: U4 U& s+ K5 J
{
) y! u) l+ W8 P7 b& Q, t $result['boolen'] = 1;
. o! @: A) K: J' C. D; H9 W $result['type_data'] = 'temp/'.$filename;
2 l0 [$ K( z" J) v/ v $result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
7 {( @0 w3 k" a } else {" K4 _0 W% X o; J
$result['boolen'] = 0;
- Y8 q9 e3 E' N: k: z2 V# Z3 x$ E4 \ $result['message'] = '上传失败';
; b4 n: M: U6 ^) t n$ n1 Q/ P }+ O3 _; Y7 |. ~6 `# _ b4 ]
}else{8 ?1 S- C, r" P5 L& J j' b
$result['boolen'] = 0;" k p. s- x" Q* e, S5 i7 p
$result['message'] = '上传失败';3 L4 F4 K5 C" Y5 \0 i, Q$ [
}# J7 E$ I& h! [$ ?( A! \( l
return $result;3 H' }' J$ z! p) k# ]. E
}
9 V, c! ]) ]0 f9 Y4 I: @- Z5 }unloadpic()方法没有对文件类型进行验证
6 G2 R3 E8 w2 k- v' ` ) I" r' W& k' S4 \! x% r
可以构建表单, 选择任意文件, 提交到" O0 U' V' o+ [8 d1 x/ t& w
/index.php?app=w3g&mod=Index&act=doPost
( q' e( J) q3 I* J 0 d1 S' i& g, Q3 ]2 N& U/ w$ ^
在新提交的微博上可以找到上传的文件地址(去掉small_、middle_ 前缀); c' D8 k3 W. r9 h
0 w$ W# K) c" V, q6 R
- R4 X1 l1 B% _- a% a在登录thinksns官方微博后,0 {. N% N t! p+ m8 d7 Y D
构建以下表单:
, ~- r5 S1 |0 r9 D 6 u g6 f- t0 x9 U9 i' c" H
<form action="http://t.thinksns.com/index.php?app=w3g&mod=Index&act=doPost" method="post" enctype="multipart/form-data" />
0 d; N6 G& x3 z/ K! m<textarea name="content">test</textarea>4 F) J# Z6 L( _! u% D6 ]
file: <input id="file" type="file" name="pic" />
( Y8 A" ^) W, D<input type="submit" value="Post" />6 b& @( J& M3 X+ ^" w6 H
</form>5 K9 G% N7 h7 `
去掉缩略图的前缀(small_ )$ {9 F0 O1 `' m
修复方案:
2 f* ~# p9 w4 O5 c8 o. v; Z
* }% S* a3 s5 y$ u$ R" S$ w: S4 T* {/ p$ \5 W
\api\StatusesApi.class.php
/ |# s, F, V& d L" p& D- _: i2 s
, t# _1 x' d$ o3 j2 F2 Lfunction uploadpic(){" ?1 L+ E! L3 k: x* T" E
/**
: @: P4 b! s8 w2 G * 20121018 @yelo
/ a; l' D* q/ s4 q3 _" s * 增加上传类型验证3 B0 }4 ~: d( }/ Y' M3 L$ l7 i
*/+ f* |6 u' G0 c
$pathinfo = pathinfo($_FILES['pic']['name']);
5 Y' ]5 E2 A; m3 C! J& G $ext = $pathinfo['extension'];$ n* r7 e0 n0 @- x8 ^6 `- y+ j
$allowExts = array('jpg', 'png', 'gif', 'jpeg');/ b Q; ~3 h/ M$ }; w& ] i
! @8 b' E$ }% j& U1 @/ M8 }% `9 Q( k
$uploadCondition = $_FILES['pic'] && in_array(strtolower($ext),$allowExts,true);
( J, g9 i( q0 l8 y
" ^# ?8 j5 A+ r) t if( $uploadCondition ){. B _) P: T8 h) w) l
//执行上传操作8 F, ^! z B1 Z$ i2 A9 k
$savePath = $this->_getSaveTempPath();, {. x, n3 O) M( Y
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);* X. ~& }" }( M6 q* k. I( q( S; O
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))% P" o0 }! }7 Z: l) ?
{
- X6 G3 o3 r* w $result['boolen'] = 1;
, u2 I [% E3 I% ?2 g0 H: z0 Z3 ~ $result['type_data'] = 'temp/'.$filename;& m, Q+ ]: ^2 i1 x3 ]
$result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
# m* N7 a# q! N; e" b5 b. ^ } else {/ A' K8 P/ r P+ e ]
$result['boolen'] = 0;9 B5 P5 e: C" d1 l0 b7 r: u
$result['message'] = '上传失败';* k+ k% g1 q( `6 G
}( K* D! V2 @1 @" h" ]! o" ^
}else{
) x6 j$ {1 B: x- N7 p5 \ $result['boolen'] = 0;
: V7 k9 ~: e/ L! i+ n5 @ $result['message'] = '上传失败';' _; Q! B. F( u4 d: _1 u, C& M
}
& H$ G" N |3 K" d7 i) ^1 ~return $result;% n8 A4 B6 W/ F$ X2 Y2 K
}
9 A* m+ {5 |& ]: T0 U, Q' Y- q3 D; V6 d$ F; y
% f4 d. a7 K9 S+ x( R- H
|