網站不管是前台的用戶評論,還是后台的添加商品描述都會用到在線編輯器,
一般給后台管理人員進行網站編輯使用的是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);
}
