## **一、什么是 XSS ?**
XSS (Cross Site Scripting),即跨站腳本攻擊,是一種常見于 Web 應用中的計算機安全漏洞。惡意攻擊者往 Web 頁面里嵌入惡意的客戶端腳本,當用戶瀏覽此網頁時,腳本就會在用戶的瀏覽器上執行,進而達到攻擊者的目的。比如獲取用戶的 Cookie、導航到惡意網站、攜帶木馬等。借助安全圈里面非常有名的一句話:
~~~text
所有的輸入都是有害的。
~~~
這句話把 XSS 漏洞的本質體現的淋漓盡致。大部分的 XSS 漏洞都是由于沒有處理好用戶的輸入,導致惡意腳本在瀏覽器中執行。任何輸入提交數據的地方都有可能存在 XSS。
## **二、XSS 攻擊分類**
第一種:反射型
第二種:持久型
第三種:DOM 型( DOM Based XSS )
## **三、XSS 防御**
**1、使用 XSS Filter**
針對用戶提交的數據進行有效的驗證,只接受我們規定的長度或內容的提交,過濾掉其他的輸入內容。比如:
表單數據指定值的類型:年齡只能是 int 、name 只能是字母數字等。
過濾或移除特殊的 html 標簽:\<script\>、\<iframe\>等。
過濾 js 事件的標簽:onclick、onerror、onfocus等。
**2、html 實體**
當需要往 HTML 標簽之間插入不可信數據的時候,首先要做的就是對不可信數據進行 HTML Entity 編碼,
在 html 中有些字符對于 HTML 來說是具有特殊意義的,所以這些特殊字符不允許在文本中直接使用,需要使用實體字符。
html 實體的存在是導致 XSS 漏洞的主要愿意之一,因此我們需要將實體轉化為相應的實體編號。
**3、JavaScript編碼**
這條原則主要針對動態生成的JavaScript代碼,這包括腳本部分以及HTML標簽的事件處理屬性(如onerror, onload等)。
在往JavaScript代碼里插入數據的時候,只有一種情況是安全的,那就是對不可信數據進行JavaScript編碼,
并且只把這些數據放到使用引號包圍起來的值部分(data value)之中,除了上面的那些轉義之外,還要附加上下面的轉義:
\ 轉成 \\
/ 轉成 \/
; 轉成 ;(全角;)
注意:在對不可信數據做編碼的時候,不能圖方便使用反斜杠\ 對特殊字符進行簡單轉義,比如將雙引號 ”轉義成 \”,
這樣做是不可靠的,因為瀏覽器在對頁面做解析的時候,會先進行HTML解析,然后才是JavaScript解析,
所以雙引號很可能會被當做HTML字符進行HTML解析,這時雙引號就可以突破代碼的值部分,使得攻擊者可以繼續進行XSS攻擊;
另外,輸出的變量的時候,變量值必須在引號內部,避免安全問題;更加嚴格的方式,對除了數字和字母以外的所有字符,
使用十六進制\xhh 的方式進行編碼。
**4、Http Only cookie**
許多 XSS 攻擊的目的就是為了獲取用戶的 cookie,將重要的 cookie 標記為 http only,
這樣的話當瀏覽器向服務端發起請求時就會帶上 cookie 字段,但是在腳本中卻不能訪問 cookie,
這樣就避免了 XSS 攻擊利用 js 的 document.cookie獲取 cookie。
HttpOnly是cookie里面一個屬性,假如在cookie里面設置了HttpOnly這個屬性,那么JavaScript將無法訪問到我們到cookie,
但是這個方法也只能是防御cookie劫持。HttpOnly設置規則如下。
```
<?php
????header("set-cookie: username=admin");
????header("set-cookie: password=123456;httponly",false);
?>
```
**5、X-Frame-Options配置:**
低危漏洞- X-Frame-Options Header未配置X-Frame-Options 響應頭
X-Frame-Options HTTP 響應頭是用來給瀏覽器指示允許一個頁面可否在 \<frame\>, \</iframe\> 或者 \<object\> 中展現的標記。
網站可以使用此功能,來確保自己網站的內容沒有被嵌到別人的網站中去,也從而避免了點擊劫持 (clickjacking) 的攻擊。
使用 X-Frame-Options
X-Frame-Options 有三個值:
**  DENY**
  表示該頁面不允許在 frame 中展示,即便是在相同域名的頁面中嵌套也不允許。
**  SAMEORIGIN**
  表示該頁面可以在相同域名頁面的 frame 中展示。
**  ALLOW-FROM uri**
  表示該頁面可以在指定來源的 frame 中展示。
  換一句話說,如果設置為 DENY,不光在別人的網站 frame 嵌入時會無法加載,在同域名頁面中同樣會無法加載。另一方面,如果設置為 SAMEORIGIN,那么頁面就可以在同域名頁面的 frame 中嵌套。
**配置代理服務器**:
**  配置 Apache**
  在所有頁面上發送 X-Frame-Options 響應頭,需要把下面這行添加到 ‘site’ 的配置中:
```
Header always append X-Frame-Options SAMEORIGIN
```
**  配置 nginx**
  配置 nginx 發送 X-Frame-Options 響應頭,把下面這行添加到 ‘http’, ‘server’ 或者 ‘location’ 的配置中:
```
add_header X-Frame-Options SAMEORIGIN;
```
**  配置 IIS**
  配置 IIS 發送 X-Frame-Options 響應頭,添加下面的配置到 Web.config 文件中:
```
<system.webServer>
...
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
...
</system.webServer>
```
**總結:**
對輸入輸出做嚴格的過濾、添加HttpOnly、X-Frame-Options配置
- 空白目錄
- containerd
- php
- php常用函數
- 點語法
- 依賴注入
- 反射
- 迭代器和yield
- array_walk
- str_replace
- openssl_decrypt
- array_merge
- 閉包
- 深拷貝與淺拷貝
- 面向對象
- 魔術方法
- __invoke
- __isset 和 __unset
- __clone
- 常用知識點
- 訪問權限
- 抽象類
- 多態
- php框架
- tp
- tp3
- tp5
- job
- laravel
- 中間件
- laravel閉包
- symfony
- 小工具
- phpexcel
- xlswrite
- 設計模式
- 事件event
- 里氏替換原則
- 借鑒
- RESTful API
- 環境安裝
- 編譯安裝
- 編譯安裝后擴展補充
- php小記錄
- php-fpm
- 容器(Container)
- composer
- composer踩坑
- mysql
- 基礎知識
- 外鍵
- 索引
- 觸發器
- 定時器
- 分表
- 分區
- 連接查詢
- 事務
- 鎖機制
- 視圖
- 存儲過程
- 查詢
- 字符截取
- 批量修改表名(前綴)
- explain
- when_case
- pdo
- mysql優化
- 主從復制
- 權限分配
- 實用例子
- 查詢用戶
- 常見問題
- 5.7group by問題
- 遠程鏈接慢問題
- 查看進程
- 遠程訪問
- 常用小記
- mysqldump
- 備份還原
- 系統盤遷移數據盤
- 安裝sql
- 安裝MariaDB
- docker
- 安裝docker
- 配置centos開發環境
- docker運行程序
- rabbitmq
- 刪除無用鏡像
- 解決Centos firewalld導致的docker容器內無法訪問外網,無法訪問其他容器(host沒辦法解析)
- docker-compose
- docker-selenium
- ports 配置
- docker-compose-settings
- 安裝
- docker-compose常用配置
- docker常用命令
- build
- docker-hub加速
- docker-run
- Dockerfile
- apt-get update 無法升級
- 阿里打標簽
- 打包流程
- docker-network
- ufw 允許 docker 容器聯網
- 安裝containerd
- linux
- centos7
- 常用語法
- chmod
- chown
- find
- grep
- /etc/passwd
- chattr
- In軟連接
- 文件目錄大小
- xargs
- 管道用法
- top
- free
- 端口占用
- 壓縮解壓
- tar
- gzip
- zip
- 2>&1
- 環境變量
- 服務管理
- systemctl
- sed
- shell腳本
- time
- journal
- history
- linux-set
- linux-curl
- cp
- umask
- mkdir
- http狀態碼
- awk
- lsof
- crontab
- supervisor
- 常用命令匯總
- 用戶權限
- 普通用戶添加sudo權限
- sudo su
- 添加用戶
- 查看用戶信息
- 修改用戶信息
- 特殊權限
- 系統命令
- 常用小技巧
- vim小技巧
- 防火墻
- 常用規則
- iptables
- 磁盤清理
- 分區掛載
- linux-sh
- tmux
- 多命令執行
- 常用工具
- telnet
- ip轉發
- nohup
- watch
- dig
- 查看磁盤IO
- ssh
- 修改ssh端口
- ssh免密登錄
- 配置文件
- 公鑰分發
- xsync
- 國內鏡像站
- github加速
- 測網速
- 網卡
- 清理日志備份
- 配置sftp
- shell
- rpm
- 安全
- 安裝openssl
- 安裝openssh
- 禁用selinux和防火墻
- lanp環境安裝
- versionTool
- git
- git基本用法
- Gogs搭建
- git鉤子
- git的習慣配置
- phpStorm設置git bash
- git bash 設置代理
- gitignore 不起作用的解決辦法
- gitea搭建
- 同步主干到fork
- git修改地址
- svn
- svn基本操作
- svn 鉤子應用
- svn多版本操作
- Go語言
- Go語言基礎
- 安裝環境
- linux安裝
- window安裝
- 工具使用教程
- linux終端分屏Screen
- keepass 帳號密碼管理
- phpstorm
- 去掉window換行符
- php_cs
- 自定義快捷模塊
- phpstorm快捷鍵
- curl
- 正則
- 設計架構
- 設計模式的六大原則
- 計算機基礎
- TCP三次握手
- OSI7層
- http狀態返回碼
- 前端框架
- Vue
- Angular
- React
- node
- 服務端渲染(SSR)
- MVVM
- nuxt
- pm2
- js
- Promise
- es6
- 常用站點
- 工具類
- 學習類
- ps常用命令
- nginx
- 緩存
- 配置
- TCP
- 常用配置
- ng優先級
- vhost注意點
- nginx第一層驗證
- 轉發(跨域問題)
- 404
- nginx日志格式化
- 重啟腳本
- 寶塔禁用境外ip訪問
- ng統計
- ng編譯安裝
- 防盜鏈
- 技術相關了解
- ddos
- xss
- mysql防注入
- csrf攻擊
- 郵箱系統原理
- DNS
- python
- Selenium
- 微信
- 公眾號
- 公眾號配置
- 用戶授權
- 小程序
- 公有云
- 華為云
- JAVA
- springboot
- windows
- service
- WSL
- 目錄遷移
- wsl2 踩坑
- NoSql
- mongodb
- 安裝mongodb
- redis
- redis-windows
- redis-linux
- openstack
- ====副業====
- 擼茅臺
- 網絡
- 單位換算
- DB
- clickhouse
- mac