diff --git a/docs/NEWS b/docs/NEWS index a320f62a..88e2f0a8 100644 --- a/docs/NEWS +++ b/docs/NEWS @@ -1,5 +1,20 @@ # +Version 1.7.9 () +------------------------------------------------------------------------ + + * Fix security issues reported by Tim Coen of Curesec.com: + + - Forbid uploading files with PHP contents and possible + PHP execution by authenticated users (critical if + you have possible untrustworthy authors) + - Add proper escaping for comment approval tokens to prevent + SQL injection (authenticated authors only) + - Add proper escaping of comment's author names in the + comment reply form to prevent XSS (2k11 template, javascript + based) + + Version 1.7.8 (February 9th, 2014) ------------------------------------------------------------------------ diff --git a/docs/RELEASE b/docs/RELEASE index 3832a6ff..3f7faaba 100644 --- a/docs/RELEASE +++ b/docs/RELEASE @@ -1,2 +1,2 @@ -stable:1.7.8 -beta:2.0-rc2 +stable:2.0.2 +beta:2.1-alpha2 diff --git a/include/admin/comments.inc.php b/include/admin/comments.inc.php index 07a997c4..d9b29a30 100644 --- a/include/admin/comments.inc.php +++ b/include/admin/comments.inc.php @@ -18,7 +18,7 @@ $errormsg = ''; if ($serendipity['POST']['formAction'] == 'multiDelete' && sizeof($serendipity['POST']['delete']) != 0 && serendipity_checkFormToken()) { if ($serendipity['POST']['togglemoderate'] != '') { foreach ( $serendipity['POST']['delete'] as $k => $v ) { - $ac = serendipity_approveComment($k, $v, false, 'flip'); + $ac = serendipity_approveComment((int)$k, (int)$v, false, 'flip'); if ($ac > 0) { $errormsg .= DONE . ': '. sprintf(COMMENT_APPROVED, (int)$k) . '
'; } else { @@ -86,7 +86,7 @@ if (isset($serendipity['GET']['adminAction']) && $serendipity['GET']['adminActio if ($rs === false) { $errormsg .= ERROR .': '. sprintf(COMMENT_ALREADY_APPROVED, (int)$serendipity['GET']['id']); } else { - serendipity_approveComment($serendipity['GET']['id'], $rs['entry_id']); + serendipity_approveComment((int)$serendipity['GET']['id'], (int)$rs['entry_id']); $errormsg .= DONE . ': '. sprintf(COMMENT_APPROVED, (int)$serendipity['GET']['id']); } } @@ -102,7 +102,7 @@ if (isset($serendipity['GET']['adminAction']) && $serendipity['GET']['adminActio if ($rs === false) { $errormsg .= ERROR .': '. sprintf(COMMENT_ALREADY_APPROVED, (int)$serendipity['GET']['id']); } else { - serendipity_approveComment($serendipity['GET']['id'], $rs['entry_id'], true, true); + serendipity_approveComment((int)$serendipity['GET']['id'], (int)$rs['entry_id'], true, true); $errormsg .= DONE . ': '. sprintf(COMMENT_MODERATED, (int)$serendipity['GET']['id']); } } diff --git a/include/functions_comments.inc.php b/include/functions_comments.inc.php index 944e1e92..77ea4182 100644 --- a/include/functions_comments.inc.php +++ b/include/functions_comments.inc.php @@ -29,14 +29,14 @@ function serendipity_checkCommentToken($token, $cid) { WHERE okey LIKE 'comment_%' AND name < " . (time() - 604800) ); // Get the token for this comment id $tokencheck = serendipity_db_query("SELECT * FROM {$serendipity['dbPrefix']}options - WHERE okey = 'comment_" . $cid . "' LIMIT 1", true, 'assoc'); + WHERE okey = 'comment_" . (int)$cid . "' LIMIT 1", true, 'assoc'); // Verify it against the passed key if (is_array($tokencheck)) { if ($tokencheck['value'] == $token) { $goodtoken = true; // use this to bypass security checks later // if using tokens, delete this comment from that list no matter how we got here serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}options - WHERE okey = 'comment_" . $cid . "'"); + WHERE okey = 'comment_" . (int)$cid . "'"); } } diff --git a/include/functions_images.inc.php b/include/functions_images.inc.php index c9ec3ba0..c3af0ef1 100644 --- a/include/functions_images.inc.php +++ b/include/functions_images.inc.php @@ -24,7 +24,7 @@ function serendipity_isActiveFile($file) { return true; } - $core = preg_match('@\.(php.*|[psj]html?|aspx?|cgi|jsp|py|pl)$@i', $file); + $core = preg_match('@\.(php.*|[psj]html?|pht|aspx?|cgi|jsp|py|pl)$@i', $file); if ($core) { return true; } diff --git a/serendipity_config.inc.php b/serendipity_config.inc.php index c1be1333..12f41b6b 100644 --- a/serendipity_config.inc.php +++ b/serendipity_config.inc.php @@ -45,7 +45,7 @@ if (defined('USE_MEMSNAP')) { } // The version string -$serendipity['version'] = '1.7.8'; +$serendipity['version'] = '1.7.9'; // Setting this to 'false' will enable debugging output. All alpa/beta/cvs snapshot versions will emit debug information by default. To increase the debug level (to enable Smarty debugging), set this flag to 'debug'. if (!isset($serendipity['production'])) { diff --git a/templates/2k11/js/2k11.min.js b/templates/2k11/js/2k11.min.js index 05b6cfe4..8d54e3f2 100644 --- a/templates/2k11/js/2k11.min.js +++ b/templates/2k11/js/2k11.min.js @@ -19,4 +19,4 @@ var AccessifyHTML5=function(a,b){"use strict";var f,g,h,i,j,k,l,m,n,o,c={article /*! http://mths.be/placeholder v2.0.7 by @mathias */ !function(a,b,c){function k(a){var b={},d=/^jQuery\d+$/;return c.each(a.attributes,function(a,c){c.specified&&!d.test(c.name)&&(b[c.name]=c.value)}),b}function l(a,b){var d=this,e=c(d);if(d.value==e.attr("placeholder")&&e.hasClass("placeholder"))if(e.data("placeholder-password")){if(e=e.hide().next().show().attr("id",e.removeAttr("id").data("placeholder-id")),a===!0)return e[0].value=b;e.focus()}else d.value="",e.removeClass("placeholder"),d==n()&&d.select()}function m(){var a,b=this,d=c(b),e=this.id;if(""==b.value){if("password"==b.type){if(!d.data("placeholder-textinput")){try{a=d.clone().attr({type:"text"})}catch(f){a=c("").attr(c.extend(k(this),{type:"text"}))}a.removeAttr("name").data({"placeholder-password":d,"placeholder-id":e}).bind("focus.placeholder",l),d.data({"placeholder-textinput":a,"placeholder-id":e}).before(a)}d=d.removeAttr("id").hide().prev().attr("id",e).show()}d.addClass("placeholder"),d[0].value=d.attr("placeholder")}else d.removeClass("placeholder")}function n(){try{return b.activeElement}catch(a){}}var i,j,d="placeholder"in b.createElement("input"),e="placeholder"in b.createElement("textarea"),f=c.fn,g=c.valHooks,h=c.propHooks;d&&e?(j=f.placeholder=function(){return this},j.input=j.textarea=!0):(j=f.placeholder=function(){var a=this;return a.filter((d?"textarea":":input")+"[placeholder]").not(".placeholder").bind({"focus.placeholder":l,"blur.placeholder":m}).data("placeholder-enabled",!0).trigger("blur.placeholder"),a},j.input=d,j.textarea=e,i={get:function(a){var b=c(a),d=b.data("placeholder-password");return d?d[0].value:b.data("placeholder-enabled")&&b.hasClass("placeholder")?"":a.value},set:function(a,b){var d=c(a),e=d.data("placeholder-password");return e?e[0].value=b:d.data("placeholder-enabled")?(""==b?(a.value=b,a!=n()&&m.call(a)):d.hasClass("placeholder")?l.call(a,!0,b)||(a.value=b):a.value=b,d):a.value=b}},d||(g.input=i,h.value=i),e||(g.textarea=i,h.value=i),c(function(){c(b).delegate("form","submit.placeholder",function(){var a=c(".placeholder",this).each(l);setTimeout(function(){a.each(m)},10)})}),c(a).bind("beforeunload.placeholder",function(){c(".placeholder").each(function(){this.value=""})}))}(this,document,jQuery); /*! 2k11 main JS */ -jQuery(document).ready(function(a){AccessifyHTML5({header:"#banner",footer:"#colophon"}),a("input[type=search]").parents("form").attr("role","search");var b=a("");a("#primary-nav li").each(function(){var c=a(this);c.find("span").length?a("