Permalink
Browse files

fix pingback's security issue

  • Loading branch information...
joyqi committed Oct 12, 2017
1 parent 0e7b399 commit eeedef972a5c17f328c158b0055cec41cfb9d1d3
Showing with 77 additions and 3 deletions.
  1. +62 −1 var/Typecho/Common.php
  2. +5 −1 var/Typecho/Http/Client/Adapter.php
  3. +0 −1 var/Widget/Service.php
  4. +10 −0 var/Widget/XmlRpc.php
View
@@ -22,7 +22,7 @@
class Typecho_Common
{
/** 程序版本 */
const VERSION = '1.1/17.8.17';
const VERSION = '1.1/17.10.13';
/**
* 允许的属性
@@ -1105,6 +1105,67 @@ public static function extractBackupBuffer($fp, &$offset)
return array($type, $header, $body);
}
/**
* 检查是否是一个安全的主机名
*
* @param $host
* @return bool
*/
public static function checkSafeHost($host)
{
if ('localhost' == $host) {
return false;
}
$address = gethostbyname($host);
$inet = inet_pton($address);
if ($inet === false) {
// 有可能是ipv6的地址
$records = dns_get_record($host, DNS_AAAA);
if (empty($records)) {
return false;
}
$address = $records[0]['ipv6'];
$inet = inet_pton($address);
}
if (strpos($address, '.')) {
// ipv4
// 非公网地址
$privateNetworks = array(
'10.0.0.0|10.255.255.255',
'172.16.0.0|172.31.255.255',
'192.168.0.0|192.168.255.255',
'169.254.0.0|169.254.255.255',
'127.0.0.0|127.255.255.255'
);
$long = ip2long($address);
foreach ($privateNetworks as $network) {
list ($from, $to) = explode('|', $network);
if ($long >= ip2long($from) && $long <= ip2long($to)) {
return false;
}
}
} else {
// ipv6
// https://en.wikipedia.org/wiki/Private_network
$from = inet_pton('fd00::');
$to = inet_pton('fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff');
if ($inet >= $from && $inet <= $to) {
return false;
}
}
return true;
}
/**
* 获取图片
*
@@ -294,8 +294,8 @@ public function setHeader($key, $value)
*
* @access public
* @param string $url 请求地址
* @param string $rfc 请求协议
* @return string
* @throws Typecho_Http_Client_Exception
*/
public function send($url)
{
@@ -307,6 +307,10 @@ public function send($url)
throw new Typecho_Http_Client_Exception('Unknown Host', 500);
}
if (!in_array($params['scheme'], array('http', 'https'))) {
throw new Typecho_Http_Client_Exception('Unknown Scheme', 500);
}
if (!empty($params['path'])) {
$this->path = $params['path'];
}
View
@@ -140,7 +140,6 @@ public function sendPing($cid, array $trackback = NULL)
->setHeader('User-Agent', $this->options->generator)
->setTimeout(3)
->setData($input)
->setIp('127.0.0.1')
->send(Typecho_Common::url('/action/service', $this->options->index));
} catch (Typecho_Http_Client_Exception $e) {
View
@@ -2057,6 +2057,16 @@ public function pingbackPing($source, $target)
$pathInfo = Typecho_Common::url(substr($target, strlen($this->options->index)), '/');
$post = Typecho_Router::match($pathInfo);
/** 检查源地址是否合法 */
$params = parse_url($source);
if (false === $params || !in_array($params['scheme'], array('http', 'https'))) {
return new IXR_Error(16, _t('源地址服务器错误'));
}
if (!Typecho_Common::checkSafeHost($params['host'])) {
return new IXR_Error(16, _t('源地址服务器错误'));
}
/** 这样可以得到cid或者slug*/
if (!($post instanceof Widget_Archive) || !$post->have() || !$post->is('single')) {
return new IXR_Error(33, _t('这个目标地址不存在'));

0 comments on commit eeedef9

Please sign in to comment.