Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2020-18671: Roundcube mail 3 Xss

Cross Site Scripting (XSS) vulnerability in Roundcube Mail <=1.4.4 via smtp config in /installer/test.php.

CVE
#sql#xss#vulnerability

3个没用的Xss

Store Xss in /installer/test.php

in install step2

image.png-66.2kB

Access trigger

1

http://127.0.0.1/roundcubemail-1.4.4/installer/index.php?_step=3

image.png-178.8kB

code anlysize

input in step2

1
2
3
4
5

if (!empty($_POST[‘submit’])) {
$_SESSION[‘config’] = $RCI->create_config();

if ($RCI->save_configfile($_SESSION[‘config’])) {
echo '<p class="notice">The config file was saved successfully into <tt>’.RCMAIL_CONFIG_DIR.’</tt> directory of your Roundcube installation.’;

follow intocreate_config\program\include\rcmail_install.php line 216

1
2
3
4
5
6
7
8
9
10

if ($prop == ‘db_dsnw’ && !empty($_POST[‘_dbtype’])) {
if ($_POST[‘_dbtype’] == ‘sqlite’) {
$value = sprintf('%s://%s?mode=0646’, $_POST[‘_dbtype’],
$_POST[‘_dbname’][0] == ‘/’ ? ‘/’ . $_POST[‘_dbname’] : $_POST[‘_dbname’]);
}
else if ($_POST[‘_dbtype’]) {
$value = sprintf('%s://%s:%s@%s/%s’, $_POST[‘_dbtype’],
rawurlencode($_POST[‘_dbuser’]), rawurlencode($_POST[‘_dbpass’]), $_POST[‘_dbhost’], $_POST[‘_dbname’]);
}
}

Regarding the configuration of db, only when it is not sqlite, the user and pass are filtered, and other parameters are not filtered. Direct incoming will be put into config.

in step3,installer/test.php,directly export config out.

image.png-40kB

store xss in smtp config

image.png-29.4kB

image.png-33.5kB

code analysize

There is no filtering when entering variables

When the output is not defined by the html_inputfield class, it will take effect if the output is obtained directly

image.png-42.5kB

store xss in email in database

image.png-37.8kB

image.png-46.1kB

code analysize

When accessing index.php, the corresponding page will render the template, when obtaining the template, from

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

program/include/rcmail_output_html.php line 2094

public function current_username($attrib)
{
static $username;

if (!empty($username)) {  
    return $username;  
}  
  
if (strpos($\_SESSION\['username'\], '@')) {  
    $username = $\_SESSION\['username'\];  
}  
  
else if ($sql\_arr = $this\->app->user->get\_identity()) {  
    $username = $sql\_arr\['email'\];  
}  
else {  
    $username = $this\->app->user->get\_username();  
}  
  
return rcube\_utils::idn\_to\_utf8($username);  

}

in program/lib/roundcube/rcube_user.php line 304

1
2
3
4
5
6
7
8
9
10
11

function get_identity($id = null)
{
$id = (int)$id;

if (!array\_key\_exists($id, $this\->identities)) {  
    $result = $this\->list\_identities($id ? "AND \`identity\_id\` = $id" : '');  
    $this\->identities\[$id\] = $result\[0\];  
}  

return $this\->identities\[$id\];  

}

Directly from the database identities.

And this value is inserted into the database by call function insert_identity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

program/lib/roundcube/rcube_user.php line 397

function insert_identity($data)
{
if (!$this->ID) {
return false;
}

unset($data\['user\_id'\]);  

$insert\_cols   = array();  
$insert\_values = array();  

foreach ((array)$data as $col => $value) {  
    $insert\_cols\[\]   = $this\->db->quote\_identifier($col);  
    $insert\_values\[\] = $value;  
}  

$insert\_cols\[\]   = $this\->db->quote\_identifier('user\_id');  
$insert\_values\[\] = $this\->ID;  

$sql = "INSERT INTO ".$this\->db->table\_name('identities', true).  
    " (\`changed\`, ".implode(', ', $insert\_cols).")".  
    " VALUES (".$this\->db->now().", ".implode(', ', array\_pad(array(), count($insert\_values), '?')).")";  

$insert = $this\->db->query($sql, $insert\_values);  

  
$this\->identities = array();  
$this\->emails     = null;  

return $this\->db->affected\_rows($insert) ? $this\->db->insert\_id('identities') : false;  

}

This function is mainly called in two places, one is the installation place, and the other is the login place.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

/program/lib/roundcube/rcube_user.php lime 648

$rcube->user = $user_instance;
$mail_domain = $rcube->config->mail_domain($data[‘host’]);
$user_name = $data[‘user_name’];
$user_email = $data[‘user_email’];
$email_list = $data[‘email_list’];

if (empty($email_list)) {
if (empty($user_email)) {
$user_email = strpos($data[‘user’], ‘@’) ? $user : sprintf('%s@%s’, $data[‘user’], $mail_domain);
}
$email_list[] = $user_email;
}

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda