fck神马东西,不解释,很暴力,几乎很难有编辑器再超过它,但是最新版的那个ckeditor,把f去掉后的那个界面实在用不习惯,看的两眼昏花,所以目前做项目还是选择2.6版本的fck吧。但是他的各种漏洞也很让人蛋疼,各种乱码浮云也让人纠结,所以这篇文章就记下来,每次纠结一次记录一次。
严重错误更正 我们不能通过 HttpPostedFile ofile 取读取文件的路径来判断文件类型,得通过Image.FromStream来读取文件流生成图片,当然如果是非正常图片就会出错了,自然也不会上传上去了。
纠结1:找到2.6.6的fck C#源码,
看里面的FileWorkerBase 类下的上传代码,感觉写的有点不太负责人,我临时加了图片验证代码进去,上传类如下,加中文注释的是我新加上去的:
/// <summary>
/// //保存文件 update by yepeng 2011-08-01
/// </summary>
/// <param name="resourceType"></param>
/// <param name="currentFolder"></param>
/// <param name="isQuickUpload"></param>
protected void FileUpload( string resourceType, string currentFolder, bool isQuickUpload )
{
HttpPostedFile oFile = Request.Files[ "NewFile" ];
if (resourceType == "Image") //此处只做了图片类型的检测其他文件类型在配置文件里需要禁用掉
{
if (!ChecImgkFile(oFile))
{
return;
}
}
string sFileName = "";
if ( oFile == null )
{
this.SendFileUploadResponse( 202, isQuickUpload );
return;
}
// Map the virtual path to the local server path.
string sServerDir = this.ServerMapFolder( resourceType, currentFolder, isQuickUpload );
// Get the uploaded file name.
sFileName = System.IO.Path.GetFileName( oFile.FileName );
sFileName = this.SanitizeFileName( sFileName );
string sExtension = System.IO.Path.GetExtension( oFile.FileName );
sExtension = sExtension.TrimStart( '.' );
if ( !this.Config.TypeConfig[ resourceType ].CheckIsAllowedExtension( sExtension ) )
{
this.SendFileUploadResponse( 202, isQuickUpload );
return;
}
if ( this.Config.CheckIsNonHtmlExtension( sExtension ) && !this.CheckNonHtmlFile( oFile ) )
{
this.SendFileUploadResponse( 202, isQuickUpload );
return;
}
int iErrorNumber = 0;
int iCounter = 0;
while ( true )
{
string sFilePath = System.IO.Path.Combine( sServerDir, sFileName );
if ( System.IO.File.Exists( sFilePath ) )
{
iCounter++;
sFileName =System.IO.Path.GetFileNameWithoutExtension( oFile.FileName ) +"(" + iCounter + ")." +sExtension;
iErrorNumber = 201;
}
else
{
oFile.SaveAs( sFilePath );
break;
}
}
TypeConfig typeConfig = this.Config.TypeConfig[resourceType] ;
string sFileUrl = isQuickUpload ? typeConfig.GetQuickUploadPath() : typeConfig.GetFilesPath() ;
sFileUrl += sFileName;
this.SendFileUploadResponse( iErrorNumber, isQuickUpload, sFileUrl, sFileName );
}
单独写了个简单的图片验证方法,才疏学浅代码贴下面,说明贴代码里了:
/// <summary>
/// 检测图片文件类型
/// </summary>
/// <param name="ofile"></param>
private bool ChecImgkFile(HttpPostedFile ofile)
{
bool isImage = false;
//第一层判断 图片后缀 bmp|gif|jpeg|jpg|png
string[] typearr = { ".jpg", ".png", ".gif", ".bmp", ".jpeg" };
string sExtension = Path.GetExtension(ofile.FileName).ToLower();
foreach (string t in typearr)
{
if (t==sExtension)
{
isImage = true;
}
}
//第二层图片判断 通过C#自身提供的方法来进行判断(判断某种确定的图片类型)
if (isImage)
{
isImage = false;
string fileContentType = ofile.ContentType.ToLower();
//此处 if 过滤掉那些直接保存为图片的asp木马,但是木马图片生成器生成的过滤不掉,所以继续判断
if (fileContentType == "image/bmp" || fileContentType == "image/gif" || fileContentType == "image/jpeg" || fileContentType == "image/pjpeg")
{
try
{
System.Drawing.Image img = System.Drawing.Image.FromStream(ofile.InputStream);//严重更正过来
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
{
isImage = true;
}
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp))
{
isImage = true;
}
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif))
{
isImage = true;
}
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
{
isImage = true;
}
}
catch (Exception e)
{
SendFileUploadResponse(110, false, ofile.FileName, ofile.FileName, ofile.FileName);
isImage = false;
}
}
else
{
SendFileUploadResponse(112, false, ofile.FileName, ofile.FileName, ofile.FileName);
}
}
return isImage;
//第三层 通过判断文件头来判断是否是图片 这地方暂时不做了,太多判断会很影响效率
if (isImage)
{
//try
//{
// FileStream fs = new FileStream(ofile.FileName, FileMode.Open, FileAccess.Read);
// BinaryReader reader = new BinaryReader(fs);
// string fileClass;
// byte buffer;
// buffer = reader.ReadByte();
// fileClass = buffer.ToString();
// buffer = reader.ReadByte();
// fileClass += buffer.ToString();
// reader.Close();
// fs.Close();
// if (fileClass == "255216" || fileClass == "7173" || fileClass == "13780" || fileClass == "6677")
// //255216是jpg;7173是gif;6677是BMP,13780是PNG;7790是exe,8297是rar
// {
// isImage = true;
// }
// else
// {
// isImage = false;
// }
//}
//catch
//{
// isImage = false;
//}
}
//如果四层判断都过了,那就牛A了
}
后面那一层判断暂时注释了,感觉有点画蛇添足,但是还是贴到文章,算是备注,经过实际测试过,基本上可以拦截简单的图片木马程序,但是没测试过木马图片生成器生成的图片木马,下一个都是被360和谐,不敢随便尝试,忘园友指教。没找到上传源码的地方,纠结。弱弱的试了一下博客园的服务器也让传图片木马上去,不过好像被和谐掉了,直接重命名了。
纠结2:2.6.6的fck默认不开启上传功能的,需要自己小设一下
1.将根目录下的fckconfig.js里的
var _FileBrowserLanguage = 'asp' ; // asp | aspx | cfm | lasso | perl | php | py
var _QuickUploadLanguage = 'asp' ; // asp | aspx | cfm | lasso | perl | php | py
FCKConfig.DefaultLanguage = 'zh-cn' ;
换成自己需要的语言类型
2.如果是asp版本的需要将filemannager\connector\asp下的config.asp
里的ConfigIsEnabled = true 设置为true,要不上传的时候看上去上传文件一直在等待。
3.中文乱码问题,用最新版的就可以了,基本上是因为上传的时候回显到控件上的编码出的问题
4.顺便带一下,如果是用.net的版的把里面的东西精简一下,只留下aspx的文件
纠结3:如果上传的时候进度条一直转啊转,请将FileWorkerBase 类下面这句注释掉
Response.Write(@"(function(){var d=document.domain;while (true){try{var A=window.top.opener.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\.|$)/,'');if (d.length==0) break;try{}catch (e){break;}}})();");