diff --git a/install.php b/install.php index 27d8a721..14f1b2ad 100644 --- a/install.php +++ b/install.php @@ -307,6 +307,7 @@ list($prefixVersion, $suffixVersion) = explode('/', $currentVersion); $installDb->query($installDb->insert('table.options')->rows(array('name' => 'actionTable', 'user' => 0, 'value' => 'a:0:{}'))); $installDb->query($installDb->insert('table.options')->rows(array('name' => 'panelTable', 'user' => 0, 'value' => 'a:0:{}'))); $installDb->query($installDb->insert('table.options')->rows(array('name' => 'attachmentTypes', 'user' => 0, 'value' => '@image@'))); + $installDb->query($installDb->insert('table.options')->rows(array('name' => 'secret', 'user' => 0, 'value' => Typecho_Common::randString(32, true)))); /** 初始分类 */ $installDb->query($installDb->insert('table.metas')->rows(array('name' => _t('默认分类'), 'slug' => 'default', 'type' => 'category', 'description' => _t('只是一个默认分类'), diff --git a/var/Typecho/Common.php b/var/Typecho/Common.php index 8fad579a..3f2da629 100644 --- a/var/Typecho/Common.php +++ b/var/Typecho/Common.php @@ -22,7 +22,7 @@ define('__TYPECHO_MB_SUPPORTED__', function_exists('mb_get_info')); class Typecho_Common { /** 程序版本 */ - const VERSION = '0.9/14.2.24'; + const VERSION = '0.9/14.3.14'; /** * 锁定的代码块 diff --git a/var/Upgrade.php b/var/Upgrade.php index a09dc4e2..aea5d788 100644 --- a/var/Upgrade.php +++ b/var/Upgrade.php @@ -1161,5 +1161,19 @@ Typecho_Date::setTimezoneOffset($options->timezone); break; } } -} + + /** + * v0_9r14_3_14 + * + * @param mixed $db + * @param mixed $options + * @access public + * @return void + */ + public function v0_9r14_3_14($db, $options) + { + $db->query($db->insert('table.options') + ->rows(array('name' => 'secret', 'user' => 0, 'value' => Typecho_Common::randString(32, true)))); + } +} diff --git a/var/Widget/Abstract/Contents.php b/var/Widget/Abstract/Contents.php index 9f0517f2..5c4bc757 100644 --- a/var/Widget/Abstract/Contents.php +++ b/var/Widget/Abstract/Contents.php @@ -717,7 +717,7 @@ class Widget_Abstract_Contents extends Widget_Abstract /** 处理密码保护流程 */ if (!empty($value['password']) && - $value['password'] != $this->request->protectPassword && + $value['password'] != Typecho_Cookie::get('protectPassword') && $value['authorId'] != $this->user->uid && !$this->user->pass('editor', true)) { $value['hidden'] = true; @@ -732,7 +732,8 @@ class Widget_Abstract_Contents extends Widget_Abstract /** 如果访问权限被禁止 */ if ($value['hidden']) { - $value['text'] = '
' . + $value['text'] = '' . '

' . _t('请输入密码访问') . '

' . '

' . diff --git a/var/Widget/Archive.php b/var/Widget/Archive.php index e1951ac9..a0d42bda 100644 --- a/var/Widget/Archive.php +++ b/var/Widget/Archive.php @@ -292,7 +292,7 @@ class Widget_Archive extends Widget_Abstract_Contents * 评论地址 * * @access protected - * @return void + * @return string */ protected function ___commentUrl() { @@ -306,7 +306,7 @@ class Widget_Archive extends Widget_Abstract_Contents $commentUrl .= '?parent=' . $reply; } - return $commentUrl; + return $this->security->getTokenUrl($commentUrl); } /** @@ -320,7 +320,7 @@ class Widget_Archive extends Widget_Abstract_Contents } /** - * @param $_archiveSlug the $_archiveSlug to set + * @param string $archiveSlug the $_archiveSlug to set */ public function setArchiveSlug($archiveSlug) { @@ -328,7 +328,7 @@ class Widget_Archive extends Widget_Abstract_Contents } /** - * @param $_archiveSingle the $_archiveSingle to set + * @param string $archiveSingle the $_archiveSingle to set */ public function setArchiveSingle($archiveSingle) { @@ -795,6 +795,7 @@ class Widget_Archive extends Widget_Abstract_Contents /** 保存密码至cookie */ if ($this->request->isPost() && isset($this->request->protectPassword)) { + $this->security->protect(); Typecho_Cookie::set('protectPassword', $this->request->protectPassword, 0); } @@ -1475,7 +1476,7 @@ class Widget_Archive extends Widget_Abstract_Contents * 获取回响归档对象 * * @access public - * @return void + * @return Widget_Comments_Ping */ public function pings() { diff --git a/var/Widget/Feedback.php b/var/Widget/Feedback.php index 0489ef7c..a0c2c9b6 100644 --- a/var/Widget/Feedback.php +++ b/var/Widget/Feedback.php @@ -37,6 +37,9 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa */ private function comment() { + // 使用安全模块保护 + $this->security->protect(); + $comment = array( 'cid' => $this->_content->cid, 'created' => $this->options->gmtTime, diff --git a/var/Widget/Login.php b/var/Widget/Login.php index 6d2568b4..597a559b 100644 --- a/var/Widget/Login.php +++ b/var/Widget/Login.php @@ -28,6 +28,9 @@ class Widget_Login extends Widget_Abstract_Users implements Widget_Interface_Do */ public function action() { + // protect + $this->security->protect(); + /** 如果已经登录 */ if ($this->user->hasLogin()) { /** 直接返回 */ diff --git a/var/Widget/Options.php b/var/Widget/Options.php index a893f019..c569447a 100644 --- a/var/Widget/Options.php +++ b/var/Widget/Options.php @@ -201,8 +201,9 @@ class Widget_Options extends Typecho_Widget */ protected function ___loginAction() { - return Typecho_Router::url('do', array('action' => 'login', 'widget' => 'Login'), - Typecho_Common::url('index.php', $this->rootUrl)); + return $this->widget('Widget_Security')->getTokenUrl( + Typecho_Router::url('do', array('action' => 'login', 'widget' => 'Login'), + Typecho_Common::url('index.php', $this->rootUrl))); } /** @@ -224,7 +225,8 @@ class Widget_Options extends Typecho_Widget */ protected function ___registerAction() { - return Typecho_Router::url('do', array('action' => 'register', 'widget' => 'Register'), $this->index); + return $this->widget('Widget_Security')->getTokenUrl( + Typecho_Router::url('do', array('action' => 'register', 'widget' => 'Register'), $this->index)); } /** diff --git a/var/Widget/Options/General.php b/var/Widget/Options/General.php index 641fe022..c3c777dc 100644 --- a/var/Widget/Options/General.php +++ b/var/Widget/Options/General.php @@ -179,8 +179,12 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I $attachmentTypesOther = $this->request->filter('trim', 'strtolower')->attachmentTypesOther; if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@other@') && !empty($attachmentTypesOther)) { - $attachmentTypes[] = implode(',', - array_filter(array_map('trim', explode(',', $attachmentTypesOther)), array($this, 'removeShell'))); + $types = implode(',', array_filter(array_map('trim', + explode(',', $attachmentTypesOther)), array($this, 'removeShell'))); + + if (!empty($types)) { + $attachmentTypes[] = $types; + } } $settings['attachmentTypes'] = implode(',', $attachmentTypes); diff --git a/var/Widget/Register.php b/var/Widget/Register.php index 10e2d672..abd3af2d 100644 --- a/var/Widget/Register.php +++ b/var/Widget/Register.php @@ -17,6 +17,9 @@ class Widget_Register extends Widget_Abstract_Users implements Widget_Interface_ */ public function action() { + // protect + $this->security->protect(); + /** 如果已经登录 */ if ($this->user->hasLogin() || !$this->options->allowRegister) { /** 直接返回 */ diff --git a/var/Widget/Security.php b/var/Widget/Security.php index a3aacc4b..e1562e8d 100644 --- a/var/Widget/Security.php +++ b/var/Widget/Security.php @@ -30,13 +30,21 @@ class Widget_Security extends Typecho_Widget $this->_options = $this->widget('Widget_Options'); $user = $this->widget('Widget_User'); - $token = uniqid(); + $this->_token = $this->_options->secret; if ($user->hasLogin()) { - $token = $user->authCode . '&' . $user->uid - . '&' . $this->request->getRequestUrl(); + $this->_token .= '&' . $user->authCode . '&' . $user->uid; } + } - $this->_token = md5($token); + /** + * 获取token + * + * @param string $suffix 后缀 + * @return string + */ + public function getToken($suffix) + { + return md5($this->_token . '&' . $suffix); } /** @@ -54,7 +62,7 @@ class Widget_Security extends Typecho_Widget parse_str($parts['query'], $params); } - $params['_'] = $this->_token; + $params['_'] = $this->getToken($this->request->getRequestUrl()); $parts['query'] = http_build_query($params); return Typecho_Common::buildUrl($parts); @@ -66,16 +74,8 @@ class Widget_Security extends Typecho_Widget */ public function protect() { - $user = $this->widget('Widget_User'); - $token = uniqid(); - if ($user->hasLogin()) { - $token = $user->authCode . '&' . $user->uid - . '&' . $this->request->getReferer(); - } - - if ($this->request->get('_') != md5($token)) { - $this->widget('Widget_Notice')->set(_t('一次不安全的跳转已经被阻止')); - $this->response->redirect($this->_options->adminUrl); + if ($this->request->get('_') != $this->getToken($this->request->getReferer())) { + $this->response->goBack(); } }