=====[BEGIN-SCL-REPORT]===== ________________________________________________________________________ Scovetta Labs Security Advisory Title: Multiple Vulnerabilities in WebCalendar Status: Public Identifier: SCL-2010-001 Release Date: 2010-01-01 ________________________________________________________________________ Package: WebCalendar Vendor: www.k5n.us Priority: High Vulnerability: Cross-Site Scripting, Denial of Service Affected Versions: ================== WebCalendar v1.2.0 is vulnerable. Previous versions may also be vulnerable. Background: (from [1] and [2]) =========== "WebCalendar is a PHP application used to maintain a calendar for a single user or an intranet group of users. It can also be configured as an event calendar." Description: ============ Multiple security vulnerabilities were discovered in WebCalendar v1.2.0. These vulnerabilities are the result of input data from the URL not being sanitized before being placed within a resulting page. [ Cross-Site Scripting ] The first class of vulnerabilities is related to the meta redirection tag generated in the generate_refresh_meta() function in the /includes/functions.php file. The $REQUEST_URI variable is assigned in the load_global_settings() function: function load_global_settings () { ... $REQUEST_URI = $_SERVER['REQUEST_URI']; ... } The variable then used directly within the generate_refresh_meta() function: function generate_refresh_meta () { global $AUTO_REFRESH, $AUTO_REFRESH_TIME, $REQUEST_URI; return ( $AUTO_REFRESH == 'Y' && ! empty ( $AUTO_REFRESH_TIME ) && !empty ( $REQUEST_URI ) ? '' : '' ); } An attacker could craft a URL that escapes out of the 'content' attribute, 'meta' tag, and into the main HTML context. The second class of cross-site scripting vulnerability is the result of lack of input validation in the generate_printer_friendly() function located in the /includes/functions.php file: function generate_printer_friendly ( $hrefin = '' ) { global $_SERVER, $MENU_ENABLED, $SCRIPT, $show_printer; // Set this to enable printer icon in top menu. $href = ( empty ( $href ) ? $SCRIPT : $hrefin ) . '?' . ( empty ( $_SERVER['QUERY_STRING'] ) ? '' : $_SERVER['QUERY_STRING'] ); ... } This function is called from various other pages to create a "printer-friendly" link. Unfortunately, the content returned by this function is often added into a JavaScript variable to create a menu, as shown below: var myMenu = ... ['','', 'day.php?cat_id=123&friendly=1','',''] ------------------ |---> coming directly from $_SERVER['QUERY_STRING'] The final class of cross-site scripting vulnerability is related to a lack of validation being performed on on certain parameters, such as the eType parameter passed to /edit_entry.php and the cat_id and date parameters passed to /day.php, /week.php, /month.php, and /year.php. These values are taken and displayed back to the user without any validation. [ Denial of Service ] The second type of vulnerability is a denial of service condition that can be triggered by navigating to most (if not all) of the pages and appending a slash after the script name. (The user must not be currently logged in.) This is caused by a bug in the redirection logic that sends the user to the login page - the logic uses a relative path, so a user trying to access /day.php/ is redirected to /day.php/login.php, which does not exist, so they are redirected to /day.php/login.php, and again and again. Exploit: ======== These vulnerabilities were tested using Internet Explorer. It appears that other browsers properly encode some entities which may make the exploits contained herein harder to use. Cross-Site Scripting (Class #1): /list_unapproved.php/?"> /day.php/?"> /week.php (same as for day.php) /month.php (same as for day.php) /year.php (same as for day.php) Cross-Site Scripting (Class #2): /day.php?cat_id=0','','']];//]]>--> Cross-Site Scripting (Class #3): /edit_entry.php?eType=> /day.php?cat_id=0"> /day.php?cat_id=0&date="> Denial of Service: (user must not be currently logged in) /day.php/ /week.php/ /month.php/ /year.php/ Work-around: ============ This is not a complete workaround, but protects against some of the cross-site scripting vulnerabiliteis described in this report. /includes/functions.php.patch 1864c1864 < . ( empty ( $_SERVER['QUERY_STRING'] ) ? '' : $_SERVER['QUERY_STRING'] ); --- > . ( empty ( $_SERVER['QUERY_STRING'] ) ? '' : addslashes(htmlentities($_SERVER['QUERY_STRING'])) ); 1895c1895 < . '; url=' . $REQUEST_URI . '" />' : '' ); --- > . '; url=' . addslashes(htmlentities($REQUEST_URI)) . '" />' : '' ); Vendor Response: ================ The vendor was contacted multiple times, but did not respond. Revision History ================ 2009-07-11: Vendor notified via e-mail. 2009-08-16: Bug report filed on project website (SourceForge). 2009-11-07: Comment added to bug report. 2010-01-01: Advisory published. Credits: ======== This vulnerability was discovered by Michael Scovetta using the Yasca source code analyzer (www.yasca.org). References: ========== [1] http://sourceforge.net/projects/webcalendar/ [2] http://www.k5n.us/webcalendar.php [3] http://www.yasca.org/ Disclaimer ========== The content of this report is purely informational and meant only for the purpose of education and protection. Scovetta Labs and Michael Scovetta shall in no event be liable for any damage whatsoever, direct or implied, arising from use or spread of this information. All identifiers (hostnames, IP addresses, company names, individual names, etc.) used in examples and demonstrations are used only for explanatory purposes and have no connection with any real host, company, or individual. In no event should it be assumed that use of these names means specific hosts, companies or individuals are vulnerable to any attacks nor does it mean that they consent to being used in any vulnerability tests. The use of information in this report is entirely at user's risk. Copyright ========= (c) 2010 Michael Scovetta. Forwarding and publishing of this document is permitted providing the content between "[BEGIN-SCL-REPORT]" and "[END-SCL-REPORT]" marks remains unchanged. =====[END-SCL-REPORT]=====