- Add support for SpamAssassin's X-Spam-Status header (#1589520).
- Added plugin on/off switch, which completely disables all plugins
(optionally for one named user, otherwise for all users).
+ - Security: close cross site scripting vulnerability in draft, compose
+ and mailto functionality [CVE-2006-6142].
+ - Security: work around an issue in Internet Explorer that would guess
+ the mime type of a file based on contents, not Content-Type header.
Version 1.5.1 (branched on 2006-02-12)
--------------------------------------
if ($where && $what) {
$defaultlink .= '&where='. urlencode($where).'&what='.urlencode($what);
}
-
+ // IE does make use of mime content sniffing. Forcing a download
+ // prohibit execution of XSS inside an application/octet-stream attachment
+ if ($type0 == 'application' && $type1 == 'octet-stream') {
+ $defaultlink .= '&absolute_dl=true';
+ }
/* This executes the attachment hook with a specific MIME-type.
* If that doesn't have results, it tries if there's a rule
* for a more generic type. Finally, a hook for ALL attachment
function sq_fixstyle($body, $pos, $message, $id, $mailbox){
global $view_unsafe_images;
$me = 'sq_fixstyle';
- $ret = sq_findnxreg($body, $pos, '</\s*style\s*>');
- if ($ret == FALSE){
+
+ // workaround for </style> in between comments
+ $iCurrentPos = $pos;
+ $content = '';
+ $sToken = '';
+ $bSucces = false;
+ $bEndTag = false;
+ for ($i=$pos,$iCount=strlen($body);$i<$iCount;++$i) {
+ $char = $body{$i};
+ switch ($char) {
+ case '<':
+ $sToken .= $char;
+ break;
+ case '/':
+ if ($sToken == '<') {
+ $sToken .= $char;
+ $bEndTag = true;
+ } else {
+ $content .= $char;
+ }
+ break;
+ case '>':
+ if ($bEndTag) {
+ $sToken .= $char;
+ if (preg_match('/\<\/\s*style\s*\>/i',$sToken,$aMatch)) {
+ $newpos = $i + 1;
+ $bSucces = true;
+ break 2;
+ } else {
+ $content .= $sToken;
+ }
+ $bEndTag = false;
+ } else {
+ $content .= $char;
+ }
+ break;
+ case '!':
+ if ($sToken == '<') {
+ // possible comment
+ if (isset($body{$i+2}) && substr($body,$i,3) == '!--') {
+ $i = strpos($body,'-->',$i+3);
+ $sToken = '';
+ }
+ } else {
+ $content .= $char;
+ }
+ break;
+ default:
+ if ($bEndTag) {
+ $sToken .= $char;
+ } else {
+ $content .= $char;
+ }
+ break;
+ }
+ }
+ if ($bSucces == FALSE){
return array(FALSE, strlen($body));
}
- $newpos = $ret[0] + strlen($ret[2]);
- $content = $ret[1];
+
/**
* First look for general BODY style declaration, which would be
* like so:
// This works for most types, but doesn't work with Word files
header ("Content-Type: application/download; name=\"$filename\"");
-
+ // This is to prevent IE for MIME sniffing and auto open a file in IE
+ header ("Content-Type: application/force-download; name=\"$filename\"");
// These are spares, just in case. :-)
//header("Content-Type: $type0/$type1; name=\"$filename\"");
//header("Content-Type: application/x-msdownload; name=\"$filename\"");
//header("Content-Type: application/octet-stream; name=\"$filename\"");
+ } else if ($isIE) {
+ // This is to prevent IE for MIME sniffing and auto open a file in IE
+ header ("Content-Type: application/force-download; name=\"$filename\"");
} else {
// another application/octet-stream forces download for Netscape
header ("Content-Type: application/octet-stream; name=\"$filename\"");
sqgetGlobalVar('draft_id',$draft_id);
sqgetGlobalVar('ent_num',$ent_num);
sqgetGlobalVar('saved_draft',$saved_draft);
-sqgetGlobalVar('delete_draft',$delete_draft);
+
+if ( sqgetGlobalVar('delete_draft',$delete_draft) ) {
+ $delete_draft = (int)$delete_draft;
+}
+
if ( sqgetGlobalVar('startMessage',$startMessage) ) {
$startMessage = (int)$startMessage;
} else {
if ( sqgetGlobalVar('smaction_edit_new',$tmp) ) $action = 'edit_as_new';
}
+/**
+ * Here we decode the data passed in from mailto.php.
+ */
+if ( sqgetGlobalVar('mailtodata', $mailtodata, SQ_GET) ) {
+ $trtable = array('to' => 'send_to',
+ 'cc' => 'send_to_cc',
+ 'bcc' => 'send_to_bcc',
+ 'body' => 'body',
+ 'subject' => 'subject');
+ $mtdata = unserialize($mailtodata);
+
+ foreach ($trtable as $f => $t) {
+ if ( !empty($mtdata[$f]) ) {
+ $$t = $mtdata[$f];
+ }
+ }
+ unset($mailtodata,$mtdata, $trtable);
+}
+
/* Location (For HTTP 1.1 Header("Location: ...") redirects) */
$location = get_location();
/* Identities (fetch only once) */
if (!isset($composesession)) {
$composesession = 0;
sqsession_register(0,'composesession');
+} else {
+ $composesession = (int)$composesession;
}
if (!isset($session) || (isset($newmessage) && $newmessage)) {
_("By the SquirrelMail Project Team")."<br />\n";
}
-if(sqgetGlobalVar('mailto', $mailto)) {
- $rcptaddress = addHidden('mailto', $mailto);
+if(sqgetGlobalVar('mailtodata', $mailtodata)) {
+ $mailtofield = addHidden('mailtodata', $mailtodata);
} else {
- $rcptaddress = '';
+ $mailtofield = '';
}
$password_field = addPwField('secretkey');
$login_extra = addHidden('js_autodetect_results', SMPREF_JS_OFF).
- $rcptaddress .
+ $mailtofield .
addHidden('just_logged_in', '1');
session_write_close();
'subject' => 'subject');
$url = '';
+$data = array();
+
if(sqgetGlobalVar('emailaddress', $emailaddress)) {
$emailaddress = trim($emailaddress);
if(stristr($emailaddress, 'mailto:')) {
list($emailaddress, $a) = explode('?', $emailaddress, 2);
if(strlen(trim($a)) > 0) {
$a = explode('=', $a, 2);
- $url .= $trtable[strtolower($a[0])] . '=' . urlencode($a[1]) . '&';
+ $data[strtolower($a[0])] = $a[1];
}
}
- $url = 'send_to=' . urlencode($emailaddress) . '&' . $url;
+ $data['to'] = $emailaddress;
/* CC, BCC, etc could be any case, so we'll fix them here */
foreach($_GET as $k=>$g) {
$k = strtolower($k);
if(isset($trtable[$k])) {
$k = $trtable[$k];
- $url .= $k . '=' . urlencode($g) . '&';
+ $data[$k] = $g;
}
}
- $url = substr($url, 0, -1);
}
+sqsession_is_active();
if($force_login == false && sqsession_is_registered('user_is_logged_in')) {
if($compose_only == true) {
- $redirect = 'compose.php?' . $url;
+ $redirect = 'compose.php?mailtodata=' . urlencode(serialize($data));
} else {
- $redirect = 'webmail.php?right_frame=compose.php?' . urlencode($url);
+ $redirect = 'webmail.php?mailtodata=' . urlencode(serialize($data));
}
} else {
- $redirect = 'login.php?mailto=' . urlencode($url);
+ $redirect = 'login.php?mailtodata=' . urlencode(serialize($data));
}
session_write_close();
header('Location: ' . get_location() . '/' . $redirect);
-?>
\ No newline at end of file
+?>
if(!sqGetGlobalVar('squirrelmail_language', $squirrelmail_language) || $squirrelmail_language == '') {
$squirrelmail_language = $squirrelmail_default_language;
}
-if (!sqgetGlobalVar('mailto', $mailto)) {
- $mailto = '';
+if (!sqgetGlobalVar('mailtodata', $mailtodata)) {
+ $mailtodata = '';
}
/* end of get globals */
unset($session_expired_location);
}
-if($mailto != '') {
- $redirect_url = $location . '/webmail.php?right_frame=compose.php&mailto=';
- $redirect_url .= urlencode($mailto);
+if($mailtodata != '') {
+ $redirect_url = $location . '/webmail.php?right_frame=compose.php&mailtodata=';
+ $redirect_url .= urlencode($mailtodata);
}
/* Write session data and send them off to the appropriate page. */
}
// do not use &, it will break the query string and $session will not be detected!!!
$comp_uri = SM_PATH . 'src/compose.php?mailbox='. urlencode($mailbox).
- '&session='.$aMailbox['FORWARD_SESSION'];
+ '&session='.urlencode($aMailbox['FORWARD_SESSION']);
displayPageHeader($color, $mailbox, "comp_in_new('$comp_uri', $compose_width, $compose_height);", '');
} else {
$mailbox_cache[$account.'_'.$aMailbox['NAME']] = $aMailbox;
sqgetGlobalVar('right_frame', $right_frame, SQ_GET);
-if(!sqgetGlobalVar('mailto', $mailto)) {
- $mailto = '';
+if(!sqgetGlobalVar('mailtodata', $mailtodata)) {
+ $mailtourl = 'mailtodata='.urlencode($mailtodata);
+} else {
+ $mailtourl = '';
}
// Determine the size of the left frame
$right_frame_url = 'folders.php';
break;
case 'compose.php':
- $right_frame_url = 'compose.php?' . $mailto;
+ $right_frame_url = 'compose.php?' . $mailtourl;
break;
case '':
$right_frame_url = 'right_main.php';
$oTemplate->display('webmail.tpl');
-$oTemplate->display('footer.tpl');
\ No newline at end of file
+$oTemplate->display('footer.tpl');