常見的XSS檢測代碼:
<script>alert(1)</script> // 調用JavaScript語句
<img src=x onerror=alert(1)> // src是錯誤的 就會調用error函數
<a href=javascript:alert(1)> // 點擊a即可觸發
實際應用中web程序往往會通過一些過濾規則來防止帶有惡意代碼的用戶輸入被顯示。當上述代碼被注入到輸入框或者URL參數中時,可能會成功也可能會失敗,如果失敗了,并不意味著網站不存在XSS漏洞,需要對其進行繞過等方式發掘安全漏洞。
這里,給大家總結一些XSS繞過方法。
1、大小寫繞過
某些網站僅僅過濾了<script>標簽,而忽略了大小寫替換同樣可以造成瀏覽器觸發XSS。具體方式為測試語句:
http://192.168.1.102/xss/example2.php?name=<sCript>alert("hey!")</scRipt>
2、利用過濾后返回語句再次構成攻擊語句來繞過
當網站設置過濾規則時,可以觸發XSS的關鍵字(<script>)被進行了過濾,在查看網頁源代碼時,script標簽被去除掉了,于是我們就可以人為地制造一種巧合,讓過濾完script標簽后的語句中還有script標簽(畢竟alert函數還在),像這樣:
<div>http://192.168.1.102/xss/example3.php?name=<sCri<script>pt>alert("hey!")</scRi</script>pt></div><div></div>
3、嘗試使用其他標簽來構造XSS
當script標簽被完全過濾時,這時可以嘗試使用其它標簽來構造XSS。
這里以<img>標簽進行說明:
http://192.168.1.102/xss/example4.php?name=<img
src='w.123' onerror='alert("hey!")'>
4、主動閉合標簽
可以通過手動閉合掉引號標簽等方式來達到測試XSS漏洞的目的。
閉合標簽
如果在查看頁面的源代碼的過程中,發現輸入的字符串或者輸入字符串的部分,那么就可以設法通過閉合字符串的方式來測試XSS漏洞。
比如,我們所輸入的字符串被放入到<input>標簽中(<INPUT type="text" value='<SCRIPT>alert("XSS")</SCRIPT>'/>),那么我們可以修改輸入來閉合<input>標簽,執行script腳本。
當我們輸入為'/><SCRIPT>alert("XSS")</SCRIPT>,可以發現我們的代碼執行了,說明此處存在XSS漏洞。
繞過引號
同樣的例子,但是我們假設管理員在我們的單引號之前放置了一個“\”,有時候雙引號之前也會放置,通過一些類似add_slashes的函數可以實現,這個就是轉義字符,我們先前的代碼就會變成這樣:
<INPUT type="text"value='\'><SCRIPT>alert(\"XSS\")</SCRIPT>'>
有一些方法可以繼續,但是要看過濾的那個函數是怎么放的了。其中一個方法就是使用字符實體,學過html的都知道,就是一些特殊字符會用一些固有的符號組合來表示,舉個例子,你不能用<>表示大于和小于,因為這被解釋為html標簽,但是,你如果要用,可以用下面的來代替。
使用"或者"來代替我們的雙引號,有時候可以繞過過濾。例子:
<script>alert("XSS")</script>
<script>alert("XSS")</script>
<script>alert(&XSS&)</script>
如果這都被過濾了,那我們可以使用JavaScript的fromCharCode函數,這個函數把指定的Unicode值轉換成字符串。
比如:
<script>alert("XSS")</script>
<script>alert(String.fromCharCode(88,83,83))</script>
<INPUT type="text"value='\'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>'>
5、通過組合編碼方式來測試XSS漏洞
在使用XSS編碼測試時,需要考慮HTML渲染的順序,特別是針對多種編碼組合時,要選擇合適的編碼方式進行測試。
當瀏覽器接受到一份HTML代碼后,會對標簽之間(<p>xxx</p>等,<script>除外)、標簽的屬性中(<a href='xxxx'>)進行實體字符解碼變為相應的字符,而不會發揮出其本來該有的功能,如:<被解碼為<后僅被當作字符,而不會被當成標簽名的起始。既然是字符串,那在href='xx'這些屬性值本來就是字符串的地方可以作為一種可能的繞過的手段。如:
<a href="javascript:alert(1)"></a>
被解釋后為<a href="javascript:alert(1)"></a>,可以彈窗。
總之,在進行XSS注入測試的時候要關注標簽的閉合,這跟sql語句的閉合是差不多的,不過這個變成了HTML標簽。此外思路要發散,通過語句跟繞過方式的不同搭配來構造payload,比如說當瀏覽器對script進行了轉義的時候,我們可以嘗試用其他標簽來構造,當on被轉義的時候,我們可以采用偽協議的方式構造即?javascript:,總之在構建payload的時候要發散思維。
下面邀請大家進入【Python自動化測試學習交流群】進群方式如下:
關注我的頭條號,添加V:atstudy-js,備注“頭條”,即可邀請你進群學習交流~~
TTP(Hypertext Transfer Protocol)和HTTPS(Hypertext Transfer Protocol Secure)是Web應用程序中常見的數據傳輸協議。HTTP是一種無狀態的應用層協議,主要用于Web瀏覽器與服務器之間的通信。HTTPS則是在HTTP的基礎上加入了SSL(Secure Sockets Layer)或TLS(Transport Layer Security)協議,以提供數據加密和安全通信。
云服務器,高防服務器就選藍易云,頭條搜索:藍易云
云服務器,高防服務器就選藍易云,頭條搜索:藍易云
HTTP協議是一個基于請求-響應模式的協議。客戶端(通常是Web瀏覽器)向服務器發送請求,服務器處理請求并返回響應。HTTP請求和響應都由頭部和可選的主體組成。
HTTP的特點:
HTTPS在HTTP的基礎上加入了SSL/TLS協議,通過加密通信確保數據的安全性。SSL/TLS提供了三個主要功能:加密、數據完整性和身份驗證。
HTTPS的特點:
特性 | HTTP | HTTPS |
數據傳輸 | 明文傳輸 | 加密傳輸 |
安全性 | 容易被竊聽和篡改 | 提供數據加密和身份驗證 |
性能 | 較高 | 較低(因加密解密開銷) |
使用場景 | 不敏感數據傳輸 | 敏感數據傳輸(如支付信息) |
XSS(Cross-Site Scripting)攻擊是一種常見的Web安全漏洞,攻擊者通過在受信任的網站上注入惡意腳本,使其在用戶的瀏覽器上執行。XSS攻擊的主要目標是竊取用戶數據、劫持會話以及進行其他惡意操作。
反射型XSS攻擊通過將惡意腳本嵌入到URL參數中,誘騙用戶點擊包含惡意腳本的鏈接。當用戶點擊鏈接時,惡意腳本被反射到服務器的響應中,并在用戶瀏覽器中執行。
示例:
<a href="http://example.com?search=<script>alert('XSS')</script>">Click me</a>
存儲型XSS攻擊將惡意腳本存儲在服務器端的數據存儲中(如數據庫),當用戶訪問包含該數據的頁面時,惡意腳本被執行。此類攻擊通常發生在用戶輸入內容的地方,如評論區或論壇帖子。
示例:
<input type="text" name="comment" value="<script>alert('XSS')</script>">
DOM-based XSS攻擊利用網頁的DOM結構,通過操作DOM元素觸發惡意腳本。與反射型和存儲型不同,DOM-based XSS攻擊不依賴服務器端的響應,而是直接在客戶端進行。
示例:
<script>
var search=location.hash.substring(1);
document.write("<div>" + search + "</div>");
</script>
對用戶輸入的數據進行嚴格驗證和過濾,確保只接受預期格式的輸入。可以使用正則表達式或白名單來限制輸入內容。
示例:
import re
def validate_input(user_input):
if re.match("^[a-zA-Z0-9_]+$", user_input):
return True
return False
對輸出到瀏覽器的數據進行編碼和轉義,防止惡意腳本在瀏覽器中執行。常用的方法包括HTML實體編碼和JavaScript轉義。
示例:
<!-- HTML實體編碼 -->
<div>{{ user_input | escape }}</div>
內容安全策略(CSP)是一種Web安全策略,通過限制頁面可以加載的資源類型,防止XSS攻擊。可以通過設置HTTP頭部或HTML meta標簽來配置CSP。
示例:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self';">
為了更好地理解HTTP、HTTPS和XSS攻擊的概念,下面提供了一張思維導圖:
以上內容詳細介紹了HTTP和HTTPS的工作原理及其區別,以及XSS攻擊的類型和防范方法。通過這些知識的理解和應用,可以有效提升Web應用的安全性,防范潛在的安全威脅。
在處理日常的業務開發當中,數據拷貝是經常需要用到的。但是 javascript 提供的數據操作 Api 當中能實現對象克隆的都是淺拷貝,比如 Object.assign 和 ES6 新增的對象擴展運算符(...),這兩個 Api 只能實現對象屬性的一層拷貝,對于復制的屬性其值如果是引用類型的情況下,拷貝過后的新對象還是會保留對它們的引用。
ESMAScript 給我們提供了關于操作 JSON 數據的兩個 APi,通過把 javascript 對象先轉換為 JSON 數據,之后再把 JSON 數據轉換為 Javascript 對象,這樣就簡單粗暴的實現了一個 javascript 對象的深拷貝,不論這個對象層級有多深,都會完全與源對象沒有任何聯系,切斷其屬性的引用,現在看一下這兩個 API 用代碼是怎么實現的。
// 現創建一個具有深度嵌套的源對象
const sourceObj={
nested: {
name: 'KongLingWen',
},
}
// 把源對象轉化為JSON格式的字符串
const jsonTarget=JSON.stringify(sourceObj)
// 以解析json數據的方式轉換為javascript對象
let target
try {
target=JSON.parse(jsonTarget) //數據如果不符合JSON對象格式會拋錯,這里加一個錯誤處理
} catch (err) {
console.error(err)
}
target.nested.name=''
console.log(soruceObj.nested.name) //KongLingWen
復制代碼
代碼最后通過更改新拷貝對象的 name 屬性 ,輸出源對象此屬性的值不變,這說明我們以這種方式就實現了一個對象深拷貝。
此方式拷貝對象因為有以上這么多缺陷,所以我們不如自己封裝一個屬于自己的 javascript 對象深拷貝的函數,反而一勞永逸。
對象屬性的拷貝無疑就是把源對象的屬性以深度遍歷的方式復制到新的對象上,當遍歷到一個屬性值為對象類型的值時,就需要針對這個值進行再次的遍歷,也是就用遞歸的方式遍歷源對象的所有屬性。讓我們先看這一部分代碼
function cloneDeep(obj) {
const result={}
for (let key in obj) {
// 判斷key 是否是對象自身上的屬性,以避免對象原型鏈上屬性的拷貝
if (obj.hasOwnProperty(key)) {
result[key]=cloneDeep(obj[key]) //需要對屬性值遞歸拷貝
}
}
}
復制代碼
這段代碼是對象屬性深拷貝的邏輯,但是不同的數據類型各自有其特殊的操作方式需要處理,下面就把這些處理邊界場景的代碼補充上,看看完成的代碼應該是怎樣的
function isPrimitiveValue(value) {
if (
typeof value==='string' ||
typeof value==='number' ||
value==null ||
typeof value==='boolean' ||
Number.isNaN(value)
) {
return true
}
return false
}
function cloneDeep(value) {
// 判斷拷貝的數據類型,如果為原始類型數據,直接返回其值
if (isPrimitiveValue(value)) {
return value
}
// 定義一個保存引用類型的變量,根據 引用數據類型不同的子類型初始化不同的值,以下對象類型的判斷和初始化可以根據自身功能的需要做刪減。這里列出了所有的引用類型的場景。
let result
if (typeof value==='function') {
// result=value 如果復制函數的時候需要保持同一個引用可以省去新函數的創建,這里用eval創建了一個原函數的副本
result=eval(`(${value.toString()})`)
} else if (Array.isArray(value)) {
result=[]
} else if (value instanceof RegExp) {
result=new RegExp(value)
} else if (value instanceof Date) {
result=new Date(value)
} else if (value instanceof Number) {
result=new Number(value)
} else if (value instanceof String) {
result=new String(value)
} else if (value instanceof Boolean) {
result=new Boolean(value)
} else if (typeof value==='object') {
result=new Object()
}
for (let key in value) {
if (value.hasOwnProperty(key)) {
try {
result[key]=cloneObject(value[key]) //屬性值為原始類型包裝對象的時候,(Number,String,Boolean)這里會拋錯,需要加一個錯誤處理,對運行結果沒有影響。
} catch (error) {
// console.error(error)
}
}
}
return result
}
復制代碼
代碼中首先封裝了一個判斷數據是否是原始類型的方法,這里只是為了保持 cloneDeep 函數的功能干凈,其實你也可以完全放到一塊,這個完全取決于自己的編碼風格。如果在業務上需要有多處判斷數據是原始類型還是引用類型的場景時,以上這種代碼功能抽離的方式就方便處理了。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。