微博上传图片时只在前端进行验证, 服务器端没有进行安全过滤。. _# `+ w) k) `8 w. @
& ]% c) L$ B8 @7 U& B- Z
% r3 y+ y1 m+ B& g! O% D1 W\api\StatusesApi.class.php
. c3 D. X) \; l5 i+ u' T0 P! m 0 S! }: p- E: j/ o1 \! L" B
function uploadpic(){4 p+ ]+ q6 W* s. ^# Y9 L
if( $_FILES['pic'] ){
. O8 R, Y9 ]4 G$ |+ Z Z //执行上传操作
* Q9 q+ u" c" h( O( n% h $savePath = $this->_getSaveTempPath();8 g: p+ W, a5 u, b% @
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);" R, A0 c, U/ G/ b: K1 M- {! ?& _* y
if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename))4 S0 n5 I6 C; t) B* J6 _( Y
{
7 X/ C5 F+ ^( }$ n. p7 H8 j $result['boolen'] = 1;
/ u& e7 A: @! `" H3 M. {, ^ $result['type_data'] = 'temp/'.$filename;
$ j' @% P9 |9 S! f1 E* p u ]1 z8 F $result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;
& i+ Q! a) P' m5 L } else {
5 g( N8 ^8 K1 v4 G $result['boolen'] = 0;
# T; P& B+ Q* p$ v $result['message'] = '上传失败';7 s9 {8 x' }* l" o0 k6 I* j
}
* }7 d, z+ `/ i }else{* c) }9 k0 S- f8 ^( |
$result['boolen'] = 0;
! D- t! a# U6 F/ e% g/ U $result['message'] = '上传失败';' A8 |) j9 c+ Z3 u" c3 M
}) Q. N5 }* X3 j$ O; U
return $result;6 z: [. \4 z. t) ~! t
}* {4 @$ f, c( m1 F- S2 Z
unloadpic()方法没有对文件类型进行验证- L, h- C# l) D) s& n$ l0 I/ t
) \ I4 e9 f. l1 R6 b/ X% r
可以构建表单, 选择任意文件, 提交到2 W" ]2 k: y' E7 w' n' q+ A
/index.php?app=w3g&mod=Index&act=doPost
3 m& c) V0 _2 P, R$ ~# }6 _
$ P( e6 P' J& H4 ]: ]1 P在新提交的微博上可以找到上传的文件地址(去掉small_、middle_ 前缀)- `) I8 g. ~4 g
" M3 ~& Y; _; f3 z* v7 B0 H
+ `3 ]( {4 g2 F4 I! W' _& z在登录thinksns官方微博后,
5 g- p: z2 N2 R; L m- c构建以下表单:
7 L+ G5 T! D, g1 G0 X% ]
* R- r4 o% d$ W9 W6 R<form action="http://t.thinksns.com/index.php?app=w3g&mod=Index&act=doPost" method="post" enctype="multipart/form-data" />
1 u- v4 q6 R+ P i5 p+ g2 z<textarea name="content">test</textarea>
# d- s% T) Y$ [' t3 \) _- }# hfile: <input id="file" type="file" name="pic" />) T; a! Z" Y" h" P6 r p
<input type="submit" value="Post" />% F) K3 ]& M3 r. A
</form>3 R5 T, b9 \7 D; e6 n9 L
去掉缩略图的前缀(small_ ): S5 Y j' Z4 R2 I1 _* ~
修复方案:
/ p+ U- W" l/ @! S+ x# b3 C( ^6 K8 g: j: s ] R k
* P" B7 T0 u B' w( Y3 ^0 ?\api\StatusesApi.class.php
, h- l6 b/ C7 ^3 \' E# ? V
- b* B3 H% \( D1 `0 I" Efunction uploadpic(){
4 R) U& @% C5 X7 m /**8 E6 {' Z3 g8 g f0 c
* 20121018 @yelo. }3 T5 C- H! h* J
* 增加上传类型验证- n, x: u7 {! E; O
*/
: `& v( }& u# }* w $pathinfo = pathinfo($_FILES['pic']['name']);
6 d6 K% h) N9 d, @5 K+ d9 l8 s $ext = $pathinfo['extension'];0 J8 ^+ n( r5 u# R0 O
$allowExts = array('jpg', 'png', 'gif', 'jpeg');
# V8 B' o o# v5 }
( a. E' p; `2 i* p3 O. o $uploadCondition = $_FILES['pic'] && in_array(strtolower($ext),$allowExts,true);0 w; w0 N2 R) G5 S, Q6 Q/ Z
' d+ t; O1 B& q/ X2 T% b1 a0 ]- w
if( $uploadCondition ){7 i1 y2 [; s E* U
//执行上传操作 |: Q- U8 c% m U- |
$savePath = $this->_getSaveTempPath();* y7 w2 V1 w7 E8 Z& H5 i5 p
$filename = md5( time().'teste' ).'.'.substr($_FILES['pic']['name'],strpos($_FILES['pic']['name'],'.')+1);
6 V' N$ q, x9 L, u3 ?% E* v' X if(@copy($_FILES['pic']['tmp_name'], $savePath.'/'.$filename) || @move_uploaded_file($_FILES['pic']['tmp_name'], $savePath.'/'.$filename)). n5 P3 ^- w$ u3 W, U! T2 z
{
' w0 _: ~! {, ? $result['boolen'] = 1;% W) T: a. u, y5 V: ]
$result['type_data'] = 'temp/'.$filename;: B. G9 y) H3 U* y. q' {
$result['picurl'] = SITE_PATH.'/uploads/temp/'.$filename;/ Z: J C# `. A
} else {+ { L3 j, |: u$ Q
$result['boolen'] = 0;
6 Z: w& k. R0 D- g8 ^ $result['message'] = '上传失败';
- f, P; y% ~# N }
7 g5 J6 P3 l1 q1 ~/ \$ d }else{
) J5 k3 d( M$ p% i4 V6 [# M $result['boolen'] = 0;
; D/ ?! R# D: d3 I7 g) r $result['message'] = '上传失败';" |2 ^( } O0 \) P2 R
}2 |# h: ~- L0 N5 _% }. V* Z
return $result;0 T# }5 o8 J$ t k
}
/ s8 [) b; r4 P! j4 Y: y, J4 k& ~' j6 M
; R, @# ~: v; R) T/ Q2 o4 b/ {! { |