网站不管是前台的用户评论,还是后台的添加商品描述都会用到在线编辑器,
一般给后台管理人员进行网站编辑使用的是CKEditor编辑器,给网友使用的是UBB编辑器。
CKEditor生成的是Html标签,因此当用户输入的是script或Html代码时,浏览器会执行这些代码,产生一些我们程序员不希望看到的结果,也就是xss攻击。
UBB生成的是自己的一套标签,可以防止xss跨站点脚本攻击(但仍避免不了在源码状态下手动输入一些html或js代码,需要在后台做处理)。
CKEditor使用:
一、在项目中使用步骤:
1. 将CKEditor包添加到项目中(主要包含ckeditor.js文件、themes文件等)
2. 在页面需要的地方添加<textarea></textarea>文本域
3. 添加ckeditor.js脚本引用
4. 写js将刚才的textarea文本域变为ckeditor,这段js位置一定要正确,必须在<textarea>加载完后才执行
5. 在头部添加 ValidateRequest="false" 。 因为在文本域中输入富文本,提交给后台时,ckeditor会将其变为html代码提交,在后台进行校验时发现含有‘<’等特殊字符,会报不安全错误信息。
body中代码如下:
<form method="post" >
<textarea id="editor1" rows="20" cols="100"></textarea>
<input type="submit" value="提交"/>
<script type="text/javascript">
var editor=CKEDITOR.replace('editor1');
</script>
点击提交按钮后,在后台Page_Load中处理:
if(!string.IsNullOrEmpty(Request.Form["editor1"]))
{
Response.Write(Request.Form["editor1"]);
}
二、上传图片到CKEditor
因为CKEditor中上传图像只是添加了一个外部链接,不能满足用户需求,
可以使用SWFupload无刷新上传文件组件。
部分设置:
在页面上显示上传成功的图片
function ShowMsg(file,serverData)
{//serverData:从服务端返回的数据格式 ok:***
var data=serverData.split(":");
if(data[0]=="ok")
{
var oEditor = CKEDITOR.instances.editor1;
var img="<img src="+data[1]+"/>";
if(oEditor.mode=='wysiwyg')
{
oEditor.inserHtml(img);
}
else
{
alert("不能在源码状态下插入图片");
}
}
}
三、对评论内容进行敏感词过滤(敏感词分为3类:禁止发表、待审核、替换词)
1.先创建数据表Article_Words(Id,WordPattern,IsForbid,IsMod,ReplaceWord),
2.添加词库的数据到数据库中。词库数据格式:例如每一行:自 由门={BANNED}
strng msg = this.txtCode.Text;
string[] Words = msg.Split(new char[]{'\r','\n'},StringSplitOptions.RemoveEmptyEntries);
for(int i=0;i<Words.Length;i++)
{
string[] Texts=Words[i].Split('=');
string word=Texts[0];
string pattern=Texts[1];
Model.Article_Words model = new Model.Article_Words();
model.WordPattern = word;
if(pattern == "{BANNED}")
{
model.IsForbid = true;
}
else if(pattern == "{MOD}")
{
model.IsMod = true;
}
else
{
model.ReplaceWord = pattern;//替换词
}
//调用BLL层方法,最终将数据添加到数据库
bll.Add(model);
}
3. 判断用户发布的内容中是否含有禁用词
点击提交按钮后,在后台Page_Load中处理:
if(!string.IsNullOrEmpty(Request.Form["editor1"]))
{
string msg = Request.Form["editor1"];
BLL.Article_WordsManager bll = new BLL.Article_WordsManager();
if(bll.GetForbit(msg))
{
Response.Write("你输入的内容含有禁用词!");
Response.End();
}
//当输入的内容含有审核词,评论保存到数据库,等待管理员去验证;并且前台也不能马上显示此条内容,可以显示提示信息(“包含审核词,需审核后方能显示”)。
if(bll.GetMod(msg))
{
}
}
BLL层方法:
public bool GetForbit(string msg)
{
//缓存应用:由于每评论一次, 都要取出这些禁用词、审核词进行验证,频繁操作数据库了,最好第一次读取时,将这些词放入缓存中。
List<string> list = dal.GetForbit(); //取出数据库中所有禁用词
string str = string.Join("|",list.ToArray());
return Regex.IsMatch(msg,str); //正则表达式验证
}
DAL层代码:
public List<string> GetForbit()
{
string sql = "select WordPattern from Article_Words where IsForbid=1";
using(SqlDataReader reader = DbHelperSQL.ExecuteReader(sql))
{
if(reader.HasRows)
{
List<string> list = new List<string>();
while(reader.Read())
{
list.Add(reader.GetString(0));
}
return list;
}
else
{
return null;
}
}
}
四、使用UBB (怎样防止xss攻击?)
UBB编辑器会生成自己特有的标签,这样以来,浏览器不认识这些标签,因此需要在服务器端进行UBB标签→html标签的转换。
public static string Ubb2Html(string ubb) //正则表达式将所有匹配项替换
{
//ubb源码格式如下:
//[url=http://www.bookshop.com]a标签[/url]
//[color=#FFFFFF]颜色标签[/color]
//[b]加粗标签[/b]
//等等
string html;
html = Regex.Replace(ubb,@"\[url=(.+?)\](.+?)\[/url\]", "<a href='$1'>$2</a>");
html = Regex.Replace(html,@"\[color=(.+?)\](.+?)\[/color\]", "<font color='$1'>$2</font>");
html = Regex.Replace(html,@"\[b\](.+?)\[/b\]", "<b>$1</b>");
return html;
}
UBB编辑器虽然会将用户输入的内容生成自己特殊的标签,但仍不能防止用户在源码状态下手动输入一些危险的Html、js代码,为了解决这个问题,只用在服务器端再进行一次特殊字符替换。
例如,对商品发表评论的时候:如果评论内容有"<"等特殊字符,在后台接收到此内容后,对其操作:
前台:
var oEditor = CkEDITOR.instances.CommentContent; //找到编辑器
$("#btnComment").click(function(){
var msg = oEditor.getData();
if(msg!=null){
$.post("/ashx/bookComment.ashx",{"action":"postComment","msg":msg,"bookId":$bookId},function(data){ //提交到服务器的一般处理程序
if(data!=null){ //后台返回数据
$("<li>刚刚:"+data+"</li>").appendTo("#ulComment"); //无刷新显示评论内容
oEditor.setData(""); //将当前编辑器中内容清空
}
},"text");
}
});
服务器端:
if(action == "postComment")
{
string msg = context.Request.Form["msg"];
msg = msg.Replace("<","<").Replace(">",">"); //替换特殊符号
//将用户输入的内容(msg)保存到数据库中
...
//将替换后的消息返回
context.Response.Write(msg);
}