狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

富文本輸入框控件沒做安全處理被XSS攻擊了

admin
2025年1月1日 13:30 本文熱度 54

前言

相信很多前端小伙伴項目中都用到了富文本,但你們有沒有做防XSS攻擊處理?最近的項目由于比較緊急我也沒有處理而是直接正常使用,但公司內(nèi)部有專門的安全部門針對測試,然后測出來富文本被XSS攻擊了,而且危險級別為高。

啊這....,那我就去解決一下吧,順便從XSS和解決方案兩個角度記錄到下來畢竟好久沒更新文章了。

先說說什么是XSS攻擊?

「簡述」XSS全稱Cross-Site Scripting也叫跨站腳本攻擊,是最最最常見的網(wǎng)絡(luò)安全漏洞,其實就是攻擊者在受害者的瀏覽器中注入惡意腳本執(zhí)行。這種攻擊通常發(fā)生在 Web 應(yīng)用程序未能正確過濾用戶輸入的情況下,導(dǎo)致惡意腳本被嵌入到合法的網(wǎng)頁中。執(zhí)行后會產(chǎn)生竊取信息、篡改網(wǎng)頁、和傳播病毒與木馬等危害,后果相當(dāng)嚴(yán)重。

XSS又有三大類

存儲型 XSS即Stored XSS

惡意的腳本被放置在目標(biāo)服務(wù)器上面,通過正常的網(wǎng)頁請求返回給用戶端執(zhí)行。

「例如」 在觀看某個私人博客評論中插入惡意腳本,當(dāng)其他用戶訪問該頁面時,腳本會執(zhí)行危險操作。

反射型 XSS即Reflected XSS

惡意的腳本通過 URL 參數(shù)或一些輸入的字段傳遞給目標(biāo)的服務(wù)器,用戶在正常請求時會返回并且執(zhí)行。

「例如」 通過鏈接中的參數(shù)后面注入腳本,當(dāng)用戶點擊此鏈接時,腳本就會在用戶的瀏覽器中執(zhí)行危險操作。

DOM 基于的 XSS即DOM-based XSS

惡意的腳本利用 DOM(Document Object Model)操作來修改頁面內(nèi)容。這種類型的 XSS 攻擊不涉及服務(wù)器端的代碼操作,僅僅是通過客戶端插入 JavaScript 代碼實現(xiàn)操作。

富文本就是屬于第一種,把腳本藏在代碼中存到數(shù)據(jù)庫,然后用戶獲取時會執(zhí)行。

富文本防XSS的方式?

網(wǎng)上一大堆不明不白的方法還有各種插件可以用,但其實自己轉(zhuǎn)義一下就行,根本不需要復(fù)雜化。

當(dāng)我們不做處理時傳給后臺的富文本數(shù)據(jù)是這樣的。

上面帶有標(biāo)簽,甚至有srcscript之類的操作,在里面放一些腳本真的太簡單了。

因此,我們創(chuàng)建富文本成功提交給后臺的時候把各種<>/\之類危險符號轉(zhuǎn)義成指定的字符就能防止腳本了。

如下所示,方法參數(shù)value就是要傳遞給后臺的富文本內(nèi)容。

  export const getXssFilter = (value: string): string => {    // 定義一個對象來存儲特殊字符及其對應(yīng)的 HTML 實體    const htmlEntities = {      '&': '&',      '<': '<',      '>': '>',      '"': '"',      '\'': ''',      '\\': '\',      '|': '|',      ';': ';',      '$': '$',      '%': '%',      '@': '@',      '(': '(',      ')': ')',      '+': '+',      '\r': '',      '\n': '',      ',': ',',    };      // 使用正則表達(dá)式替換所有特殊字符    let result = value.replace(/[&<>"'\\|;$%@()+,]/g, function (match) {      return htmlEntities[match] || match;    });      return result;  };

此時傳給后臺的富文本參數(shù)是這樣的,把敏感符號全部轉(zhuǎn)義。

但展現(xiàn)給用戶看肯定要看正常的內(nèi)容啊,這里就要把內(nèi)容重新還原了,這步操作可以在前端完成,也可以在后端完成。

如果是前端完成可以用以下方法把獲取到的數(shù)據(jù)進(jìn)行轉(zhuǎn)義。

 // 還原特殊字符    export const setXssFilter = (input) => {      return input      .replace(/|/g, '|')      .replace(/&/g, '&')      .replace(/;/g, ';')      .replace(/$/g, '$')      .replace(/%/g, '%')      .replace(/@/g, '@')      .replace(/'/g, '\'')      .replace(/"/g, '"')      .replace(/\/g, '\\')      .replace(/</g, '<')      .replace(/>/g, '>')      .replace(/(/g, '(')      .replace(/)/g, ')')      .replace(/+/g, '+')      .replace(//g, '\r')      .replace(//g, '\n')      .replace(/,/g, ',');    }

但是。。。。

上面只適合使用于純富文本的場景,如果在普通文本的地方回顯會依然觸發(fā)危險腳本。如下所示

其實直接轉(zhuǎn)義后不還原即可解決,但由于是富文本這種情況比較特殊情況,不還原就失去文本樣式了,怎么辦??

最終解決方案是對部分可能造成XSS攻擊的特殊字符和標(biāo)簽進(jìn)行轉(zhuǎn)義處理,例如:script、iframe等。

示例代碼

 export const getXssFilter = (value: string): string => {        // 定義一個對象來存儲特殊字符及其對應(yīng)的 HTML 實體        const htmlEntities = {          '&': '&',          '\'': ''',          '\r': '',          '\n': '',          'script': 'script',          'iframe': 'iframe',          // 'img': 'img',          'object': 'ojst',          'embed': 'embed',          'on': 'on',          'javascript': 'javascript',          'expression': 'expresssion',          'video': 'video',          'audio': 'audio',          'svg': 'svg',          'background-image': 'background-image',        };              // 使用正則表達(dá)式替換所有特殊字符        let result = value.replace(/[&<>"'\\|;$%@()+,]/g, function (match) {          return htmlEntities[match] || match;        });              // 額外處理 `script`、`iframe`、`img` 等關(guān)鍵詞        result = result.replace(/script|iframe|object|embed|on|javascript|expression|background-image/gi, function (match) {          return htmlEntities[match] || match;        });              return result;      };

效果只會對敏感部分轉(zhuǎn)義

但這種方案不用還原轉(zhuǎn)義,因為做的針對性限制。

小結(jié)

其實就是對特殊符號轉(zhuǎn)換后還原的思路,相當(dāng)?shù)暮唵巍H绻抢飳懙牟缓没蛘哂懈玫慕ㄗh,歡迎大佬指點啦。


閱讀原文:原文鏈接


該文章在 2025/1/2 13:05:27 編輯過

全部評論1

admin
2025年1月2日 13:6

 點晴公司的解決代碼,用以下代碼做提交前的預(yù)處理,輸出時再臨時轉(zhuǎn)換為正常的HTML代碼,并且屏蔽掉iframe和script:

function HtmToTxt(tmpInfo){

var str_info=tmpInfo;

if (str_info+"CS"!="CS"){

str_info = str_info.replace(/=/g, "$01@");

str_info = str_info.replace(/&/g, "$02@");

str_info = str_info.replace(/%/g, "$03@");

str_info = str_info.replace(/\(/g, "$04@");

str_info = str_info.replace(/\)/g, "$05@");

str_info = str_info.replace(/>/g, "$06@");

str_info = str_info.replace(/</g, "$07@");

str_info = str_info.replace(/{/g, "$08@");

str_info = str_info.replace(/}/g, "$09@");

str_info = str_info.replace(/,/g, "$10@");

str_info = str_info.replace(/\+/g, "$11@");

str_info = str_info.replace(/\"/g, "$12@");

str_info = str_info.replace(/!/g, "$13@");

str_info = str_info.replace(/\'/g, "$14@");

str_info = str_info.replace(/;/g, "$15@");

str_info = str_info.replace(/\//g, "$16@");

str_info = str_info.replace(/-/g, "$17@");

str_info = str_info.replace(/#/g, "$18@");

str_info = str_info.replace(/\r\n/g, "$25@");

str_info = str_info.replace(/\n/g, "$25@");

str_info = str_info.replace(/ /g, "$26@");

str_info = str_info.replace(/script/gi, "$27@");

str_info = str_info.replace(/select/gi, "$28@");

str_info = str_info.replace(/update/gi, "$29@");

str_info = str_info.replace(/delete/gi, "$30@");

str_info = str_info.replace(/from/gi, "$31@");

str_info = str_info.replace(/where/gi, "$32@");

str_info = str_info.replace(/create/gi, "$33@");

str_info = str_info.replace(/alter/gi, "$34@");

str_info = str_info.replace(/drop/gi, "$35@");

str_info = str_info.replace(/truncate/gi, "$36@");

str_info = str_info.replace(/insert/gi, "$37@");

str_info = str_info.replace(/union/gi, "$38@");

str_info = str_info.replace(/exec/gi, "$39@");

str_info = str_info.replace(/\?/g, "$40@");

str_info = str_info.replace(/\[/g, "$41@");

str_info = str_info.replace(/\]/g, "$42@");

}

return str_info;

}


function TxtToHtm(tmpInfo){

var str_info=tmpInfo;

if ((str_info+"CS").indexOf("&")>-1 && (str_info+"CS").indexOf("¥")>-1){

str_info = str_info.replace(/=/g, "=");

str_info = str_info.replace(/&/g, "&");

str_info = str_info.replace(/%/g, "%");

str_info = str_info.replace(/(/g, "(");

str_info = str_info.replace(/)/g, ")");

str_info = str_info.replace(/>/g, ">");

str_info = str_info.replace(/

str_info = str_info.replace(/{/g, "{");

str_info = str_info.replace(/}/g, "}");

str_info = str_info.replace(/,/g, ",");

str_info = str_info.replace(/+/g, "+");

str_info = str_info.replace(/"/g, "\"");

str_info = str_info.replace(/!/g, "!");

str_info = str_info.replace(/'/g, "'");

str_info = str_info.replace(/;/g, ";");

str_info = str_info.replace(///g, "/");

str_info = str_info.replace(/-/g, "-");

str_info = str_info.replace(/#/g, "#");

str_info = str_info.replace(/ /g, " ");

str_info = str_info.replace(/ /g, " ");

str_info = str_info.replace(/ /g, "  ");

str_info = str_info.replace(/"/g, "\"");

str_info = str_info.replace(/'/g, "'");

str_info = str_info.replace(/ /g, "\r\n");

str_info = str_info.replace(/ /g, "\r\n");

str_info = str_info.replace(/ /g, "\r\n");

str_info = str_info.replace(/select/g, "select");

str_info = str_info.replace(/update/g, "update");

str_info = str_info.replace(/delete/g, "delete");

str_info = str_info.replace(/from/g, "from");

str_info = str_info.replace(/where/g, "where");

str_info = str_info.replace(/create/g, "create");

str_info = str_info.replace(/alter/g, "alter");

str_info = str_info.replace(/drop/g, "drop");

str_info = str_info.replace(/truncate/g, "truncate");

str_info = str_info.replace(/insert/g, "insert");

str_info = str_info.replace(/union/g, "union");

str_info = str_info.replace(/exec/g, "exec");

str_info = str_info.replace(/\<script/gi, "&lt;script");

str_info = str_info.replace(/\<\/script\>/gi, "&lt;script");

str_info = str_info.replace(/\<iframe/gi, "&lt;iframe");

str_info = str_info.replace(/\<\/iframe\>/gi, "&lt;/iframe&gt;");

}

if ((str_info+"CS").indexOf("$")>-1 && (str_info+"CS").indexOf("@")>-1){

str_info = str_info.replace(/\$01\@/g, "=");

str_info = str_info.replace(/\$02\@/g, "&");

str_info = str_info.replace(/\$03\@/g, "%");

str_info = str_info.replace(/\$04\@/g, "(");

str_info = str_info.replace(/\$05\@/g, ")");

str_info = str_info.replace(/\$06\@/g, ">");

str_info = str_info.replace(/\$07\@/g, "<");

str_info = str_info.replace(/\$08\@/g, "{");

str_info = str_info.replace(/\$09\@/g, "}");

str_info = str_info.replace(/\$10\@/g, ",");

str_info = str_info.replace(/\$11\@/g, "+");

str_info = str_info.replace(/\$12\@/g, "\"");

str_info = str_info.replace(/\$13\@/g, "!");

str_info = str_info.replace(/\$14\@/g, "'");

str_info = str_info.replace(/\$15\@/g, ";");

str_info = str_info.replace(/\$16\@/g, "/");

str_info = str_info.replace(/\$17\@/g, "-");

str_info = str_info.replace(/\$18\@/g, "#");

str_info = str_info.replace(/\$19\@/g, " ");

str_info = str_info.replace(/\$20\@/g, "  ");

str_info = str_info.replace(/\$21\@/g, "\"");

str_info = str_info.replace(/\$22\@/g, "'");

str_info = str_info.replace(/\$23\@/g, "\r\n");

str_info = str_info.replace(/\$24\@/g, "\r\n");

str_info = str_info.replace(/\$25\@/g, "\r\n");

str_info = str_info.replace(/\$26\@/g, " ");

str_info = str_info.replace(/\$27\@/g, "script");

str_info = str_info.replace(/\$28\@/g, "select");

str_info = str_info.replace(/\$29\@/g, "update");

str_info = str_info.replace(/\$30\@/g, "delete");

str_info = str_info.replace(/\$31\@/g, "from");

str_info = str_info.replace(/\$32\@/g, "where");

str_info = str_info.replace(/\$33\@/g, "create");

str_info = str_info.replace(/\$34\@/g, "alter");

str_info = str_info.replace(/\$35\@/g, "drop");

str_info = str_info.replace(/\$36\@/g, "truncate");

str_info = str_info.replace(/\$37\@/g, "insert");

str_info = str_info.replace(/\$38\@/g, "union");

str_info = str_info.replace(/\$39\@/g, "exec");

str_info = str_info.replace(/\$40\@/g, "?");

str_info = str_info.replace(/\$41\@/g, "[");

str_info = str_info.replace(/\$42\@/g, "]");

str_info = str_info.replace(/\<script/gi, "&lt;script");

str_info = str_info.replace(/\<\/script\>/gi, "&lt;script");

str_info = str_info.replace(/\<iframe/gi, "&lt;iframe");

str_info = str_info.replace(/\<\/iframe\>/gi, "&lt;/iframe&gt;");

}

return str_info;

}?

附件:HtmToTxt.rar?

該評論在 2025/1/2 13:08:25 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務(wù)費用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務(wù)都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved