微博上传图片时只在前端进行验证, 服务器端没有进行安全过滤。
" n: c! q/ ~8 P" z" s* g( x0 w, h D7 T1 k
* R2 p7 |9 E" l) s1 v
\api\StatusesApi.class.php! o: |% A2 b# K1 F$ N: S
( A h. |/ @/ T8 ffunction uploadpic(){3 P) c0 S U/ y' M0 V2 T: N
if( $_FILES['pic'] ){
; H$ R( @8 {9 O& }# r6 b6 O9 u //执行上传操作0 f* W* x" E5 u
$savePath = $this->_getSaveTempPath();2 e1 Z2 M" \ o: _4 i: ]# K( ^0 D1 G+ \
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);
K m& J! S6 a4 U8 B! |0 W1 { if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))4 v8 J( X( _/ H% G, n- ^- O
{0 i! s. w# ^0 o, v: y9 M
$result['boolen'] = 1;6 U0 O8 [, K% p3 o
$result['type_data'] = 'temp/'.$filename;
6 d' U6 \1 e$ m% V0 P C $result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;& q; @! E" ]# t2 s+ H7 e3 g
} else {
2 \0 H; D: c$ c9 J' U9 R& k $result['boolen'] = 0;9 h0 ?7 ^6 y7 l3 L" c% ^: d
$result['message'] = '上传失败';5 |* h7 B- y3 q& x9 F! P3 p
}
& K* r' K- X: \( q# r }else{. u9 i* q) r3 P" b/ ]8 i4 R
$result['boolen'] = 0;
4 V: @. S6 I* L7 h2 } $result['message'] = '上传失败';
' H* ^+ B* K7 ` }( L8 ^6 e! e5 E7 I Z3 n5 f8 e
return $result;( I! Q7 Y6 ?' h5 p' w% x& t3 N1 I( P+ u
}
% Z0 m1 Y; B6 f& Q+ t0 e" l4 gunloadpic()方法没有对文件类型进行验证; p3 I! t' [) c2 C1 {
- I& {' i3 {8 A8 P# H' b
可以构建表单, 选择任意文件, 提交到
R- c0 K+ ? q0 Q x4 [/index.php?app=w3g&mod=Index&act=doPost
9 Q& b4 ?& ^ }" d- y# ]8 B 6 D6 m b: E7 c/ h& _" r
在新提交的微博上可以找到上传的文件地址(去掉small_、middle_ 前缀)1 a o# n( l$ B* v; H4 A
! V$ }0 t# E3 K! K g3 Q: r+ \
. [" u# Q. w$ y% ~2 W; F
在登录thinksns官方微博后,9 A5 P$ {- r! z0 `9 S3 A- U2 P
构建以下表单:
( l" U! c# W3 i2 _
1 l) B* s' J6 W- ^) X8 g/ E6 H<form action="http://t.thinksns.com/index.php?app=w3g&mod=Index&act=doPost" method="post" enctype="multipart/form-data" />
: ]) g' S/ m" @9 o7 |7 Z! [<textarea name="content">test</textarea>
; y& D+ W- R% x5 ]; pfile: <input id="file" type="file" name="pic" />/ J3 h! E1 y, A3 b% K6 g
<input type="submit" value="Post" />
4 v( k9 B2 h( O( f, S- {</form>
4 g8 d5 |2 S- e- e b/ Q u2 \, L去掉缩略图的前缀(small_ )
; V; }+ X% P2 O5 V0 ?, {2 ?修复方案:5 ?8 R* j+ D! n6 W9 H( f
& F1 m/ b) G2 w4 F
2 @9 |: n2 F4 d. g/ j# g0 A\api\StatusesApi.class.php
9 C6 I/ z/ J& B7 Y+ s) u ) X8 j! i3 z( ^; U3 \. D
function uploadpic(){
' V0 y2 n1 S1 C; u/ ^$ X7 G% p /**
0 m! P3 @, C+ Z * 20121018 @yelo
' m" Z: V ?4 j0 ]9 _ * 增加上传类型验证
7 d: o% v$ ~: p5 d% ]( y */
8 d5 s& K! K6 ]; N! c' G# ~ $pathinfo = pathinfo($_FILES['pic']['name']);" m" Y; V. L2 k* _% ^% s( J
$ext = $pathinfo['extension'];
7 A7 A- k! F4 h8 t: }' V $allowExts = array('jpg', 'png', 'gif', 'jpeg');, ^& {2 Q" C7 J1 W3 H
# G3 E' r( I- [: _) E, L# h
$uploadCondition = $_FILES['pic'] && in_array(strtolower($ext),$allowExts,true);
6 y& X8 h0 q/ z. R/ r" X- [ + m. w- [) m9 C
if( $uploadCondition ){' V. q4 k) ]) ?) P
//执行上传操作0 T- S: B( \$ G! F3 @
$savePath = $this->_getSaveTempPath();
3 w' F/ ^# h! x2 [' X7 s $filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);/ |7 r! z1 d! M
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))
- O$ E0 c: x, J8 y6 L7 A/ _& L) ` {. H- h7 B1 I, u! ~. V5 E0 T6 G( Q
$result['boolen'] = 1;
$ K1 |( A. `6 ~) U7 y; i- k $result['type_data'] = 'temp/'.$filename;
- J9 e* W: g5 }. t. N $result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;( H8 @$ i7 C% x0 g- g9 {' f6 o
} else {- f" W0 r6 }+ r( ^2 j9 T% U
$result['boolen'] = 0;
' h! o' {4 A; U: d! y8 a $result['message'] = '上传失败';4 P. M: g8 B/ b7 }( {% F
}
" _* ]/ s; a- _% y }else{/ A9 X' ?7 q! N9 w! C) }6 b
$result['boolen'] = 0;( F& L) r" a9 b7 Z* K8 Y
$result['message'] = '上传失败';
# j# U4 @# D; Y8 V! }. { }' w1 v9 T+ l7 h* A
return $result;
% y* f0 W8 r- S& {& G }; {2 m- _! m- d: e
* B7 p% L; [( z( m) ]: Q8 W
' \* O. J5 d1 e% K g0 H% g |