[Web] Fix BCC validation for aliases

master
andryyy 2021-06-05 08:40:55 +02:00
parent 51b32bc4c0
commit 7050d7c259
No known key found for this signature in database
GPG Key ID: 8EC34FF2794E25EF
3 changed files with 19 additions and 9 deletions

View File

@ -0,0 +1,2 @@
<?php
// PoC

View File

@ -48,7 +48,8 @@ function bcc($_action, $_data = null, $attr = null) {
$local_dest_sane = '@' . idn_to_ascii($local_dest, 0, INTL_IDNA_VARIANT_UTS46); $local_dest_sane = '@' . idn_to_ascii($local_dest, 0, INTL_IDNA_VARIANT_UTS46);
} }
elseif (filter_var($local_dest, FILTER_VALIDATE_EMAIL)) { elseif (filter_var($local_dest, FILTER_VALIDATE_EMAIL)) {
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $local_dest)) { $mailbox = mailbox('get', 'mailbox_details', $local_dest);
if ($mailbox === false && array_key_exists($local_dest, array_merge($direct_aliases, $shared_aliases)) === false) {
$_SESSION['return'][] = array( $_SESSION['return'][] = array(
'type' => 'danger', 'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'log' => array(__FUNCTION__, $_action, $_data, $_attr),
@ -56,10 +57,16 @@ function bcc($_action, $_data = null, $attr = null) {
); );
return false; return false;
} }
$domain = mailbox('get', 'mailbox_details', $local_dest)['domain']; if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $local_dest) &&
if (empty($domain)) { !hasAliasObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $local_dest)) {
return false; $_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data, $_attr),
'msg' => 'access_denied'
);
return false;
} }
$domain = idn_to_ascii(substr(strstr($local_dest, '@'), 1), 0, INTL_IDNA_VARIANT_UTS46);
$local_dest_sane = $local_dest; $local_dest_sane = $local_dest;
} }
else { else {

View File

@ -548,16 +548,17 @@ function hasMailboxObjectAccess($username, $role, $object) {
} }
function hasAliasObjectAccess($username, $role, $object) { function hasAliasObjectAccess($username, $role, $object) {
global $pdo; global $pdo;
if (empty($username) || empty($role) || empty($object)) {
return false;
}
if (!filter_var(html_entity_decode(rawurldecode($username)), FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) { if (!filter_var(html_entity_decode(rawurldecode($username)), FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
return false; return false;
} }
if ($role != 'admin' && $role != 'domainadmin' && $role != 'user') { if ($role != 'admin' && $role != 'domainadmin' && $role != 'user') {
return false; return false;
} }
if ($username == $object) { // Do not verify mailboxes
return true; $stmt = $pdo->prepare("SELECT `domain` FROM `alias` WHERE `address` = :object AND `address` != `goto`");
}
$stmt = $pdo->prepare("SELECT `domain` FROM `alias` WHERE `address` = :object");
$stmt->execute(array(':object' => $object)); $stmt->execute(array(':object' => $object));
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(PDO::FETCH_ASSOC);
if (isset($row['domain']) && hasDomainAccess($username, $role, $row['domain'])) { if (isset($row['domain']) && hasDomainAccess($username, $role, $row['domain'])) {
@ -1031,7 +1032,7 @@ function user_get_alias_details($username) {
if (empty($row['ad_alias'])) { if (empty($row['ad_alias'])) {
continue; continue;
} }
$data['direct_aliases'][$row['ad_alias']]['public_comment'] = '<span data-toggle="tooltip" title="' . $lang['add']['alias_domain'] . '">' . $row['alias_domain'] . '</span>'; $data['direct_aliases'][$row['ad_alias']]['public_comment'] = $lang['add']['alias_domain'];
$data['alias_domains'][] = $row['alias_domain']; $data['alias_domains'][] = $row['alias_domain'];
} }
$stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` NOT LIKE '@%';"); $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` NOT LIKE '@%';");