Skip to content

Commit 43132e1

Browse files
authored
Merge pull request #269 from dodgepudding/master
XXE外部实体注入漏洞
2 parents c7c9726 + 8dd4ca8 commit 43132e1

File tree

7 files changed

+828
-27
lines changed

7 files changed

+828
-27
lines changed

Codeigniter/CI_Wechat.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
defined('BASEPATH') OR exit('No direct script access allowed');
3+
4+
/**
5+
* 微信公众平台PHP-SDK, Codeigniter实例
6+
* @author nigelvon@gmail.com
7+
* @link https://github.com/dodgepudding/wechat-php-sdk
8+
* usage:
9+
* $this->load->library('CI_Wechat');
10+
* $this->ci_wechat->valid();
11+
* ...
12+
*
13+
*/
14+
require_once(dirname(__FILE__) . '/wechat-php-sdk/wechat.class.php');
15+
16+
class CI_Wechat extends Wechat {
17+
protected $_CI;
18+
public function __construct() {
19+
$this->_CI =& get_instance();
20+
$this->_CI->config->load('wechat');
21+
$options = $this->_CI->config->item('wechat');
22+
23+
$this->_CI->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));
24+
25+
parent::__construct($options);
26+
}
27+
28+
/**
29+
* 重载设置缓存
30+
* @param string $cachename
31+
* @param mixed $value
32+
* @param int $expired
33+
* @return boolean
34+
*/
35+
protected function setCache($cachename, $value, $expired) {
36+
return $this->_CI->cache->save($cachename, $value, $expired);
37+
}
38+
39+
/**
40+
* 重载获取缓存
41+
* @param string $cachename
42+
* @return mixed
43+
*/
44+
protected function getCache($cachename) {
45+
return $this->_CI->cache->get($cachename);
46+
}
47+
48+
/**
49+
* 重载清除缓存
50+
* @param string $cachename
51+
* @return boolean
52+
*/
53+
protected function removeCache($cachename) {
54+
return $this->_CI->cache->delete($cachename);
55+
}
56+
}
57+
58+
/* End of file CI_Wechat.php */
59+
/* Location: ./application/libraries/CI_Wechat.php */

Thinkphp/JsSdkPay.class.php

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
<?php
2+
/**
3+
* 官方文档:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
4+
* 微信支付:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_1#
5+
* 官方示例:http://demo.open.weixin.qq.com/jssdk/sample.zip
6+
* UCToo示例:http://git.oschina.net/uctoo/uctoo/blob/master/Addons/Jssdk/Controller/JssdkController.class.php
7+
*
8+
* 微信JSSDK支付类,主要实现了微信JSSDK支付,参考官方提供的示例文档,
9+
* @命名空间版本
10+
* @author uctoo (www.uctoo.com)
11+
* @date 2015-5-15 14:10
12+
*/
13+
namespace Com;
14+
15+
class JsSdkPay {
16+
private $appId;
17+
private $appSecret;
18+
public $debug = false;
19+
public $weObj; //微信类实例
20+
public $parameters;//获取prepay_id时的请求参数
21+
//受理商ID,身份标识
22+
public $MCHID = '';
23+
//商户支付密钥Key。审核通过后,在微信商户平台中查看 https://pay.weixin.qq.com
24+
public $KEY = '';
25+
26+
//=======【JSAPI路径设置】===================================
27+
//获取access_token过程中的跳转uri,通过跳转将code传入jsapi支付页面
28+
public $JS_API_CALL_URL = '';
29+
30+
//=======【证书路径设置】=====================================
31+
//证书路径,注意应该填写绝对路径
32+
public $SSLCERT_PATH = '/xxx/xxx/xxxx/WxPayPubHelper/cacert/apiclient_cert.pem';
33+
public $SSLKEY_PATH = '/xxx/xxx/xxxx/WxPayPubHelper/cacert/apiclient_key.pem';
34+
35+
//=======【异步通知url设置】===================================
36+
//异步通知url,商户根据实际开发过程设定
37+
//C('url')."admin.php/order/notify_url.html";
38+
public $NOTIFY_URL = '';
39+
40+
//=======【curl超时设置】===================================
41+
//本例程通过curl使用HTTP POST方法,此处可修改其超时时间,默认为30秒
42+
public $CURL_TIMEOUT = 30;
43+
44+
public $prepay_id;
45+
46+
public function __construct($options) {
47+
$this->appId = $options['appid'];
48+
$this->appSecret = $options['appsecret'];
49+
$this->weObj = new TPWechat($options);
50+
}
51+
52+
//微信支付相关方法
53+
/**
54+
* 作用:格式化参数,签名过程需要使用
55+
*/
56+
function formatBizQueryParaMap($paraMap, $urlencode)
57+
{
58+
$buff = "";
59+
ksort($paraMap);
60+
foreach ($paraMap as $k => $v)
61+
{
62+
if($urlencode)
63+
{
64+
$v = urlencode($v);
65+
}
66+
//$buff .= strtolower($k) . "=" . $v . "&";
67+
$buff .= $k . "=" . $v . "&";
68+
}
69+
$reqPar = "";
70+
if (strlen($buff) > 0)
71+
{
72+
$reqPar = substr($buff, 0, strlen($buff)-1);
73+
}
74+
return $reqPar;
75+
}
76+
/**
77+
* 作用:设置jsapi的参数
78+
*/
79+
public function getParameters()
80+
{
81+
$jsApiObj["appId"] = $this->appId; //请求生成支付签名时需要,js调起支付参数中不需要
82+
$timeStamp = time();
83+
$jsApiObj["timeStamp"] = "$timeStamp"; //用大写的timeStamp参数请求生成支付签名
84+
$jsParamObj["timestamp"] = $timeStamp; //用小写的timestamp参数生成js支付参数,还要注意数据类型,坑!
85+
$jsParamObj["nonceStr"] = $jsApiObj["nonceStr"] = $this->weObj->generateNonceStr();
86+
$jsParamObj["package"] = $jsApiObj["package"] = "prepay_id=$this->prepay_id";
87+
$jsParamObj["signType"] = $jsApiObj["signType"] = "MD5";
88+
$jsParamObj["paySign"] = $jsApiObj["paySign"] = $this->getSign($jsApiObj);
89+
90+
$jsParam = json_encode($jsParamObj);
91+
92+
return $jsParam;
93+
}
94+
95+
/**
96+
* 获取prepay_id
97+
*/
98+
function getPrepayId()
99+
{
100+
$result = $this->xmlToArray($this->postXml());
101+
$prepay_id = $result["prepay_id"];
102+
return $prepay_id;
103+
}
104+
/**
105+
* 作用:将xml转为array
106+
*/
107+
public function xmlToArray($xml)
108+
{
109+
//将XML转为array
110+
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
111+
return $array_data;
112+
}
113+
/**
114+
* 作用:post请求xml
115+
*/
116+
function postXml()
117+
{
118+
$xml = $this->createXml();
119+
return $this->postXmlCurl($xml,"https://api.mch.weixin.qq.com/pay/unifiedorder",$this->CURL_TIMEOUT);
120+
121+
}
122+
/**
123+
* 作用:以post方式提交xml到对应的接口url
124+
*/
125+
public function postXmlCurl($xml,$url,$second=30)
126+
{
127+
//初始化curl
128+
$ch = curl_init();
129+
//设置超时
130+
curl_setopt($ch,CURLOP_TIMEOUT, $this->CURL_TIMEOUT);
131+
//这里设置代理,如果有的话
132+
//curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
133+
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
134+
curl_setopt($ch,CURLOPT_URL, $url);
135+
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
136+
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
137+
//设置header
138+
curl_setopt($ch, CURLOPT_HEADER, FALSE);
139+
//要求结果为字符串且输出到屏幕上
140+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
141+
//post提交方式
142+
curl_setopt($ch, CURLOPT_POST, TRUE);
143+
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
144+
//运行curl
145+
$data = curl_exec($ch);
146+
curl_close($ch);
147+
//返回结果
148+
if($data)
149+
{
150+
curl_close($ch);
151+
return $data;
152+
}
153+
else
154+
{
155+
$error = curl_errno($ch);
156+
echo "curl出错,错误码:$error"."<br>";
157+
echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
158+
curl_close($ch);
159+
return false;
160+
}
161+
}
162+
/**
163+
* 作用:设置标配的请求参数,生成签名,生成接口参数xml
164+
*/
165+
function createXml()
166+
{
167+
$this->parameters["appid"] = $this->appId;//公众账号ID
168+
$this->parameters["mch_id"] = $this->MCHID;//商户号
169+
$this->parameters["nonce_str"] = $this->weObj->generateNonceStr();//随机字符串
170+
$this->parameters["sign"] = $this->getSign($this->parameters);//签名
171+
return $this->arrayToXml($this->parameters);
172+
}
173+
/**
174+
* 作用:array转xml
175+
*/
176+
function arrayToXml($arr)
177+
{
178+
$xml = "<xml>";
179+
foreach ($arr as $key=>$val)
180+
{
181+
if (is_numeric($val))
182+
{
183+
$xml.="<".$key.">".$val."</".$key.">";
184+
185+
}
186+
else
187+
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
188+
}
189+
$xml.="</xml>";
190+
return $xml;
191+
}
192+
/**
193+
* 作用:生成签名
194+
*/
195+
public function getSign($Obj)
196+
{
197+
foreach ($Obj as $k => $v)
198+
{
199+
$Parameters[$k] = $v;
200+
}
201+
//签名步骤一:按字典序排序参数
202+
ksort($Parameters);
203+
$String = $this->formatBizQueryParaMap($Parameters, false);
204+
//echo '【string1】'.$String.'</br>';
205+
//签名步骤二:在string后加入KEY
206+
$String = $String."&key=".$this->KEY;
207+
//echo "【string2】".$String."</br>";
208+
//签名步骤三:MD5加密
209+
$String = md5($String);
210+
//echo "【string3】 ".$String."</br>";
211+
//签名步骤四:所有字符转为大写
212+
$result_ = strtoupper($String);
213+
//echo "【result】 ".$result_."</br>";
214+
return $result_;
215+
}
216+
217+
}
218+

Thinkphp/Wxauth.class.php

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
/**
3+
* 微信oAuth认证示例
4+
* 官方文档:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
5+
* UCToo示例:http://git.oschina.net/uctoo/uctoo/blob/master/Addons/Ucuser/UcuserAddon.class.php
6+
*
7+
* 微信oAuth认证类,适配Thinkphp框架,
8+
* @命名空间版本
9+
* @author uctoo (www.uctoo.com)
10+
* @date 2015-5-15 14:10
11+
*/
12+
namespace Com;
13+
14+
class Wxauth {
15+
private $options;
16+
public $open_id;
17+
public $wxuser;
18+
19+
public function __construct($options){
20+
$this->options = $options;
21+
$this->wxoauth();
22+
}
23+
24+
public function wxoauth(){
25+
$scope = 'snsapi_base';
26+
$code = isset($_GET['code'])?$_GET['code']:'';
27+
$token_time = isset($_SESSION['token_time'])?$_SESSION['token_time']:0;
28+
if(!$code && isset($_SESSION['open_id']) && isset($_SESSION['user_token']) && $token_time>time()-3600)
29+
{
30+
if (!$this->wxuser) {
31+
$this->wxuser = $_SESSION['wxuser'];
32+
}
33+
$this->open_id = $_SESSION['open_id'];
34+
return $this->open_id;
35+
}
36+
else
37+
{
38+
39+
$options = array(
40+
'token'=>$this->options["token"], //填写你设定的key
41+
'encodingaeskey'=>$this->options["encodingaeskey"], //填写加密用的EncodingAESKey
42+
'appid'=>$this->options["appid"], //填写高级调用功能的app id
43+
'appsecret'=>$this->options["appsecret"] //填写高级调用功能的密钥
44+
);
45+
$we_obj = new TPWechat($options);
46+
if ($code) {
47+
$json = $we_obj->getOauthAccessToken();
48+
if (!$json) {
49+
unset($_SESSION['wx_redirect']);
50+
die('获取用户授权失败,请重新确认');
51+
}
52+
$_SESSION['open_id'] = $this->open_id = $json["openid"];
53+
$access_token = $json['access_token'];
54+
$_SESSION['user_token'] = $access_token;
55+
$_SESSION['token_time'] = time();
56+
$userinfo = $we_obj->getUserInfo($this->open_id);
57+
if ($userinfo && !empty($userinfo['nickname'])) {
58+
$this->wxuser = array(
59+
'open_id'=>$this->open_id,
60+
'nickname'=>$userinfo['nickname'],
61+
'sex'=>intval($userinfo['sex']),
62+
'location'=>$userinfo['province'].'-'.$userinfo['city'],
63+
'avatar'=>$userinfo['headimgurl']
64+
);
65+
} elseif (strstr($json['scope'],'snsapi_userinfo')!==false) {
66+
$userinfo = $we_obj->getOauthUserinfo($access_token,$this->open_id);
67+
if ($userinfo && !empty($userinfo['nickname'])) {
68+
$this->wxuser = array(
69+
'open_id'=>$this->open_id,
70+
'nickname'=>$userinfo['nickname'],
71+
'sex'=>intval($userinfo['sex']),
72+
'location'=>$userinfo['province'].'-'.$userinfo['city'],
73+
'avatar'=>$userinfo['headimgurl']
74+
);
75+
} else {
76+
return $this->open_id;
77+
}
78+
}
79+
if ($this->wxuser) {
80+
$_SESSION['wxuser'] = $this->wxuser;
81+
$_SESSION['open_id'] = $json["openid"];
82+
unset($_SESSION['wx_redirect']);
83+
return $this->open_id;
84+
}
85+
$scope = 'snsapi_userinfo';
86+
}
87+
if ($scope=='snsapi_base') {
88+
$url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
89+
$_SESSION['wx_redirect'] = $url;
90+
} else {
91+
$url = $_SESSION['wx_redirect'];
92+
}
93+
if (!$url) {
94+
unset($_SESSION['wx_redirect']);
95+
die('获取用户授权失败');
96+
}
97+
$oauth_url = $we_obj->getOauthRedirect($url,"wxbase",$scope);
98+
redirect ( $oauth_url );
99+
}
100+
}
101+
}
102+
//$options = array(
103+
// 'token'=>'uctoo', //填写你设定的key
104+
// 'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询
105+
// 'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥
106+
//);
107+
//$auth = new Wxauth($options);
108+
//var_dump($auth->wxuser);

qywechat.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ static function json_encode($arr) {
202202
elseif ($value === true)
203203
$str .= 'true';
204204
else
205-
$str .= '"' . addslashes ( $value ) . '"'; //All other things
205+
$str .= '"' .addcslashes($value, "\\\"\n\r\t/"). '"'; //All other things
206206
// :TODO: Is there any more datatype we should be in the lookout for? (Object?)
207207
$parts [] = $str;
208208
}

0 commit comments

Comments
 (0)