Fix for potential XSS vulnerability on uploaded file names. To be further tested before retrofitting in branches.

SVN:trunk[3985]
This commit is contained in:
Denis Flaven
2016-04-05 16:15:29 +00:00
parent 3997ea3a23
commit 32ce26aa7d
5 changed files with 10 additions and 122 deletions

View File

@@ -1868,7 +1868,7 @@ EOF
$iMaxFileSize = utils::ConvertToBytes(ini_get('upload_max_filesize'));
$sHTMLValue = "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"$iMaxFileSize\" />\n";
$sHTMLValue .= "<input name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}[filename]\" type=\"hidden\" id=\"$iId\" \" value=\"".htmlentities($sFileName, ENT_QUOTES, 'UTF-8')."\"/>\n";
$sHTMLValue .= "<span id=\"name_$iInputId\">$sFileName</span><br/>\n";
$sHTMLValue .= "<span id=\"name_$iInputId\">".htmlentities($sFileName, ENT_QUOTES, 'UTF-8')."</span><br/>\n";
$sHTMLValue .= "<input title=\"$sHelpText\" name=\"attr_{$sFieldPrefix}{$sAttCode}{$sNameSuffix}[fcontents]\" type=\"file\" id=\"file_$iId\" onChange=\"UpdateFileName('$iId', this.value)\"/>&nbsp;{$sValidationSpan}{$sReloadSpan}\n";
break;

View File

@@ -90,12 +90,12 @@ class ormDocument
{
// If the filename is not empty, display it, this is used
// by the creation wizard while the file has not yet been uploaded
$sResult = $this->GetFileName();
$sResult = htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8');
}
else
{
$data = $this->GetData();
$sResult = $this->GetFileName().' [ '.$this->GetMimeType().', size: '.strlen($data).' byte(s) ]<br/>';
$sResult = htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8').' [ '.$this->GetMimeType().', size: '.strlen($data).' byte(s) ]<br/>';
}
return $sResult;
}
@@ -106,7 +106,7 @@ class ormDocument
*/
public function GetDisplayLink($sClass, $Id, $sAttCode)
{
return "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" target=\"_blank\" >".$this->GetFileName()."</a>\n";
return "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" target=\"_blank\" >".htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8')."</a>\n";
}
/**
@@ -115,7 +115,7 @@ class ormDocument
*/
public function GetDownloadLink($sClass, $Id, $sAttCode)
{
return "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode\">".$this->GetFileName()."</a>\n";
return "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode\">".htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8')."</a>\n";
}
/**

View File

@@ -74,7 +74,7 @@ try
$oAttachment->Set('contents', $oDoc);
$iAttId = $oAttachment->DBInsert();
$aResult['msg'] = $oDoc->GetFileName();
$aResult['msg'] = htmlentities($oDoc->GetFileName(), ENT_QUOTES, 'UTF-8');
$aResult['icon'] = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($oDoc->GetFileName());
$aResult['att_id'] = $iAttId;
$aResult['preview'] = $oDoc->IsPreviewAvailable() ? 'true' : 'false';
@@ -96,118 +96,6 @@ try
$oAttachment->DBDelete();
}
break;
case 'cke_img_upload':
// Image uploaded via CKEditor
$aResult = array(
'uploaded' => 0,
'fileName' => '',
'url' => '',
'icon' => '',
'msg' => '',
'att_id' => 0,
'preview' => 'false',
);
$sObjClass = stripslashes(utils::ReadParam('obj_class', '', false, 'class'));
$sTempId = utils::ReadParam('temp_id', '');
if (empty($sObjClass))
{
$aResult['error'] = "Missing argument 'obj_class'";
}
elseif (empty($sTempId))
{
$aResult['error'] = "Missing argument 'temp_id'";
}
else
{
try
{
$oDoc = utils::ReadPostedDocument('upload');
$oAttachment = MetaModel::NewObject('Attachment');
$oAttachment->Set('expire', time() + 3600); // one hour...
$oAttachment->Set('temp_id', $sTempId);
$oAttachment->Set('item_class', $sObjClass);
$oAttachment->SetDefaultOrgId();
$oAttachment->Set('contents', $oDoc);
$iAttId = $oAttachment->DBInsert();
$aResult['uploaded'] = 1;
$aResult['msg'] = $oDoc->GetFileName();
$aResult['fileName'] = $oDoc->GetFileName();
$aResult['url'] = utils::GetAbsoluteUrlAppRoot().ATTACHMENT_DOWNLOAD_URL.$iAttId;
$aResult['icon'] = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($oDoc->GetFileName());
$aResult['att_id'] = $iAttId;
$aResult['preview'] = $oDoc->IsPreviewAvailable() ? 'true' : 'false';
}
catch (FileUploadException $e)
{
$aResult['error'] = $e->GetMessage();
}
}
$oPage->add(json_encode($aResult));
break;
case 'cke_browse':
$oPage = new NiceWebPage('Browse for image...');
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlModulesRoot().'itop-attachments/css/magnific-popup.css');
$oPage->add_linked_script(utils::GetAbsoluteUrlModulesRoot().'itop-attachments/js/jquery.magnific-popup.min.js');
$sImgUrl = utils::GetAbsoluteUrlAppRoot().ATTACHMENT_DOWNLOAD_URL;
$oPage->add_script(
<<<EOF
// Helper function to get parameters from the query string.
function getUrlParam( paramName ) {
var reParam = new RegExp( '(?:[\?&]|&)' + paramName + '=([^&]+)', 'i' );
var match = window.location.search.match( reParam );
return ( match && match.length > 1 ) ? match[1] : null;
}
// Simulate user action of selecting a file to be returned to CKEditor.
function returnFileUrl(iAttId, sAltText) {
var funcNum = getUrlParam( 'CKEditorFuncNum' );
var fileUrl = '$sImgUrl'+iAttId;
window.opener.CKEDITOR.tools.callFunction( funcNum, fileUrl, function() {
// Get the reference to a dialog window.
var dialog = this.getDialog();
// Check if this is the Image Properties dialog window.
if ( dialog.getName() == 'image' ) {
// Get the reference to a text field that stores the "alt" attribute.
var element = dialog.getContentElement( 'info', 'txtAlt' );
// Assign the new value.
if ( element )
element.setValue(sAltText);
}
// Return "false" to stop further execution. In such case CKEditor will ignore the second argument ("fileUrl")
// and the "onSelect" function assigned to the button that called the file manager (if defined).
// return false;
} );
window.close();
}
EOF
);
$oPage->add_ready_script(
<<<EOF
$('.img-picker').magnificPopup({type: 'image', closeOnContentClick: true });
EOF
);
$sTempId = utils::ReadParam('temp_id');
$sClass = utils::ReadParam('obj_class', '', false, 'class');
$iObjectId = utils::ReadParam('obj_key', 0, false, 'integer');
$sOQL = "SELECT Attachment WHERE ((temp_id = :temp_id) OR (item_class = :obj_class AND item_id = :obj_id))";
$oSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array(), array('temp_id' => $sTempId, 'obj_class' => $sClass, 'obj_id' => $iObjectId));
while($oAttachment = $oSet->Fetch())
{
$oDoc = $oAttachment->Get('contents');
if ($oDoc->GetMainMimeType() == 'image')
{
$sDocName = addslashes(htmlentities($oDoc->GetFileName(), ENT_QUOTES, 'UTF-8'));
$iAttId = $oAttachment->GetKey();
$oPage->add("<div style=\"float:left;margin:1em;text-align:center;\"><img class=\"img-picker\" style=\"max-width:300px;cursor:zoom-in\" href=\"{$sImgUrl}{$iAttId}\" alt=\"$sDocName\" title=\"$sDocName\" src=\"{$sImgUrl}{$iAttId}\"><br/><button onclick=\"returnFileUrl($iAttId, '$sDocName')\">Insert</button></div>");
}
}
break;
default:
$oPage->p("Missing argument 'operation'");

View File

@@ -275,7 +275,7 @@ EOF
{
$iAttId = $oAttachment->GetKey();
$oDoc = $oAttachment->Get('contents');
$sFileName = $oDoc->GetFileName();
$sFileName = htmlentities($oDoc->GetFileName(), ENT_QUOTES, 'UTF-8');
$sIcon = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($sFileName);
$sPreview = $oDoc->IsPreviewAvailable() ? 'true' : 'false';
$sDownloadLink = utils::GetAbsoluteUrlAppRoot().ATTACHMENT_DOWNLOAD_URL.$iAttId;
@@ -303,7 +303,7 @@ EOF
// Display them
$iAttId = $oAttachment->GetKey();
$oDoc = $oAttachment->Get('contents');
$sFileName = $oDoc->GetFileName();
$sFileName = htmlentities($oDoc->GetFileName(), ENT_QUOTES, 'UTF-8');
$sIcon = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($sFileName);
$sDownloadLink = utils::GetAbsoluteUrlAppRoot().ATTACHMENT_DOWNLOAD_URL.$iAttId;
$sPreview = $oDoc->IsPreviewAvailable() ? 'true' : 'false';
@@ -439,7 +439,7 @@ EOF
{
$iAttId = $oAttachment->GetKey();
$oDoc = $oAttachment->Get('contents');
$sFileName = $oDoc->GetFileName();
$sFileName = htmlentities($oDoc->GetFileName(), ENT_QUOTES, 'UTF-8');
$sIcon = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($sFileName);
$sPreview = $oDoc->IsPreviewAvailable() ? 'true' : 'false';
$sDownloadLink = utils::GetAbsoluteUrlAppRoot().ATTACHMENT_DOWNLOAD_URL.$iAttId;

View File

@@ -2274,7 +2274,7 @@ EOF
$iAttId = $oAttachment->DBInsert();
$aResult['uploaded'] = 1;
$aResult['msg'] = $oDoc->GetFileName();
$aResult['msg'] = htmlentities($oDoc->GetFileName(), ENT_QUOTES, 'UTF-8');
$aResult['fileName'] = $oDoc->GetFileName();
$aResult['url'] = utils::GetAbsoluteUrlAppRoot().INLINEIMAGE_DOWNLOAD_URL.$iAttId.'&s='.$oAttachment->Get('secret');
if (is_array($aDimensions))