微博上传图片时只在前端进行验证, 服务器端没有进行安全过滤。
* L% a" D* O K9 J- t1 q4 A% Q' f& H9 K% C' J/ h
# ]" P7 Q0 @4 M# u) n6 y9 z; s7 h\api\StatusesApi.class.php, z; y7 L! l& w6 e# C
! n2 K6 i. o2 D" M
function uploadpic(){
( L! z) X( l- S& m+ c) t; S if( $_FILES['pic'] ){6 X: V S# u: J7 L1 ^
//执行上传操作1 [5 D4 T9 \& x J0 R
$savePath = $this->_getSaveTempPath(); }% ~: D& C( J" i7 \7 J4 l
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);
. ?( {+ i6 R' U if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))9 w% ^( H0 ]) t6 g
{
$ \ y# E; p% F8 [ $result['boolen'] = 1;
( l. p ]/ e9 R2 f1 u $result['type_data'] = 'temp/'.$filename;
: [, M( [0 p* o( _- z- _- E $result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;/ T/ R" Y5 Y( J3 [& `) z+ L8 ~* |
} else {
o- E9 I' G5 E, d2 c $result['boolen'] = 0;
& ?6 i* N1 N1 P. C3 N1 w, N $result['message'] = '上传失败';
?4 R S8 A( D. k }1 _1 A/ \9 D! z5 A
}else{6 w- A, L' u+ u2 I
$result['boolen'] = 0;
* Y o4 i8 M! o/ J) q5 x $result['message'] = '上传失败';
' v T# p+ |6 u }
5 B) X4 n# e" R0 k: P& q( ereturn $result;6 P+ e/ D2 ?" b) h1 D/ u
}, x, ~% X: P& `+ A( w0 R" V
unloadpic()方法没有对文件类型进行验证7 D/ b% f6 g1 n7 J+ o; r g3 ]9 \4 n
/ m+ n/ X4 o4 ^+ R/ o, p, h% t9 A
可以构建表单, 选择任意文件, 提交到
& P1 _, P2 z: w5 u# j) M! u/index.php?app=w3g&mod=Index&act=doPost
' k5 ?2 d) m" g6 T& k9 \, j' `
6 l8 G$ a* Q2 c2 o/ T3 l* x2 o' k在新提交的微博上可以找到上传的文件地址(去掉small_、middle_ 前缀)" Y+ M3 ~% X1 n2 r! B
4 u' m5 |9 w8 }/ e6 r8 L; Q
8 U7 P/ j9 A% r2 c1 a% U在登录thinksns官方微博后,
2 P& u4 z( e' q构建以下表单:: ?/ s8 }: R: I. W
. n9 l9 `+ w& s( |+ i' L3 P j
<form action="http://t.thinksns.com/index.php?app=w3g&mod=Index&act=doPost" method="post" enctype="multipart/form-data" />6 I8 J6 z; b$ A3 V$ I5 Z$ l
<textarea name="content">test</textarea>
/ o; V( g5 O& a" v# ]file: <input id="file" type="file" name="pic" />
$ w& o7 [4 K3 f# x# F<input type="submit" value="Post" />
" i- ]! f2 y3 z% u. a, z</form>
# j7 M9 ~) d% j$ X; e: ]( O. P去掉缩略图的前缀(small_ )0 @- y, S2 \, w# i! l# B
修复方案:
1 j6 \4 I/ A% V6 f v$ Z6 e9 E1 |' S7 V& Q9 J% n0 I0 V
5 ?8 _& z" Y0 S
\api\StatusesApi.class.php. t% M" x g+ T4 x) e0 j1 o% S
5 U$ G( X$ k+ y- V7 @+ o [
function uploadpic(){
' i6 K- J: K% w+ r, k) C8 d- l /**
8 g5 J" W/ G2 c * 20121018 @yelo1 \( v7 t% Z( a$ ]1 } H# r
* 增加上传类型验证
2 H4 B; Q$ O- K C* ?9 h */2 q1 \8 C: i2 u7 E
$pathinfo = pathinfo($_FILES['pic']['name']);9 j& h2 {7 _, u2 {5 q0 ~
$ext = $pathinfo['extension'];
! n: d. x: G' R4 q9 A1 U. \7 B $allowExts = array('jpg', 'png', 'gif', 'jpeg');
( V: Q: ]0 ?; G+ V
" V$ D9 _4 q5 U. g9 p $uploadCondition = $_FILES['pic'] && in_array(strtolower($ext),$allowExts,true);
8 Q) @& F* {/ H; H7 N7 q + ]: P: p) O3 E/ b; p n* B
if( $uploadCondition ){# \8 |7 n0 U8 \1 \. o2 s% Z7 G
//执行上传操作# P G6 l" L& G( J' b/ g2 s
$savePath = $this->_getSaveTempPath();
+ @; d. N% t+ O $filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);
4 w# N, @0 E8 v5 w if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))7 n4 _* D, H' e. P; H
{
# n: H3 h: x) G( y( s/ H $result['boolen'] = 1;
" |# P4 P3 y" @+ P+ t $result['type_data'] = 'temp/'.$filename;: q7 r( C" _" |) i- O1 M
$result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
/ ?9 q }1 `% H" n: C/ |# z } else {
0 O$ @5 J0 v8 E7 a9 J, |- L1 k $result['boolen'] = 0;* x* E+ d/ ?; b% O3 B
$result['message'] = '上传失败';1 f- b3 j' p' ]) b8 x5 ?
}
; J5 s1 s0 c; @+ H+ d }else{
7 w, T. A; |; G, w $result['boolen'] = 0;
$ `( C: @' W6 _. G, ~7 y# W9 W# Z3 ` $result['message'] = '上传失败';6 r- [6 e% r! A' Z4 I4 M
}* T! ~3 n' M: C3 e: e4 B+ X
return $result;
. i) @+ T0 {4 z" M* a+ } }2 w1 u; o, j8 |1 a7 j
9 A+ z. N! j7 u* B+ d% y
" |5 z& P, ?2 b7 _* B* S
|