/** * Detects typical XSS attack patterns * @param string str String to search for XSS attack vectors * @param bool cleanImg Flag to allow <img> tags to survive - only used by InboundEmail for inline images. * @return array Array of matches, empty on clean string */ function clean_xss($str, $cleanImg = true) { global $sugar_config; if (empty($sugar_config['email_xss'])) { $sugar_config['email_xss'] = getDefaultXssTags(); } $arr = unserialize(base64_decode($sugar_config['email_xss'])); $regex = ''; foreach ($arr as $v) { if (!empty($regex)) { $regex .= "|"; } $regex .= $v; } $tag_regex = "#<({$regex})[^>]*>?#sim"; // cn: bug 13079 - "on\w" matched too many non-events (cONTact, strONG, etc.) $jsEvents = "onblur|onfocus|oncontextmenu|onresize|onscroll|onunload|ondblclick|onclick|"; $jsEvents .= "onmouseup|onmouseover|onmousedown|onmouseenter|onmouseleave|onmousemove|onload|onchange|"; $jsEvents .= "onreset|onselect|onsubmit|onkeydown|onkeypress|onkeyup|onabort|onerror|ondragdrop"; $attribute_regex = "#<.+({$jsEvents})[^=>]*=[^>]*>#sim"; $javascript_regex = '@<[^/>][^>]+(expression\\(|j\\W*a\\W*v\\W*a|v\\W*b\\W*s\\W*c\\W*r|&#|/\\*|\\*/)[^>]*>@sim'; $imgsrc_regex = '#<[^>]+src[^=]*=([^>]*?http(s)?://[^>]*)>#sim'; $css_url = '#url\\(.*\\.\\w+\\)#'; $str = str_replace("\t", "", $str); $matches = array_merge(xss_check_pattern($tag_regex, $str), xss_check_pattern($javascript_regex, $str)); $jsMatches = xss_check_pattern($attribute_regex, $str); if (!empty($jsMatches)) { preg_match_all($attribute_regex, $str, $newMatches, PREG_PATTERN_ORDER); if (!empty($newMatches[0][0])) { $matches2 = array_merge(xss_check_pattern("#({$jsEvents})#sim", $newMatches[0][0])); $matches = array_merge($matches, $matches2); } } if ($cleanImg) { $matches = array_merge($matches, xss_check_pattern($imgsrc_regex, $str)); } // cn: bug 13498 - custom white-list of allowed domains that vet remote images preg_match_all($css_url, $str, $cssUrlMatches, PREG_PATTERN_ORDER); if (isset($sugar_config['security_trusted_domains']) && !empty($sugar_config['security_trusted_domains']) && is_array($sugar_config['security_trusted_domains'])) { if (is_array($cssUrlMatches) && count($cssUrlMatches) > 0) { // normalize whitelist foreach ($sugar_config['security_trusted_domains'] as $k => $v) { $sugar_config['security_trusted_domains'][$k] = strtolower($v); } foreach ($cssUrlMatches[0] as $match) { $domain = strtolower(substr(strstr($match, "://"), 3)); $baseUrl = substr($domain, 0, strpos($domain, "/")); if (!in_array($baseUrl, $sugar_config['security_trusted_domains'])) { $matches[] = $match; } } } } else { $matches = array_merge($matches, $cssUrlMatches[0]); } return $matches; }
/** * @see SugarView::display() */ public function display() { global $mod_strings; global $app_list_strings; global $app_strings; global $current_user; global $sugar_config; echo $this->getModuleTitle(false); global $currentModule; $focus = Administration::getSettings(); //retrieve all admin settings. $GLOBALS['log']->info("Mass Emailer(EmailMan) ConfigureSettings view"); $this->ss->assign("MOD", $mod_strings); $this->ss->assign("APP", $app_strings); $this->ss->assign("RETURN_MODULE", "Administration"); $this->ss->assign("RETURN_ACTION", "index"); $this->ss->assign("MODULE", $currentModule); $this->ss->assign("PRINT_URL", "index.php?" . $GLOBALS['request_string']); $this->ss->assign("HEADER", get_module_title("EmailMan", "{MOD.LBL_CONFIGURE_SETTINGS}", true)); $this->ss->assign("notify_fromaddress", $focus->settings['notify_fromaddress']); $this->ss->assign("notify_send_from_assigning_user", isset($focus->settings['notify_send_from_assigning_user']) && !empty($focus->settings['notify_send_from_assigning_user']) ? "checked='checked'" : ""); $this->ss->assign("notify_on", $focus->settings['notify_on'] ? "checked='checked'" : ""); $this->ss->assign("notify_fromname", $focus->settings['notify_fromname']); $this->ss->assign("notify_allow_default_outbound_on", !empty($focus->settings['notify_allow_default_outbound']) && $focus->settings['notify_allow_default_outbound'] ? "checked='checked'" : ""); $this->ss->assign("mail_smtptype", $focus->settings['mail_smtptype']); $this->ss->assign("mail_smtpserver", $focus->settings['mail_smtpserver']); $this->ss->assign("mail_smtpport", $focus->settings['mail_smtpport']); $this->ss->assign("mail_smtpuser", $focus->settings['mail_smtpuser']); $this->ss->assign("mail_smtpauth_req", $focus->settings['mail_smtpauth_req'] ? "checked='checked'" : ""); $this->ss->assign("mail_haspass", empty($focus->settings['mail_smtppass']) ? 0 : 1); $this->ss->assign("MAIL_SSL_OPTIONS", get_select_options_with_id($app_list_strings['email_settings_for_ssl'], $focus->settings['mail_smtpssl'])); //Assign the current users email for the test send dialogue. $this->ss->assign("CURRENT_USER_EMAIL", $current_user->email1); $showSendMail = FALSE; $outboundSendTypeCSSClass = "yui-hidden"; if (isset($sugar_config['allow_sendmail_outbound']) && $sugar_config['allow_sendmail_outbound']) { $showSendMail = TRUE; $app_list_strings['notifymail_sendtype']['sendmail'] = 'sendmail'; $outboundSendTypeCSSClass = ""; } $this->ss->assign("OUTBOUND_TYPE_CLASS", $outboundSendTypeCSSClass); $this->ss->assign("mail_sendtype_options", get_select_options_with_id($app_list_strings['notifymail_sendtype'], $focus->settings['mail_sendtype'])); /////////////////////////////////////////////////////////////////////////////// //// USER EMAIL DEFAULTS // editors $editors = $app_list_strings['dom_email_editor_option']; $newEditors = array(); foreach ($editors as $k => $v) { if ($k != "") { $newEditors[$k] = $v; } } // preserve attachments $preserveAttachments = ''; if (isset($sugar_config['email_default_delete_attachments']) && $sugar_config['email_default_delete_attachments'] == true) { $preserveAttachments = 'CHECKED'; } $this->ss->assign('DEFAULT_EMAIL_DELETE_ATTACHMENTS', $preserveAttachments); //// END USER EMAIL DEFAULTS /////////////////////////////////////////////////////////////////////////////// //setting to manage. //emails_per_run //tracking_entities_location_type default or custom //tracking_entities_location http://www.sugarcrm.com/track/ ////////////////////////////////////////////////////////////////////////////// //// EMAIL SECURITY if (!isset($sugar_config['email_xss']) || empty($sugar_config['email_xss'])) { $sugar_config['email_xss'] = getDefaultXssTags(); } foreach (unserialize(base64_decode($sugar_config['email_xss'])) as $k => $v) { $this->ss->assign($k . "Checked", 'CHECKED'); } //// END EMAIL SECURITY /////////////////////////////////////////////////////////////////////////////// require_once 'modules/Emails/Email.php'; $email = BeanFactory::getBean('Emails'); $this->ss->assign('ROLLOVER', $email->rolloverStyle); $this->ss->assign('THEME', $GLOBALS['theme']); $this->ss->assign("JAVASCRIPT", get_validate_record_js()); $this->ss->display('modules/EmailMan/tpls/config.tpl'); }
public function testEmailManController() { require_once 'modules/EmailMan/controller.php'; global $sugar_config; $conn = new EmailManController(); // populate the REQUEST array because configurator will read that to write config_override foreach ($this->email_xss as $key => $val) { $_REQUEST["{$key}"] = $val; } $new_security_settings = base64_encode(serialize($this->email_xss)); // make sure that settings from config.php are untouched $original_security_settings = getDefaultXssTags(); $this->assertNotEquals($original_security_settings, $new_security_settings, "ensure that original email_xss is not touched"); $conn->action_Save(); // testing the save, // it should use the above request vars // to create a new config_override.php // now check to make sure that config_override received the updated settings require "config_override.php"; $this->assertEquals($new_security_settings, $sugar_config['email_xss'], "testing that new email_xss settings got saved"); }
/** * Detects typical XSS attack patterns * @deprecated * @param string str String to search for XSS attack vectors * @param bool cleanImg Flag to allow <img> tags to survive - only used by InboundEmail for inline images. * @return array Array of matches, empty on clean string */ function clean_xss($str, $cleanImg = true) { global $sugar_config; if (empty($sugar_config['email_xss'])) { $sugar_config['email_xss'] = getDefaultXssTags(); } $xsstags = unserialize(base64_decode($sugar_config['email_xss'])); // cn: bug 13079 - "on\w" matched too many non-events (cONTact, strONG, etc.) $jsEvents = "onblur|onfocus|oncontextmenu|onresize|onscroll|onunload|ondblclick|onclick|"; $jsEvents .= "onmouseup|onmouseover|onmousedown|onmouseenter|onmouseleave|onmousemove|onload|onchange|"; $jsEvents .= "onreset|onselect|onsubmit|onkeydown|onkeypress|onkeyup|onabort|onerror|ondragdrop"; $attribute_regex = "#\\b({$jsEvents})\\s*=\\s*(?|(?!['\"])\\S+|['\"].+?['\"])#sim"; $javascript_regex = '@<[^/>][^>]+(expression\\(|j\\W*a\\W*v\\W*a|v\\W*b\\W*s\\W*c\\W*r|&#|/\\*|\\*/)[^>]*>@sim'; $imgsrc_regex = '#<[^>]+src[^=]*=([^>]*?http(s)?://[^>]*)>#sim'; $css_url = '#url\\(.*\\.\\w+\\)#'; $tagsrex = '#<\\/?(\\w+)((?:\\s+(?:\\w|\\w[\\w-]*\\w)(?:\\s*=\\s*(?:\\".*?\\"|\'.*?\'|[^\'\\">\\s]+))?)+\\s*|\\s*)\\/?>#im'; $tagmatches = array(); $matches = array(); preg_match_all($tagsrex, $str, $tagmatches, PREG_PATTERN_ORDER); foreach ($tagmatches[1] as $no => $tag) { if (in_array($tag, $xsstags)) { // dangerous tag - take out whole $matches[] = $tagmatches[0][$no]; continue; } $attrmatch = array(); preg_match_all($attribute_regex, $tagmatches[2][$no], $attrmatch, PREG_PATTERN_ORDER); if (!empty($attrmatch[0])) { $matches = array_merge($matches, $attrmatch[0]); } } $matches = array_merge($matches, xss_check_pattern($javascript_regex, $str)); if ($cleanImg) { $matches = array_merge($matches, xss_check_pattern($imgsrc_regex, $str)); } // cn: bug 13498 - custom white-list of allowed domains that vet remote images preg_match_all($css_url, $str, $cssUrlMatches, PREG_PATTERN_ORDER); if (isset($sugar_config['security_trusted_domains']) && !empty($sugar_config['security_trusted_domains']) && is_array($sugar_config['security_trusted_domains'])) { if (is_array($cssUrlMatches) && count($cssUrlMatches) > 0) { // normalize whitelist foreach ($sugar_config['security_trusted_domains'] as $k => $v) { $sugar_config['security_trusted_domains'][$k] = strtolower($v); } foreach ($cssUrlMatches[0] as $match) { $domain = strtolower(substr(strstr($match, "://"), 3)); $baseUrl = substr($domain, 0, strpos($domain, "/")); if (!in_array($baseUrl, $sugar_config['security_trusted_domains'])) { $matches[] = $match; } } } } else { $matches = array_merge($matches, $cssUrlMatches[0]); } return $matches; }
$preserveAttachments = ''; if (isset($sugar_config['email_default_delete_attachments']) && $sugar_config['email_default_delete_attachments'] == true) { $preserveAttachments = 'CHECKED'; } $xtpl->assign('DEFAULT_EMAIL_DELETE_ATTACHMENTS', $preserveAttachments); //// END USER EMAIL DEFAULTS /////////////////////////////////////////////////////////////////////////////// //setting to manage. //emails_per_run //tracking_entities_location_type default or custom //tracking_entities_location http://www.sugarcrm.com/track/ $outboundRaw = isset($sugar_config['email_outbound_save_raw']) && $sugar_config['email_outbound_save_raw'] == true ? 'email_outbound_save_raw_yes' : 'email_outbound_save_raw_no'; $xtpl->assign($outboundRaw, 'CHECKED'); ////////////////////////////////////////////////////////////////////////////// //// EMAIL SECURITY if (!isset($sugar_config['email_xss']) || empty($sugar_config['email_xss'])) { $sugar_config['email_xss'] = getDefaultXssTags(); } foreach (unserialize(base64_decode($sugar_config['email_xss'])) as $k => $v) { $xtpl->assign($k . "Checked", 'CHECKED'); } if (!isset($sugar_config['email_preserve_raw']) || empty($sugar_config['email_preserve_raw'])) { $sugar_config['email_preserve_raw'] = 0; } $xtpl->assign("preserve_rawChecked", empty($sugar_config['email_preserve_raw']) ? "" : "CHECKED"); //clean_xss('here'); //// END EMAIL SECURITY /////////////////////////////////////////////////////////////////////////////// $xtpl->assign("JAVASCRIPT", get_validate_record_js()); $xtpl->parse("main"); $xtpl->out("main");