微博上传图片时只在前端进行验证, 服务器端没有进行安全过滤。( V8 @- x1 Q$ [+ ^' v
8 w( O/ m2 K( h4 p# s
$ W1 _6 A) C4 k3 I6 t: R$ X# B\api\StatusesApi.class.php6 h, n: e( p- A% e
3 W$ q$ p7 @9 N5 m. ^" `5 e6 t
function uploadpic(){+ g( f+ Q- x+ h3 C4 {4 a5 H
if( $_FILES['pic'] ){
0 U$ \$ l; A7 t: H* ] //执行上传操作& D r5 E$ {" i7 `/ l n$ s5 w. Q
$savePath = $this->_getSaveTempPath();6 ], y' }1 Y4 u& ^9 B. E Q- C: g0 l
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);$ R- N; a* P2 s; H
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))
& @3 q, P8 ~. f- F: i' J. s, U {
0 b! W! D$ X1 W( S0 h7 f, d. c $result['boolen'] = 1;! ~: \# d9 {. R X, j* H
$result['type_data'] = 'temp/'.$filename;! ^- \. ^' o1 I$ j7 i" W, N
$result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
2 w* k1 H. x" b( H6 Z/ _ } else {0 Z' | v% f: H1 _; e' k. l: [! q0 w
$result['boolen'] = 0;! k- k$ k; q2 E- g7 r
$result['message'] = '上传失败';9 H1 t. p; G$ x/ d: h* l
}
% X1 |7 d% I" ?0 K( U- r) M/ P }else{
6 y- A6 ^& n) Z6 I3 L $result['boolen'] = 0;, j) l- ^2 i* D$ M0 A/ {
$result['message'] = '上传失败';
H. h0 n2 ]4 ]1 _ }7 E6 v8 t8 g! b2 a: E; M% b
return $result;
- M, Z3 U# z' Z& u b, @ }, n1 A, D9 f4 B8 Q8 `+ O) _( M
unloadpic()方法没有对文件类型进行验证
2 x* K1 N" e7 [( a( }/ n & h: W9 {- v+ ]* S
可以构建表单, 选择任意文件, 提交到
2 d& b$ Z/ g" W/index.php?app=w3g&mod=Index&act=doPost% ^8 b2 G; t* q, G t5 ^% e
3 l2 c S% b1 j在新提交的微博上可以找到上传的文件地址(去掉small_、middle_ 前缀)
0 B4 |! S+ Y" A& e# \+ H+ Q
5 E2 `4 a9 B6 p- w
+ x+ K% S3 G- ?1 _! Q3 ]在登录thinksns官方微博后,3 m, ]: U3 l( ~1 T, x- |
构建以下表单:& R8 h i& l- ~0 G' r1 @( l6 P
8 a8 j& } J0 ?' t2 J
<form action="http://t.thinksns.com/index.php?app=w3g&mod=Index&act=doPost" method="post" enctype="multipart/form-data" />
# A, k5 u" v2 S8 q' ` g9 G<textarea name="content">test</textarea>, }) F1 z3 o' _, r: a P
file: <input id="file" type="file" name="pic" />/ N0 w* m1 K. x
<input type="submit" value="Post" />8 B& Y% b- K* [+ Y5 K+ n& b
</form>9 L7 P4 s& R3 _" k
去掉缩略图的前缀(small_ )
) \3 B& ]4 ]1 c- C4 ?) ]# ]修复方案:! s8 W6 A; J; A1 _4 \, \7 @
" u* n( k o* C4 e! X3 {+ t" Q0 i1 x- C& _' ?+ H5 [
\api\StatusesApi.class.php6 F# B7 @& k' U- } E
; W3 x( j$ _% u
function uploadpic(){ B0 x. T5 f- p `( D
/**
1 U+ G) p, N3 W3 f * 20121018 @yelo2 R6 s6 b& d3 F- b
* 增加上传类型验证- I' W4 y) n. a( I, ^
*/" V: W2 r8 c1 ]# u0 h6 q: w1 \0 L0 g
$pathinfo = pathinfo($_FILES['pic']['name']);2 P+ \2 d- a& |9 Z* A
$ext = $pathinfo['extension'];# U1 s& _& T9 n7 v. f1 k. f
$allowExts = array('jpg', 'png', 'gif', 'jpeg');) u# p. r9 ^ p% B9 v. Z- d' l
+ p$ m4 ]1 B) A. O
$uploadCondition = $_FILES['pic'] && in_array(strtolower($ext),$allowExts,true);5 r/ g- L& D: F
" s6 G$ v6 L; t( L3 p
if( $uploadCondition ){
( ~1 f+ B3 P! p4 W- n3 V- [5 q+ w //执行上传操作7 j6 h% _3 q. w% ~
$savePath = $this->_getSaveTempPath();
0 {6 r: I5 u7 g" S0 ]# I $filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);
! A7 @( I5 v1 X, _. R if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))
, i) r, @( ?) r2 p {
d1 }0 k' O3 }0 ^1 {: D $result['boolen'] = 1;
9 Y2 v9 B- l+ \ $result['type_data'] = 'temp/'.$filename;- Q& [( W4 t* W
$result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
" v6 _/ P5 `9 Y* t( ^. P5 k1 p. M } else {( w; n9 W( u4 y- j3 q/ f7 y/ I
$result['boolen'] = 0;
! k3 k0 h4 ?1 ]+ F4 z9 q/ C: F! z $result['message'] = '上传失败';
, t9 S: q1 h" F G& R }: k' r7 Y+ R$ } c7 q2 o
}else{
' j: v0 S3 _" Y, R7 M$ { $result['boolen'] = 0; K) E @9 f5 e5 N9 w, L, @
$result['message'] = '上传失败';: D e+ K+ z' N- q# `
} q l% R7 ]1 Z% }6 M. F( \
return $result;5 O8 T9 e3 n, E, d: {& h" s( S
}
N( ~* H) J6 M3 T4 r2 k7 v' N( `$ k) f0 J/ S
8 o+ B& C( |( h9 j: M; G$ a2 a: D
|