微博上传图片时只在前端进行验证, 服务器端没有进行安全过滤。8 q8 F' i* ^, f
6 S2 U# x' B& q' N2 t5 {! r2 U
, O6 C: g& E1 s$ y6 `+ C
\api\StatusesApi.class.php
8 O+ L6 x3 ?5 U+ x. }+ v 2 |- l- W: D. b `
function uploadpic(){& B a7 z* q9 N9 X# P" s& m) `* y
if( $_FILES['pic'] ){8 \4 k/ {0 C" L6 R' e
//执行上传操作+ \( I2 ^& Y0 ?- K; H
$savePath = $this->_getSaveTempPath();- L5 r: I* r& A% w8 J5 g2 [" W( O
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);- ?8 [) }; ]: J' p. S& L
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))+ k5 x# ~7 c* N+ X
{
2 n, }3 a* M, P9 x2 w" W $result['boolen'] = 1;' w0 W# n. x% t5 T/ _
$result['type_data'] = 'temp/'.$filename;: h0 q5 ]2 R! {( E
$result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
. r0 w" O' L$ v) \. j% e" b } else {
8 ]- W0 U% ]9 k9 T9 ` $result['boolen'] = 0;1 t( @* v+ R3 h4 T
$result['message'] = '上传失败';
4 j# w" m# e b: \ }6 _+ w" ]6 `6 _2 k5 k" n4 F2 `
}else{2 l, j) T9 O. U$ U- \6 E6 D& w
$result['boolen'] = 0;; P( ~, E9 R8 l$ S
$result['message'] = '上传失败';6 U0 H0 o5 I( d' l+ G
}' t9 y9 @ O% w( ?6 M
return $result;
9 u: [5 r1 D+ b/ D5 A, } }
) u2 S: ]" c) S& H/ Q* Uunloadpic()方法没有对文件类型进行验证
. f5 T5 Z$ Q6 y4 \
8 C4 T. P3 H$ R" c/ ?7 |' F( r可以构建表单, 选择任意文件, 提交到
. {/ n0 j1 ?5 Z' ~1 Z' i) k5 g' X/index.php?app=w3g&mod=Index&act=doPost8 u0 A% l4 l+ P* z: s8 ^
# C- ?3 c6 \7 C: }3 f在新提交的微博上可以找到上传的文件地址(去掉small_、middle_ 前缀)
" i6 Q! C1 }* g" t2 s: I* J2 I/ @- V- \! N( }3 \% R" T6 ~) n
3 ~+ t! Q6 u) ^3 y% C在登录thinksns官方微博后,( t; \$ Y5 _$ U; R) A# I
构建以下表单:( b% y L2 m1 ^. k
# ], [$ B6 ^; @7 ^; B<form action="http://t.thinksns.com/index.php?app=w3g&mod=Index&act=doPost" method="post" enctype="multipart/form-data" />/ s& W3 U0 b/ ~2 T; O, |4 u$ B
<textarea name="content">test</textarea>
' i+ j: x6 h5 N- o5 r" kfile: <input id="file" type="file" name="pic" />' q6 a2 b3 f$ p/ m
<input type="submit" value="Post" />
8 Y f7 S3 F- F+ p7 p3 n! p</form>) s! w- l7 z8 ^1 c. P( s8 s. Y
去掉缩略图的前缀(small_ )
5 O3 j) _7 r6 `# O( f8 l& N3 c* _9 s# i& K修复方案:
: E0 L J; B9 x) m" L7 q& P9 q9 {5 m, A* o; b w9 |" C" e8 g) u5 ?
+ G Y2 b x1 R. o5 E\api\StatusesApi.class.php
9 s/ h$ t7 h, I. _3 p $ D! r/ u5 R! `( C
function uploadpic(){
! |- v9 o4 H. |/ o /**3 u# q( D& q* _" W
* 20121018 @yelo) X- M: H) J$ i9 r* R: F+ I0 R4 q
* 增加上传类型验证
1 H( b: Q3 x. \, g; G6 ` */% y0 e% O" w) Q' L9 d
$pathinfo = pathinfo($_FILES['pic']['name']);4 Y U# f7 ^! V! e( f
$ext = $pathinfo['extension'];- z9 P- p9 d _, \) z s
$allowExts = array('jpg', 'png', 'gif', 'jpeg');
3 k/ G/ V5 G6 Q! z( X
" g" D" Q% I) ~' O7 p# _2 u $uploadCondition = $_FILES['pic'] && in_array(strtolower($ext),$allowExts,true); d0 |% w9 [/ \7 w& n) Z8 v- l$ x
7 v) y! v2 d1 I7 ^% Z! M if( $uploadCondition ){
0 c7 S5 N5 y) B5 ?8 i. c //执行上传操作# y7 j; f9 z! [& u/ }
$savePath = $this->_getSaveTempPath();# c/ Z m. ^4 Y* b% n8 \8 `, c
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);2 p6 ^3 X' t& Z. D; ?& ?; |
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))
7 m* a$ ^# i6 m t3 M/ ? X1 `( ?/ v9 c {
0 u" d0 l" |& D/ W4 n) G $result['boolen'] = 1;
0 O. \: u# P4 o0 T5 F0 C4 }- R $result['type_data'] = 'temp/'.$filename;$ T- b H: r/ s: Z# ~* K8 ?
$result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;5 P; t5 A: n: x; _5 g9 \ @
} else {" p6 s7 N+ Q# F0 C0 Y
$result['boolen'] = 0;
% V. X a. B. {2 k# T+ f3 h $result['message'] = '上传失败';! b# s% H6 p) ^( y4 O5 d" J
}
% y* Q) P1 \ l7 p9 x }else{! d) O& s3 ]& n% t' `$ x
$result['boolen'] = 0;4 y2 a" N4 C$ E- U! _( T' D
$result['message'] = '上传失败';$ t& t1 t' |. n2 ~
}
6 H ^8 K9 N1 ^5 K1 E7 }return $result;
, F0 e5 O. D5 j( T: o0 S; h# v6 A }
/ C* W, `7 s1 k$ A: E4 [
, _ H* E7 b0 C) K( a: u( x/ O% P g; `4 M" l( i7 V; Y/ F' T
|