微博上传图片时只在前端进行验证, 服务器端没有进行安全过滤。
, o: n4 S! R) q+ a i! \4 u5 h3 O6 m2 Q) j& L% }# ~/ e
2 ]4 E6 S' F& E4 t) L x! L1 g
\api\StatusesApi.class.php
+ i3 o5 Z+ I) f! W5 S" k 2 G0 [! g8 g# ?
function uploadpic(){' [/ @+ p5 Y3 ~# x: A0 Y& Y
if( $_FILES['pic'] ){" g" o1 w) D8 A) a3 ~' s+ S
//执行上传操作
9 W8 F. e4 T% \& C! Q $savePath = $this->_getSaveTempPath();
9 W, G" c4 u! | ~; I9 A5 L $filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);
- i3 z6 U9 Y2 K- I, { if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename)): D% j2 k) [5 z$ I
{
* L9 [) q7 `$ R( ^( } $result['boolen'] = 1;) l6 ?; Y, m1 z* M! G3 I
$result['type_data'] = 'temp/'.$filename;! R# |$ w2 I7 A6 J3 `8 n( z8 N
$result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;$ c) H8 t1 }: \$ N+ w% `7 d) J V
} else {
# V$ H8 c! B. m" o. K: Q $result['boolen'] = 0;
% W d1 x5 n1 E! T/ D+ R" D $result['message'] = '上传失败';0 w. ^) L. r1 ^% ~& l! d/ ^8 ~
}
. z0 O+ F* ~1 w. @2 d }else{! j7 y. R" r0 E! d
$result['boolen'] = 0;
0 c- K" k& u6 A( z' ]8 C* D" ~ $result['message'] = '上传失败';
! _5 y( Z9 S) G' r1 q3 H. T }
; y( G, L( p1 l) W# ~return $result;7 L& l% s" T+ t0 I
}
+ _; k( m. ^0 M. [unloadpic()方法没有对文件类型进行验证' p+ y# K! K4 I. i$ @2 ?
" L3 W [" m& p+ o可以构建表单, 选择任意文件, 提交到
: U1 |. ` f/ e; m" _& p% t/index.php?app=w3g&mod=Index&act=doPost
4 w4 c+ _3 w0 h# b4 h
5 @7 h1 p% Q) b5 b/ c9 `. L$ a在新提交的微博上可以找到上传的文件地址(去掉small_、middle_ 前缀)
% G) ?9 \2 U1 k: u: {+ ]% \
7 [8 Z: y, Q& i" L/ p6 X& M, Q- z! a) @' }/ J' f: u
在登录thinksns官方微博后,1 X9 z- X* ~- ~+ X& `0 w
构建以下表单:) e# Q- F! ~/ D
- F7 J! C. |7 }, v. D" g<form action="http://t.thinksns.com/index.php?app=w3g&mod=Index&act=doPost" method="post" enctype="multipart/form-data" />/ y! f0 X9 \* j: K5 \
<textarea name="content">test</textarea>2 F# \. w `, k. _" X4 _7 z' n
file: <input id="file" type="file" name="pic" />/ J: _8 Y% M5 ?) j e
<input type="submit" value="Post" />& Y- @/ J# {& r) V
</form>4 W3 H1 Q9 G; w% C2 {! g; q. j0 P' Q
去掉缩略图的前缀(small_ )+ ~$ P/ ?2 t1 i* U' Z) H, v
修复方案:5 g: ^$ S4 R6 q3 z7 |
$ z3 g5 T4 d% V/ D) H4 y1 D; M4 w& @$ N2 J
\api\StatusesApi.class.php
9 _8 ^- M' b3 N+ T9 V& ^2 l 2 a7 z( M4 u( L) n }
function uploadpic(){
% A) v8 D3 Q" V0 n, P4 {* ], [. z /**) Z- @9 W7 T2 H3 a! R
* 20121018 @yelo
# {% g7 _; P/ b4 ]. ~ * 增加上传类型验证
. w/ q" i5 o/ R */
8 ^. M( O, Y6 d& ^ $pathinfo = pathinfo($_FILES['pic']['name']);
% f2 a1 {8 b! _6 W $ext = $pathinfo['extension'];
2 a! M( s8 F2 j& J( q; i U $allowExts = array('jpg', 'png', 'gif', 'jpeg');
" D1 E- z s/ R# P! E$ V
& }; s$ M; ~. U$ C $uploadCondition = $_FILES['pic'] && in_array(strtolower($ext),$allowExts,true);
4 V8 z* K4 q7 e* k. ]
5 ~& y. D# l% ^2 p; N% O if( $uploadCondition ){2 _) y! C4 j; h- R. u4 \- b& Z9 e2 G
//执行上传操作
9 i Q: ?. k5 \+ X1 @: c" ~0 Y $savePath = $this->_getSaveTempPath();
: i7 _/ f5 t4 }" I, Z" j8 R $filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);0 }% |1 K0 b+ y8 E
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))3 {+ b g8 Q: J! H4 G
{
6 y% s" u+ O* B F" r& g $result['boolen'] = 1;1 ^! E2 `! @: G* k# `4 f
$result['type_data'] = 'temp/'.$filename;
$ w/ m! d) c, l s# }: b, L& Y $result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename; s5 {- g `* S8 u
} else {' x. D0 s% u- n+ M
$result['boolen'] = 0;
5 n" u% ~) S0 R& k) M% N $result['message'] = '上传失败';- L' w$ f: `( V+ r2 f! L5 ^6 F
}
8 G- p" N1 Q2 O' f' k, _ }else{7 Y$ M- j: _4 D
$result['boolen'] = 0;( N' A! R: c% ^
$result['message'] = '上传失败';" [2 X* {5 _( ^
}0 J. Q# v3 S* [
return $result;
2 y, a: b: [# V3 b) G7 p( Y }& Q. k8 H$ `6 H8 y& F/ x
: ^: |& [1 c+ a, x$ Y+ C
' J' P5 q" z1 s+ ~ ~ v- T |