├── @attachment └── images │ ├── Integrated │ └── Linux │ │ └── awk_1662533872617.png │ ├── Security │ ├── Web安全 │ │ └── 信息收集_1661733427720.png │ └── 安全工具 │ │ └── BurpSuite_1660992463972.png │ └── banner │ ├── README.png │ └── shimahara.gif ├── Develop ├── Python │ └── Python 基础.md └── 编程资源.md ├── Integrated ├── FileFilter.md ├── VSCode.md ├── awk.md ├── git.md └── vim.md ├── Network ├── HTTP.md └── TCP&IP.md ├── README.md └── Security ├── Web安全 ├── XSS.md ├── 未授权访问.md └── 逻辑漏洞.md ├── 信息收集 ├── 信息收集.md └── 空间测绘.md ├── 安全工具 ├── ExploitTools.md ├── ScanTools.md └── TrafficTools.md ├── 安全资源.md └── 漏洞赏金.md /@attachment/images/Integrated/Linux/awk_1662533872617.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icekylin/Do1ng/fc89898a3b5ba92ce0bf3342de780cbac2bd6e76/@attachment/images/Integrated/Linux/awk_1662533872617.png -------------------------------------------------------------------------------- /@attachment/images/Security/Web安全/信息收集_1661733427720.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icekylin/Do1ng/fc89898a3b5ba92ce0bf3342de780cbac2bd6e76/@attachment/images/Security/Web安全/信息收集_1661733427720.png -------------------------------------------------------------------------------- /@attachment/images/Security/安全工具/BurpSuite_1660992463972.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icekylin/Do1ng/fc89898a3b5ba92ce0bf3342de780cbac2bd6e76/@attachment/images/Security/安全工具/BurpSuite_1660992463972.png -------------------------------------------------------------------------------- /@attachment/images/banner/README.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icekylin/Do1ng/fc89898a3b5ba92ce0bf3342de780cbac2bd6e76/@attachment/images/banner/README.png -------------------------------------------------------------------------------- /@attachment/images/banner/shimahara.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icekylin/Do1ng/fc89898a3b5ba92ce0bf3342de780cbac2bd6e76/@attachment/images/banner/shimahara.gif -------------------------------------------------------------------------------- /Develop/编程资源.md: -------------------------------------------------------------------------------- 1 | # 编程学习资源.md 2 | 3 | - [编程学习资源.md](#编程学习资源md) 4 | - [Python](#python) 5 | - [Golang](#golang) 6 | - [Javascript](#javascript) 7 | 8 | --- 9 | 10 | ## Python 11 | 12 | - **学习路线** 13 | - Python 学习路线: 14 | - **相关文档** 15 | - Python 中文在线手册: 16 | - **基础入门** 17 | - 廖雪峰 Python: 18 | - 菜鸟教程 Python: 19 | - W3school: 20 | - **进阶学习** 21 | - "流畅的Python": 22 | - "Python Cookbook 中文版,第 3 版": 23 | 24 | ## Golang 25 | 26 | - **学习路线** 27 | - Go 学习路线: 28 | - **相关文档** 29 | - 官方中文文档: 30 | - **基础入门** 31 | - Go 语言之旅: 32 | - **进阶学习** 33 | - Go 语言圣经: 34 | 35 | ## Javascript 36 | 37 | - **学习路线** 38 | - 前端学习路线: 39 | - **基础入门** 40 | - 廖雪峰 JavaScriot 教程: 41 | - 菜鸟教程 JavaScript: 42 | -------------------------------------------------------------------------------- /Integrated/FileFilter.md: -------------------------------------------------------------------------------- 1 | - [基础命令](#基础命令) 2 | - [正则表达式](#正则表达式) 3 | - [取根域名-1](#取根域名-1) 4 | - [文件批处理](#文件批处理) 5 | - [删除指定字符串](#删除指定字符串) 6 | - [替换指定字符串](#替换指定字符串) 7 | - [添加前缀](#添加前缀) 8 | - [添加后缀](#添加后缀) 9 | - [去重合并](#去重合并) 10 | 11 | ## 基础命令 12 | 13 | - 设置系统时间 `tzselect` 14 | 15 | ## 正则表达式 16 | 17 | ### 取根域名-1 18 | 19 | ``` 20 | cat result.txt 21 | http://www.adomain.com/index.html 22 | http://www.bdomain.com/example.html 23 | http://www.cdomain.com/urls/123 24 | 25 | awk -F '/' '{print $3}' result.txt > domain.txt 26 | cat domain.txt 27 | www.adomain.com 28 | www.bdomain.com 29 | www.cdomain.com 30 | 31 | awk -F 'www.' '{print $2}' domain.txt > rootdomain.txt 32 | cat rootdomain.txt 33 | adomain.com 34 | bdomain.com 35 | cdomain.com 36 | ``` 37 | 38 | ## 文件批处理 39 | 40 | - 相关链接: 41 | - [rename命令详解](https://wangchujiang.com/linux-command/c/rename.html) 42 | - [Mac 批量重命名(增加前缀后缀)](https://blog.csdn.net/m0_46728513/article/details/114396779) 43 | 44 | ### 删除指定字符串 45 | 46 | ```bash 47 | $ ls 48 | a_1.txt a_2.txt a_3.txt a_4.txt a_5.txt 49 | $ rename -d a_ *.txt 50 | $ ls 51 | 1.txt 2.txt 3.txt 4.txt 5.txt 52 | ``` 53 | 54 | ### 替换指定字符串 55 | 56 | ```bash 57 | ls 58 | 1.txt 2.txt 3.txt 4.txt 5.txt 59 | 60 | rename 's/.txt/.log/' * 61 | ls 62 | 1.log 2.log 3.log 4.log 5.log 63 | ``` 64 | 65 | ### 添加前缀 66 | 67 | ```bash 68 | ls 69 | 1.txt 2.txt 3.txt 4.txt 5.txt 70 | 71 | for i in *.txt;do mv "$i" "username_${i%.txt}.txt" ;done 72 | ls 73 | username_1.txt username_2.txt username_3.txt username_4.txt username_5.txt 74 | ``` 75 | 76 | ### 添加后缀 77 | 78 | ```bash 79 | ls 80 | 1.txt 2.txt 3.txt 4.txt 5.txt 81 | 82 | for i in *.txt;do mv "$i" "${i%.txt}_bak.txt" ;done 83 | ls 84 | 1_bak.txt 2_bak.txt 3_bak.txt 4_bak.txt 5_bak.txt 85 | ``` 86 | 87 | ### 去重合并 88 | 89 | ```bash 90 | ls 91 | 1.txt 2.txt 92 | cat 1.txt 93 | 3 94 | 2 95 | 1 96 | cat 2.txt 97 | 2 98 | 3 99 | 4 100 | cat *.txt|sort|uniq 101 | 1 102 | 2 103 | 3 104 | 4 105 | ``` 106 | -------------------------------------------------------------------------------- /Integrated/VSCode.md: -------------------------------------------------------------------------------- 1 | - [常用快捷键](#常用快捷键) 2 | - [个性化配置](#个性化配置) 3 | - [实用拓展](#实用拓展) 4 | - [Example](#example) 5 | - [连字支持](#连字支持) 6 | 7 | ## 常用快捷键 8 | 9 | - VSCode 集成快捷键 10 | - 键盘快捷键:Ctrl+K Ctrl+S 11 | - 切换窗口:Ctrl+数字键 12 | - 切换编辑器组:Ctrl+数字键 13 | - 顶部显示大纲:Command+Shift+O 14 | - 多行编辑: Option + Command + 方向键 15 | - 移动当前行: Option + 上下 16 | - 在 Finder 中打开文件 Command + K R 17 | - Markdown 18 | - 打开侧边预览:CMD+K V 19 | - 打开预览:Shift+CMD+V 20 | - Markdown Image 21 | - 粘贴图片:Shift+Opt+V -> Opt+V 22 | - breadcrumbs 23 | - 打开并聚焦在 面包屑的选择上:Shift+CMD+. 24 | - 打开面包屑(不展开子项目):Shift+CMD+; 25 | 26 | ## 个性化配置 27 | 28 | Debug pane嵌入:`debug.toolBarLocation: "docked"` 29 | 30 | ## 实用拓展 31 | 32 | Markdown: 33 | 34 | - [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) 35 | 36 | 图片操作 37 | 38 | - [Markdown Image](https://marketplace.visualstudio.com/items?itemName=hancel.markdown-image) 39 | 40 | 表格格式化 41 | 42 | - [Markdown Table](https://marketplace.visualstudio.com/items?itemName=TakumiI.markdowntable) 43 | 44 | Markdown格式Tree 45 | 46 | - [File Tree to Text Generator](https://marketplace.visualstudio.com/items?itemName=d-koppenhagen.file-tree-to-text-generator) 47 | 48 | 所见即所得 49 | 50 | ## Example 51 | 52 | ### 连字支持 53 | 54 | 1. 安装字体: 55 | 2. 设置字体为:Fira Code 56 | 3. 配置文件新增:"editor.fontLigatures": true 57 | -------------------------------------------------------------------------------- /Integrated/awk.md: -------------------------------------------------------------------------------- 1 | - [基本用法](#基本用法) 2 | - [运算符](#运算符) 3 | - [内建变量](#内建变量) 4 | - [使用正则,字符串匹配](#使用正则字符串匹配) 5 | - [忽略大小写](#忽略大小写) 6 | - [模式取反](#模式取反) 7 | - [awk脚本](#awk脚本) 8 | - [另外一些实例](#另外一些实例) 9 | 10 | > AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。 11 | > 12 | > 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。 13 | 14 | **相关链接** 15 | - [Linux awk 命令 | 菜鸟教程](https://www.runoob.com/linux/linux-comm-awk.html) 16 | 17 | --- 18 | 19 | **语法** 20 | 21 | ``` 22 | awk [选项参数] 'script' var=value file(s) 23 | 或 24 | awk [选项参数] -f scriptfile var=value file(s) 25 | ``` 26 | 27 | 选项参数说明: 28 | 29 | - -F fs or --field-separator fs 30 | 指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。 31 | - -v var=value or --asign var=value 32 | 赋值一个用户定义变量。 33 | - -f scripfile or --file scriptfile 34 | 从脚本文件中读取awk命令。 35 | - -mf nnn and -mr nnn 36 | 对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。 37 | - -W compact or --compat, -W traditional or --traditional 38 | 在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。 39 | - -W copyleft or --copyleft, -W copyright or --copyright 40 | 打印简短的版权信息。 41 | - -W help or --help, -W usage or --usage 42 | 打印全部awk选项和每个选项的简短说明。 43 | - -W lint or --lint 44 | 打印不能向传统unix平台移植的结构的警告。 45 | - -W lint-old or --lint-old 46 | 打印关于不能向传统unix平台移植的结构的警告。 47 | - -W posix 48 | 打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符**和**=不能代替^和^=;fflush无效。 49 | - -W re-interval or --re-inerval 50 | 允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。 51 | - -W source program-text or --source program-text 52 | 使用program-text作为源代码,可与-f命令混用。 53 | - -W version or --version 54 | 打印bug报告信息的版本。 55 | 56 | ## 基本用法 57 | 58 | log.txt 内容如下 59 | 60 | ``` 61 | 2 this is a test 62 | 3 Do you like awk 63 | This's a test 64 | 10 There are orange,apple,mongo 65 | ``` 66 | 67 | 用法一: 68 | 69 | ```bash 70 | # 默认按空格或TAB分割,输出文本中1、4项 71 | awk '{print $1,$4}' log.txt 72 | ---------------------------- 73 | 2 a 74 | 3 like 75 | This's 76 | 10 orange,apple,mongo 77 | ``` 78 | 79 | 用法二: 80 | 81 | ```bash 82 | # 使用 awk 内置变量使用 , 分割 83 | awk -F, '{print $1,$2}' log.txt 84 | ---------------------------- 85 | 2 this is a test 86 | 3 Do you like awk 87 | This 's a test 88 | 10 There are orange apple 89 | 90 | # 或者使用内建变量 91 | awk 'BEGIN{FS=","} {print $1,$2}' log.txt 92 | ---------------------------- 93 | 2 this is a test 94 | 3 Do you like awk 95 | This's a test 96 | 10 There are orange apple 97 | 98 | # 使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割 99 | awk -F '[ ,]' '{print $1,$2,$5}' log.txt 100 | ---------------------------- 101 | 2 this test 102 | 3 Do awk 103 | This's a 104 | 10 There apple 105 | ``` 106 | 107 | 用法三: 108 | 109 | ```bash 110 | # 定义变量 111 | awk -v a=1 '{print $1,$1+a}' log.txt 112 | ---------------------------- 113 | 2 3 114 | 3 4 115 | This's 1 116 | 10 11 117 | ``` 118 | 119 | 用法四: 120 | 121 | ```bash 122 | # 使用脚本规则 123 | awk -f cal.awk log.txt 124 | ``` 125 | 126 | ## 运算符 127 | 128 | ![图 1](/@attachment/images/Integrated/Linux/awk_1662533872617.png) 129 | 130 | 输出第一列大于 2 行的行 131 | 132 | ```bash 133 | awk '$1>2' log.txt 134 | ---------------------------- 135 | 3 Do you like awk 136 | This's a test 137 | 10 There are orange,apple,mongo 138 | ``` 139 | 140 | 输出第一列等于 2 的行 141 | 142 | ```bash 143 | awk '$1==2' log.txt 144 | ---------------------------- 145 | 2 this is a test 146 | # 联合输出语句输出第 1,3 位的内容 147 | awk '$1==2 {print $1,$3}' log.txt 148 | ---------------------------- 149 | 2 is 150 | ``` 151 | 152 | 输出第一列大于 2 且第三列等于 "are" 的行 153 | 154 | ```bash 155 | awk '$1>2 && $3=="are"' log.txt 156 | ---------------------------- 157 | 10 There are orange,apple,mongo 158 | # 联合输出语句第 1,2,3 位内容 159 | awk '$1>2 && $3=="are" {print $1,$2,$3}' log.txt 160 | ---------------------------- 161 | 10 There are 162 | ``` 163 | 164 | ## 内建变量 165 | 166 | | 变量 | 描述 | 167 | | ----------- | ------------------------------------------------- | 168 | | $n | 当前记录的第n个字段,字段间由FS分隔 | 169 | | $0 | 完整的输入记录 | 170 | | ARGC | 命令行参数的数目 | 171 | | ARGIND | 命令行中当前文件的位置(从0开始算) | 172 | | ARGV | 包含命令行参数的数组 | 173 | | CONVFMT | 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组 | 174 | | ERRNO | 最后一个系统错误的描述 | 175 | | FIELDWIDTHS | 字段宽度列表(用空格键分隔) | 176 | | FILENAME | 当前文件名 | 177 | | FNR | 各文件分别计数的行号 | 178 | | FS | 字段分隔符(默认是任何空格) | 179 | | IGNORECASE | 如果为真,则进行忽略大小写的匹配 | 180 | | NF | 一条记录的字段的数目 | 181 | | NR | 已经读出的记录数,就是行号,从1开始 | 182 | | OFMT | 数字的输出格式(默认值是%.6g) | 183 | | OFS | 输出字段分隔符,默认值与输入字段分隔符一致。 | 184 | | ORS | 输出记录分隔符(默认值是一个换行符) | 185 | | RLENGTH | 由match函数所匹配的字符串的长度 | 186 | | RS | 记录分隔符(默认是一个换行符) | 187 | | RSTART | 由match函数所匹配的字符串的第一个位置 | 188 | | SUBSEP | 数组下标分隔符(默认值是/034) | 189 | 190 | ```bash 191 | awk 'BEGIN{printf "%4s %4s %4s","FILENAME","FS\n","----------------\n"} {printf "%4s %4s\n",FILENAME,NF}' log.txt 192 | ---------------------------- 193 | FILENAME FS 194 | ---------------- 195 | log.txt 5 196 | log.txt 5 197 | log.txt 3 198 | log.txt 4 199 | # 输出顺序号 NR, 匹配文本行号 200 | awk '{print NR,FNR,$1,$2,$3}' log.txt 201 | ---------------------------- 202 | 1 1 2 this is 203 | 2 2 3 Are you 204 | 3 3 This's a test 205 | 4 4 10 There are 206 | # 指定输出分隔符 $ 207 | awk '{print $1,$2,$3}' OFS=" $ " log.txt 208 | ---------------------------- 209 | 2 $ this $ is 210 | 3 $ Are $ you 211 | This's $ a $ test 212 | 10 $ There $ are 213 | ``` 214 | 215 | ## 使用正则,字符串匹配 216 | 217 | ```bash 218 | # 输出第二列包含 "th",并打印第二列与第四列 219 | awk '$2 ~ /th/ {print $2,$4}' log.txt 220 | ---------------------------- 221 | this a 222 | ``` 223 | 224 | ~ 表示模式开始。// 中是模式。 225 | 226 | ```bash 227 | # 输出包含 "re" 的行 228 | awk '/re/' log.txt 229 | ---------------------------- 230 | 3 Are you like awk 231 | 10 There are orange,apple,mongo 232 | ``` 233 | 234 | ## 忽略大小写 235 | 236 | ```bash 237 | # MacOS 下测试无效 238 | awk 'BEGIN{IGNORECASE=1} /this/' log.txt 239 | ---------------------------- 240 | 2 this is a test 241 | This's a test 242 | ``` 243 | 244 | ## 模式取反 245 | 246 | ```bash 247 | # 输出第二列不包含 th 的行,并打 2,4 列 248 | awk '$2 !~ /th/ {print $2,$4}' log.txt 249 | ---------------------------- 250 | Are like 251 | a 252 | There orange,apple,mongo 253 | # 输出不包含 th 的行,并打 2,4 列 254 | awk '!/th/ {print $2,$4}' log.txt 255 | Are like 256 | a 257 | There orange,apple,mongo 258 | ``` 259 | 260 | ## awk脚本 261 | 262 | - BEGIN{执行前的语句} 263 | - {处理每一行时要执行的语句} 264 | - END {处理完所有的行后要执行的语句} 265 | 266 | score.txt 文件如下 267 | 268 | ``` 269 | Marry 2143 78 84 77 270 | Jack 2321 66 78 45 271 | Tom 2122 48 77 71 272 | Mike 2537 87 97 95 273 | Bob 2415 40 57 62 274 | ``` 275 | 276 | cal.awk 脚本如下: 277 | 278 | ```bash 279 | #!/bin/awk -f 280 | #运行前 281 | BEGIN { 282 | math = 0 283 | english = 0 284 | computer = 0 285 | 286 | printf "NAME NO. MATH ENGLISH COMPUTER TOTAL\n" 287 | printf "---------------------------------------------\n" 288 | } 289 | #运行中 290 | { 291 | math+=$3 292 | english+=$4 293 | computer+=$5 294 | printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5 295 | } 296 | #运行后 297 | END { 298 | printf "---------------------------------------------\n" 299 | printf " TOTAL:%10d %8d %8d \n", math, english, computer 300 | printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR 301 | } 302 | ``` 303 | 304 | 执行效果 305 | 306 | ```bash 307 | awk -f cal.awk score.txt 308 | NAME NO. MATH ENGLISH COMPUTER TOTAL 309 | --------------------------------------------- 310 | Marry 2143 78 84 77 239 311 | Jack 2321 66 78 45 189 312 | Tom 2122 48 77 71 196 313 | Mike 2537 87 97 95 279 314 | Bob 2415 40 57 62 159 315 | --------------------------------------------- 316 | TOTAL: 319 393 350 317 | AVERAGE: 63.80 78.60 70.00 318 | ``` 319 | 320 | ## 另外一些实例 321 | 322 | AWK 的 Hello World 323 | 324 | ```bash 325 | BEGIN { print "Hello, world!" } 326 | ``` 327 | 328 | 计算文件大小 329 | 330 | ```bash 331 | ls -l *.txt | awk '{sum+=$5} END {print sum}' 332 | ``` 333 | 334 | 从文件中找出长度大于 80 的行: 335 | 336 | ```bash 337 | awk 'length>80' log.txt 338 | ``` 339 | 340 | 打印九九乘法表 341 | 342 | ```bash 343 | seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}' 344 | ``` -------------------------------------------------------------------------------- /Integrated/git.md: -------------------------------------------------------------------------------- 1 | - [Basic](#basic) 2 | - [Repo](#repo) 3 | - [Pull](#pull) 4 | - [Push](#push) 5 | 6 | --- 7 | 8 | ## Basic 9 | 10 | ```bash 11 | # 生成公钥与github连接 12 | ssh-keygen 13 | cat ~/.ssh/id_rsa.pub # Github 新建 SSH keys 填入这里的内容 14 | git config --global user.name "your_username" 15 | git config --global user.email "your_email" 16 | git config --list 17 | 18 | # 建立仓库提示命令 19 | echo "# Cyber-Security-Notes" >> README.md 20 | git init 21 | git add README.md 22 | git commit -m "first commit" 23 | git branch -M main 24 | git remote add origin git@github.com:kyl1n0/Cyber-Security-Notes.git 25 | git push -u origin main 26 | ``` 27 | 28 | ## Repo 29 | 30 | ```bash 31 | # 重新绑定仓库(主要用于修改仓库名称后) 32 | git remote rm origin 33 | git remote add origin git@github.com:moekylin/Do1ng.git 34 | ``` 35 | 36 | ## Pull 37 | 38 | ```bash 39 | # 清除本地修改,拉取仓库最新内容 40 | # 当本地仓库修改了内容执行 `git pull` 时,会出现如下内容,可以通过两种方式拉取远程仓库内容 41 | error: Your local changes to the following files would be overwritten by merge: 42 | README.md 43 | Please commit your changes or stash them before you merge. 44 | 45 | ## 方式 1:stash 会把所有未提交的修改(包括暂存的和非暂存的)都保存起来,用于后续恢复当前工作目录。比如下面的中间状态,通过git stash命令推送一个新的储藏,当前的工作目录就干净了。 46 | git stash 47 | git pull 48 | git stash pop 49 | 50 | ## 方式 2: --hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交: 51 | git reset --hard 52 | git pull 53 | ``` 54 | 55 | ## Push 56 | 57 | ```bash 58 | # 撤销 (revert) 上一次 commit push 59 | git log # 找到上一次 commit 的编号 60 | git revert [commit编号] # 撤销上一次更改 61 | git push 62 | 63 | # 回滚 commit 到某一节点(同时删除仓库commit) 64 | git log # 找到想要回滚的 commit 编号 65 | git reset --hard commit_id # HEAD 指向此次提交记录 66 | git push origin HEAD --force # 强制 push 67 | 68 | # 清除缓存重新提交数据 (用于更新.gitnore) 69 | git rm --cached -r . 70 | git add . 71 | git commit -m "$(date)" # 当前时间的 commit 72 | git push 73 | ``` 74 | -------------------------------------------------------------------------------- /Integrated/vim.md: -------------------------------------------------------------------------------- 1 | 2 | > 你想以最快的速度学习人类史上最好的文本编辑器VIM吗?你先得懂得如何在VIM幸存下来,然后一点一点地学习各种戏法。 3 | 4 | **相关链接** 5 | - [简明 VIM 练级攻略](https://coolshell.cn/articles/5426.html) 6 | -------------------------------------------------------------------------------- /Network/HTTP.md: -------------------------------------------------------------------------------- 1 | - [图解 HTTP 笔记](#图解-http-笔记) 2 | - [第一章 网络基础](#第一章-网络基础) 3 | - [1.1 网络基础 TCP/IP](#11-网络基础-tcpip) 4 | - [1.2 域名解析DNS服务](#12-域名解析dns服务) 5 | - [1.3 各个协议与 HTTP 协议关系](#13-各个协议与-http-协议关系) 6 | - [第二章 简单的 HTTP 协议](#第二章-简单的-http-协议) 7 | - [2.1 通过请求+响应的交换达到通信](#21-通过请求响应的交换达到通信) 8 | - [2.2 HTTP 是不保存状态的协议](#22-http-是不保存状态的协议) 9 | - [2.3 HTTP 请求方法](#23-http-请求方法) 10 | - [2.4 Cookie 的状态管理](#24-cookie-的状态管理) 11 | - [第三章 HTTP 报文信息](#第三章-http-报文信息) 12 | - [3.1 HTTP 报文](#31-http-报文) 13 | - [3.2 请求报文和响应报文](#32-请求报文和响应报文) 14 | - [第四章 HTTP 状态码](#第四章-http-状态码) 15 | - [4.1 状态码告知服务器返回的请求结果](#41-状态码告知服务器返回的请求结果) 16 | - [4.2 2XX 成功](#42-2xx-成功) 17 | - [4.3 3XX 重定向](#43-3xx-重定向) 18 | - [4.4 4XX 客户端错误](#44-4xx-客户端错误) 19 | - [4.5 5XX 服务器错误](#45-5xx-服务器错误) 20 | - [第五章 HTTP 首部](#第五章-http-首部) 21 | - [5.1 HTTP 报文首部](#51-http-报文首部) 22 | - [5.2 HTTP 首部字段](#52-http-首部字段) 23 | - [5.3 HTTP/1.1 通用首部字段](#53-http11-通用首部字段) 24 | - [5.4 请求首部字段](#54-请求首部字段) 25 | - [5.5 响应首部字段](#55-响应首部字段) 26 | - [5.6 实体首部字段](#56-实体首部字段) 27 | - [5.7 为 Cookie 服务的首部字段](#57-为-cookie-服务的首部字段) 28 | - [第六章 HTTPS 确保Web安全](#第六章-https-确保web安全) 29 | - [6.1 HTTP 的缺点](#61-http-的缺点) 30 | - [6.2 HTTP + 加密 + 认证 + 完整性保护 = HTTPS](#62-http--加密--认证--完整性保护--https) 31 | - [第七章 确认访问用户身份的认证](#第七章-确认访问用户身份的认证) 32 | - [7.1 BASIC 认证](#71-basic-认证) 33 | - [7.1 DIGEST 认证](#71-digest-认证) 34 | - [7.3 SSL 客户端认证](#73-ssl-客户端认证) 35 | - [7.4 基于表单认证](#74-基于表单认证) 36 | - [第八章 基于 HTTP 的功能追加协议](#第八章-基于-http-的功能追加协议) 37 | - [8.1 消除 HTTPS 瓶颈的 SPDY](#81-消除-https-瓶颈的-spdy) 38 | - [8.2 使用浏览器进行全双工通信的 WebSocket](#82-使用浏览器进行全双工通信的-websocket) 39 | - [8.3 期盼已久的 HTTP/2.0](#83-期盼已久的-http20) 40 | - [8.4 Web 服务器管理文件的 WebDAV](#84-web-服务器管理文件的-webdav) 41 | - [第九章 构建 Web 内容的技术](#第九章-构建-web-内容的技术) 42 | - [9.1 HTML](#91-html) 43 | - [9.2 动态 HTML](#92-动态-html) 44 | - [9.3 Web 应用](#93-web-应用) 45 | - [9.4 数据发布的格式及语言](#94-数据发布的格式及语言) 46 | - [第十章 Web 的攻击技术](#第十章-web-的攻击技术) 47 | - [10.1 针对 Web 的攻击技术](#101-针对-web-的攻击技术) 48 | - [10.2 因输出值转义不完全引发的安全漏洞](#102-因输出值转义不完全引发的安全漏洞) 49 | - [10.3 因设置或设计上的缺陷引发的安全漏洞 (大概率已过时)](#103-因设置或设计上的缺陷引发的安全漏洞-大概率已过时) 50 | - [10.4 因会话管理疏忽引发的安全漏洞](#104-因会话管理疏忽引发的安全漏洞) 51 | - [10.5 其他安全漏洞](#105-其他安全漏洞) 52 | 53 | - **相关资源** 54 | - 书籍资源1: [Information_Security_Books/118http权威指南](https://github.com/olist213/Information_Security_Books/tree/main/118http%E6%9D%83%E5%A8%81%E6%8C%87%E5%8D%97) 55 | - 书籍资源2: [Information_Security_Books/054图解HTTP彩色版](https://github.com/olist213/Information_Security_Books/tree/main/054%E5%9B%BE%E8%A7%A3HTTP%E5%BD%A9%E8%89%B2%E7%89%88) 56 | - 精简版1: [http: 自己提炼的关于《HTTP权威指南》每章的知识点总结](https://github.com/woai30231/http) 57 | - 精简版2: [《图解HTTP与HTTPS》的干货1.2w字【绝对保值】 - 掘金](https://juejin.cn/post/6900511779869327373#heading-16) 58 | - [HTTP 开发者指南 HTTP | MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTTP) 59 | - **拓展阅读** 60 | - [5分钟快速梳理你的HTTP体系-阿里云开发者社区](https://developer.aliyun.com/article/790991) 61 | 62 | # 图解 HTTP 笔记 63 | 64 | ## 第一章 网络基础 65 | 66 | > Web 使用的协议为 HTTP (HyperText Transfer Protocol, 超文本传输协议) 的协议作为规范, 完成从客户端到服务端等一系列运作流程,而协议是指规则的约定。也可以说Web是建立在HTTP协议上通信的。 67 | 68 | ### 1.1 网络基础 TCP/IP 69 | 70 | **1.1.1 TCP/IP协议族** 71 | 72 | TCP/IP协议族按照层次分别分为以下4层:应用层、传输层、网络层和数据链路层。 73 | 74 | **应用层**: TCP/IP 协议族内预存了各类通用的**应用服务**处于应用层 75 | 76 | **传输层**: 有两个性质不同的协议 TCP 和 UDP, 传输层对上层应用层提供处于网络连接中的两台计算机之间的数据传输 77 | 78 | **网络层**: 网络层用于处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径到达对方计算机,并把数据包传给对方。与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。 79 | 80 | **链路层**: 用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC【网络适配器俗称网卡】及光纤等物理可见部分。硬件上的范畴均在链路层的作用范围之内。 81 | 82 | **1.1.2 TCP/IP通信传输流** 83 | 84 | 利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端从下层往上走。 85 | 86 | 在传输层【TCP协议】把从应用层处接收到的数据【HTTP请求报文】进行分割,并在各个报文上打上标记序号及端口号后转发给网络层。 87 | 88 | ### 1.2 域名解析DNS服务 89 | 90 | DNS【Domain Nmae System】服务是和HTTP协议一样位于应用层协议。它提供域名到IP地址之间的解析服务。 91 | 92 | ### 1.3 各个协议与 HTTP 协议关系 93 | 94 | 通过下面一张图,看各个协议在HTTP协议通信中发挥的哪些作用?假设想浏览hackr.jp/xss/Web页面 95 | 96 | ![[Pasted image 20220920084454.png]] 97 | 98 | ## 第二章 简单的 HTTP 协议 99 | 100 | > 本部分在主要讲述HTTP协议结构,主要使用的是HTTP/1.1 101 | 102 | ### 2.1 通过请求+响应的交换达到通信 103 | 104 | 看一个具体的例子 105 | ```http 106 | GET /index.htm HTTP/1.1 107 | Host: hacker.jp 108 | ``` 109 | 110 | 起始的 Get 表示请求访问服务器的类型, 称为 **方法**. 随后的字符串 /index.html 指明了请求访问的 **资源对象**. 最后的 HTTP/1.1 代表 **HTTP的版本号**, 用来提示客户端使用的 HTTP 协议功能. 请求内容的意思是: 请求访问某台 HTTP 服务器上的 /index.htm 页面的资源 111 | 112 | **请求报文** 是由请求方法, 请求URI, 协议版本, 可选的请求首部字段和内容实体构成的 113 | 114 | ![[Pasted image 20220920084700.png]] 115 | 116 | 响应报文基本由协议版本, 状态码和原因短语, 以及可选的响应首部字段和实体主体构成 117 | 118 | ![[Pasted image 20220920085005.png]] 119 | 120 | ### 2.2 HTTP 是不保存状态的协议 121 | 122 | HTTP 是一种不保存状态的无状态协议, HTTP 协议自身不对请求和响应之间的通信状态进行保存. 123 | 124 | - 客户端: 你之前给我发送了啥来着? 125 | - 服务端: 我想想, 之前给你发送了啥来着? 126 | 127 | ### 2.3 HTTP 请求方法 128 | 129 | **2.3.1 GET** 130 | 131 | GET 方法用来请求访问已被 URI 识别的资源。指定的资源经过服务器端解析后返回响应内容。也就是说如果请求的资源是文本,那就保存原样返回,如果是CGI【通用网关接口】那样的程序,则返回经过执行后的输出结果。 132 | 133 | ```http 134 | # 请求 135 | GET/index.html HTTP/1.1 136 | Host:www.hackr.jp 137 | If-Modified-Since:Thu,12 Jul 2012 07:30:00 GMT 138 | 139 | # 响应 140 | 仅返回2012年7月12日7点30分以后更新过的ndex.html页面资源.如果未 有内容更新,则以状态码304 Not Modified作 141 | ``` 142 | 143 | **2.3.2 POST** 144 | 145 | POST 方法用来传输实体的主体 146 | 147 | 虽然 GET 也可以传输实体的主体, 但是一般不用, POST 的主要目的并不是获取相应的主题内容 148 | 149 | ```http 150 | # 请求 151 | POST /submit.cgi HTTP/1.1 152 | Host:www.hackr.jp 153 | Content-Length:1560 (1560字节的数据) 154 | 155 | # 响应 156 | 返回submit.cgi接收数据的处理结果 157 | ``` 158 | 159 | **2.3.3 PUT** 160 | 161 | PUT 方法的主要作用是上传文件, 要求在请求报文的主题中包含文件的内容, 然后保存到 URI 指定的位置 162 | 163 | 但是 HTTP/1.1 自身不带验证机制, 任何人都可以上传文件, 所以应该禁用 PUT 方法 164 | 165 | ```http 166 | # 请求 167 | PUT /example.html HTTP/1.1 168 | Host:www.hackr.jp 169 | Content-Type:text/html 170 | Content-Length:1560 (1560字节的数据) 171 | 172 | # 响应 173 | 响应返回状态码204 No Content (比如:该html已存在于服务器) 174 | ``` 175 | 176 | **2.3.4 HEAD** 177 | 178 | 获取报文首部 179 | 180 | HEAD 方法和 GET 方法一样, 知识不返回报文主体部分, 用于确认 URI 的有效性及资源更新的日期时间等 181 | 182 | - 客户端: 把那个的相关信息告诉我 183 | 184 | ```http 185 | # 请求 186 | HEAD /index.html HTTP/1.1 187 | Host:www.hackr.jp 188 | 189 | # 响应 190 | 返回index.html有关的响应首部 191 | ``` 192 | 193 | **2.3.5 DELETE** 194 | 195 | DELETE 方法是用来删除文件的, 与之相反的是 PUT 方法, DELETE 方法按请求 URI 删除指定的资源, 同样的并没有验证机制, 也应该禁用 196 | 197 | ```http 198 | # 请求 199 | DELETE /example.html HTTP/1.1 200 | Host:www.hackr.jp 201 | 202 | # 响应 203 | 响应返回状态码204 No Content(比如:该html已从该服务器上乳除2 204 | ``` 205 | 206 | **2.3.6 OPTIONS** 207 | 208 | OPTIONS 方法用来查询针对请求 URI 指定的资源支持方法 209 | 210 | ```http 211 | # 请求 212 | OPTIONS * HTTP/1.1 213 | Host: www.hackr.jp 214 | 215 | # 响应 216 | HTTP/1.1 200 OK 217 | Allow: GET.POST,HEAD,OPTIONS (返回服务器支持的方法) 218 | ``` 219 | 220 | **2.3.7 TRACE** 221 | 222 | TRACE 方法是让 Web 服务器将之前的请求通信环回给客户端的方法 223 | 224 | 客户端通过 TRACE 方法可以查询发送出去的代理是怎样被加工修改的, 这是因为请求想要连接到源目标服务器可能会通过代理中专, TRACE 方法就是用来确认链接过程中发生的一系列操作 225 | 226 | ![[Pasted image 20220920090110.png]] 227 | 228 | ```http 229 | # 请求 230 | TRACE / HTTP/1.1 231 | Host: hackr.jp 232 | Max-Forwards: 2 233 | 234 | # 响应 235 | HTTP/1.1 200 OK 236 | Content-Type: message/http 237 | Content-Length: 1024 238 | 239 | TRACE / HTTP/1.1 240 | Host: hackr.jp 241 | Max-Forwards: 2(返回响应包含请求内容) 242 | ``` 243 | **2.3.8 CONNECT** 244 | 245 | CONNECT要求用隧道协议链接代理 246 | 247 | CONNECT 方法要求在与代理服务器通信时建立隧道, 实现用隧道协议进行 TCP 通信. 主要使用 SSL 和 TLS 协议把通信内容加密后经网络隧道传输. 248 | 249 | CONNECT 方法格式: `CONNECT 代理服务器名:端口号 HTTP 版本` 250 | 251 | ```http 252 | # 请求 253 | CONNECT proxy.hackr.jp:8080 HTTP/1.1 254 | Host: proxy.hackr.jp 255 | 256 | # 响应 257 | HTTP/1.1 200 OK (之后进入网络隧道) 258 | ``` 259 | 260 | ### 2.4 Cookie 的状态管理 261 | 262 | 之前提到过 HTTP 是无状态协议, 它不对之前发生过的请求和响应状态进行管理, 无法根据之前的状态去处理这次的请求 263 | 264 | 为了解决这个问题, 引入了 Cookie 技术, Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态 265 | 266 | Cookie 会根据服务端发送的响应报文中的一个叫 Set-Cookie 的首部字段, 通知客户端保存 Cookie, 当下次客户端再往服务器发送请求时, 客户端会自动在请求报文中加入 Cookie 值之后发出 267 | 268 | - 第一次没有 Cookie 信息状态下请求 269 | 1. 客户端发送请求 270 | 2. 服务端在响应中添加 Cookie 后返回 271 | - 第二次存有 Cookie 状态的请求 272 | 1. 客户端在请求中添加 Cookie 后发送 273 | 2. 服务端: 阿是刚才那个家伙; 发送响应 274 | 275 | ```http 276 | # 请求报文 (没有Cookie信息) 277 | GET /reader/HTTP/1.1 278 | Host:hackr.jp 279 | *首部字段内没有Cookie的相关信息 280 | 281 | # 响应报文 (服务端生成Cookie信息) 282 | HTTP/1.12000K 283 | Date: Thu,12 Jul 2012 07:12:20 GMT 284 | Server: Apache 285 | 286 | Content-Type:text/plain;charset=UTF-8 287 | 288 | # 请求保存 (有Cookie信息) 289 | GET /image/ HTTP/1.1 290 | Host: hackr.jp 291 | Cookie: sid=1342077140226724 292 | ``` 293 | 294 | ## 第三章 HTTP 报文信息 295 | 296 | ### 3.1 HTTP 报文 297 | 298 | 用于 HTTP 协议交互的信息被称为 HTTP 报文. 客户端的 HTTP 报文叫做请求报文, 服务端的叫做响应报文 299 | 300 | HTTP 报文大致可以分为**报文首部**和**报文主体**两块, 两者由最初出现的空行 (CR+LF) 来划分. 通常, 并不一定要有报文主体 301 | 302 | - 报文首部: 服务端或客户端需处理的请求或响应内容及属性 303 | - CR+LF: 304 | - CR (Carriage Return, 回车符: 16 进制 0x0d ) 305 | - LF (Line Frrd, 换行符: 16 进制 0x0a) 306 | - 报文主体: 应被发送的数据 307 | 308 | ### 3.2 请求报文和响应报文 309 | 310 | **3.2.1 请求报文** 311 | 312 | ![[Pasted image 20220920092107.png]] 313 | 314 | - 请求行: 包含请求的方法, 请求 URI 和 HTTP 版本 315 | - [x] 首部字段: 包含请求和响应的各种条件和属性的各类首部 (一般有四种首部, 分别是: 通用首部, 请求首部, 响应首部和实体首部) 316 | 317 | **3.2.2 响应报文** 318 | 319 | ![[Pasted image 20220920092113.png]] 320 | 321 | - 状态行: 包含响应结果和状态码, 原因短语和 HTTP 版本 322 | 323 | ## 第四章 HTTP 状态码 324 | 325 | HTTP 状态码负责表示客户端 HTTP 请求的返回结果, 标记服务端的处理是否正常, 通信出现的错误等工作 326 | 327 | ### 4.1 状态码告知服务器返回的请求结果 328 | 329 | 状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。 330 | 331 | **状态码的类别** 332 | 333 | - 1XX : Informational(信息性状态码) : 接收的请求正在处理 334 | - 2XX : Success(成功状态码) : 请求正常处理完毕 335 | - 3XX : Redirection(重定向状态码) : 需要进行附加操作以完成请求 336 | - 4XX : Client Error(客户端错误状态码) : 服务器无法处理请求 337 | - 5XX : Server Error(服务器错误状态码) : 服务器处理请求出错 338 | 339 | ### 4.2 2XX 成功 340 | 341 | 2XX 的响应结果表明请求被正常处理了 342 | 343 | **4.2.1 200 OK** 344 | 345 | 在响应报文内,随状态码一起返回的信息会因方法的不同而发生改变。比如,使用 GET 方法时,对应请求资源的实体会作为响应返回;而使用 HEAD 方法时,对应请求资源的实体首部不随报文主体作为响应返回(即在响应中只返回首部,不会返回实体的主体部分)。 346 | 347 | **4.2.2 204 Not Content** 348 | 349 | 该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。比如,当从浏览器发出请求处理后,返回 204 响应,那么浏览器显示的页面不发生更新。 350 | 351 | **4.2.3 206 Partial Content** 352 | 353 | 该状态码表示客户端进行了范围请求 (只请求一部分),而服务器成功执行了这部分的GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。 354 | 355 | ### 4.3 3XX 重定向 356 | 357 | 3XX 响应结果表明浏览器需要执行某些特殊的处理以正确处理请求。 358 | 359 | **4.3.1  301 Moved Permanently 永久性重定向** 360 | 361 | 请求的资源已被分配了新的 URI,以后应使用资源现在所指的 URI。也就是说,如果已经把资源对应的 URI 保存为书签了,这时应该按 Location 首部字段提示的 URI 重新保存。 362 | 363 | **4.3.2 302 Found 临时重定向** 364 | 365 | 请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。和 301 Moved Permanently 状态码相似,但 302 状态码代表的资源不是被永久移动,只是临时性质的。换句话说,已移动的资源对应的URI 将来还有可能发生改变。比如,用户把 URI 保存成书签,但不会像 301 状态码出现时那样去更新书签,而是仍旧保留返回 302 状态码的页面对应的 URI。  366 | 367 | **4.3.3  303 See Other** 368 | 369 | 请求对应的资源存在着另一个 URI,应使用 GET方法定向获取请求的资源。 370 | 371 | 303 状态码和 302 Found 状态码有着相同的功能,但 303 状态码明确表示客户端应当采用 GET 方法获取资源,这点与 302 状态码有区别。  372 | 373 | **4.3.4 304 Not Modified** 374 | 375 | 客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况。304 状态码返回时,不包含任何响应的主体部分。304 虽然被划分在 3XX 类别中,但是和重定向没有关系。 376 | 377 | ### 4.4 4XX 客户端错误 378 | 379 | 4XX 的响应结果表明客户端是发生错误的原因所在。 380 | 381 | **4.4.1 400 Bad Request** 382 | 383 | 请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。另外,浏览器会像 200 OK 一样对待该状态码。 384 | 385 | **4.4.2 401 Unauthorized** 386 | 387 | 该发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示用 户认证失败。 388 | 389 | **4.4.3 403 Forbidden** 390 | 391 | 对请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。 392 | 393 | **4.4.4 404 Not Found** 394 | 395 | 该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。 396 | 397 | ### 4.5 5XX 服务器错误 398 | 399 | 5XX 的响应结果表明服务器本身发生错误。 400 | 401 | **4.5.1 500 Internal Server Error** 402 | 403 | 该状态码表明服务器端在执行请求时发生了错误。也有可能是 Web应用存在的 bug 或某些临时的故障。 404 | 405 | **4.5.2 503 Service Unavailable** 406 | 407 | 该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入RetryAfter 首部字段再返回给客户端。  408 | 409 | ## 第五章 HTTP 首部 410 | 411 | ### 5.1 HTTP 报文首部 412 | 413 | HTTP 协议的请求和响应报文中必定包含 HTTP 首部,首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。 414 | 415 | **HTTP 请求报文** 416 | 417 | 在请求中,HTTP 报文由方法、URI、HTTP 版本、HTTP 首部字段等部分构成。 418 | 419 | - 报文首部: 420 | - 请求行 (方法, URI, HTTP 版本) 421 | - 请求首部字段, 通用首部字段, 实体首部字段 (HTTP 首部字段) 422 | - 其他 423 | - 空行 ( CR+LF) 424 | - 报文主体 425 | 426 | 下面是访问 hacker.jp 时, 请求报文的首部信息 427 | 428 | ```http 429 | GET / HTTP/1.1 430 | Host: hackr.jp 431 | User-Agent: Mozilla/5.0 (Windows NT 6.1;WOW64;rv:13.0)Ged 432 | Accept: text/html,application/xhtml+xml,application/xml;q=0 433 | Accept-Language: ja,en-us;q=0.7,en;q=0.3 434 | Accept-Encoding: gzip,deflate 435 | DNT: 1 436 | Connection: keep-alive 437 | If-Modified-Since: Fri,31 Aug 2007 02:02:20 GMT 438 | If-None-Match: "45bae1-16a-46d776ac" 439 | Cache-Control: max-age=0 440 | ``` 441 | 442 | **HTTP 响应报文** 443 | 444 | 在响应中,HTTP 报文由 HTTP 版本、状态码(数字和原因短语)、HTTP 首部字段 3 部分构成。  445 | 446 | - 报文首部: 447 | - 状态行 (HTTP 版本, 状态码) 448 | - 响应首部字段, 通用首部字段, 实体首部字段 (HTTP 首部字段) 449 | - 其他 450 | - 空行 ( CR+LF) 451 | - 报文主体 452 | 453 | 下面是访问 hack.jp/ 时, 返回的响应报文的首部信息 454 | 455 | ```http 456 | HTTP/1.1 304 Not Modified 457 | Date: Thu,07 Jun 2012 07:21:36 GMT 458 | Server: Apache 459 | Connection: close 460 | Etag: "45bae1-16a-46d776ac" 461 | ``` 462 | 在报文众多的字段当中,HTTP 首部字段包含的信息最为丰富。首部字段同时存在于请求和响应报文内,并涵盖 HTTP 报文相关的内容信息。 463 | 464 | ### 5.2 HTTP 首部字段 465 | 466 | **5.2.1 HTTP首部字段传递重要信息** 467 | 468 | HTTP 首部字段是构成 HTTP 报文的要素之一。在客户端与服务器之间以 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。 469 | 470 | **5.2.2 HTTP 首部字段结构** 471 | 472 | HTTP 首部字段是由**首部字段名**和**字段值构成的**, 中间用冒号 ":" 分隔. 473 | 474 | ```text 475 | 首部字段名: 字段值 476 | ``` 477 | 例如在 HTTP 首部中以 Content-Type 这个字段来表示报文主体的对象类型 478 | 479 | ```http 480 | Content-Type: text/html 481 | ``` 482 | 483 | 就上述示例来看, 首部字段名为 `Content-Type` 字符串 `text/html` 是字段值 484 | 485 | **5.2.3 4种HTTP 首部字段类型** 486 | 487 | HTTP 首部字段根据实际用途被分为以下 4 种类型。 488 | 489 | - 通用首部字段(General Header Fields) : 请求报文和响应报文两方都会使用的首部。 490 | - 请求首部字段(Request Header Fields):从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信信息、响应内容相关优先级等信息。 491 | - 响应首部字段(Response Header Fields):从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。  492 | - 实体首部字段(Entity Header Fields):针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。  493 | 494 | **5.2.4 HTTP/1.1 首部字段** 495 | 496 | **1. 通用首部字段** 497 | 498 | - Cache-Control : 控制缓存的行为 499 | - Connection : 逐跳首部、连接的管理 500 | - Date : 创建报文的日期时间 501 | - Pragma : 报文指令 502 | - Trailer : 报文末端的首部一览 503 | - Transfer-Encoding : 指定报文主体的传输编码方式 504 | - Upgrade : 升级为其他协议 505 | - Via : 代理服务器的相关信息 506 | - Warning : 错误通知 507 | 508 | **2. 请求首部字段** 509 | 510 | - Accept : 用户代理可处理的媒体类型 511 | - Accept-Charset : 优先的字符集 512 | - Accept-Encoding : 优先的内容编码 513 | - Accept-Language : 优先的语言(自然语言) 514 | - Authorization : Web认证信息 515 | - Expect : 期待服务器的特定行为 516 | - From : 用户的电子邮箱地址 517 | - Host : 请求资源所在服务器 518 | - If-Match : 比较实体标记(ETag) 519 | - If-Modified-Since : 比较资源的更新时间 520 | - If-None-Match : 比较实体标记(与If-Match相反) 521 | - If-Range : 资源未更新时发送实体Byte的范围请求 522 | - If-Unmodified-Since : 比较资源的更新时间(与If-Modified-Since相反) 523 | - Max-Forwards : 最大传输逐跳数 524 | - Proxy-Authorization : 代理服务器要求客户端的认证信息 525 | - Range : 实体的字节范围请求 526 | - Referer : 对请求中URI的原始获取方 527 | - TE : 传输编码的优先级 528 | - User-Agent : HTTP客户端程序的信息 529 | 530 | **3. 响应首部字段** 531 | 532 | - Accept-Ranges : 是否接受字节范围请求 533 | - Age : 推算资源创建经过时间 534 | - ETag : 资源的匹配信息 535 | - Location : 令客户端重定向至指定URI 536 | - Proxy-Authenticate : 代理服务器对客户端的认证信息 537 | - Retry-After : 对再次发起请求的时机要求 538 | - Server : HTTP服务器的安装信息 539 | - Vary : 代理服务器缓存的管理信息 540 | - WWW-Authenticate : 服务器对客户端的认证信息 541 | 542 | **4. 实体首部字段** 543 | 544 | - Allow : 资源可支持的HTTP方法 545 | - Content-Encoding : 实体主体适用的编码方式 546 | - Content-Language : 实体主体的自然语言 547 | - Content-Length : 实体主体的大小(单位:字节) 548 | - Content-Location : 替代对应资源的URI 549 | - Content-MD5 : 实体主体的报文摘要 550 | - Content-Range : 实体主体的位置范围 551 | - Content-Type : 实体主体的媒体类型 552 | - Expires : 实体主体过期的日期时间 553 | - Last-Modified : 资源的最后修改日期时间 554 | 555 | ### 5.3 HTTP/1.1 通用首部字段 556 | 557 | 通用首部字段是指, 请求报文和响应报文双方都会使用的首部 558 | 559 | **5.3.1 Cache-Control** 560 | 561 | ![[Pasted image 20220920101039.png]] 562 | 563 | **Cache-Control** 通用消息头字段,被用于在 http 请求和响应中,通过指定指令来实现缓存机制。缓存指令是单向的,这意味着在请求中设置的指令,不一定被包含在响应中。 564 | 565 | 通用指定首部字段 Cache-Control 的指令, 就能操作缓存的工作机制 566 | 567 | 指令的参数是可选的,多个指令之间通过“,”分隔。首部字段 Cache-Control 的指令可用于请求及响应时。   568 | 569 | ```http 570 | Cache-Control: private, max-age=0, no-cache 571 | ``` 572 | 573 | **public 指令** 574 | 575 | ```http 576 | Cache-Control: Public 577 | ``` 578 | 579 | 当指定使用 public 指令时, 则明确表明其他用户也可以利用缓存 580 | 581 | **private 指令** 582 | 583 | ```http 584 | Cache-Control: private 585 | ``` 586 | 587 | 当指定 private 指令后, 响应只以特定的用户作为对象, 这与 public 指定的行为相反, 缓存服务器会对该特定用户提供资源缓存的服务, 对于其他用户发送的请求, 代理服务器则不会返回缓存 588 | 589 | **no-cache 指令** 590 | 591 | ```http 592 | Cache-Control: no-cache 593 | ``` 594 | 595 | 使用 no-chache 指令的目的是防止从缓存中返回过期的资源, 客户端发送的请求中如果包含 no-cache 指令, 则表示客户单将不会接受缓存过的响应, 于是 "中间" 的缓存服务器必须把客户端请求转发给资源服务器 596 | 597 | **no-store 指令** 598 | 599 | ```http 600 | Cache-Control: no-store 601 | ``` 602 | 603 | 当使用 no-store 指令 1 时,暗示请求(和对应的响应)或响应中包含机密信息。 604 | 605 | **指定缓存期限和认证的指令** 606 | 607 | **s-maxage 指令** 608 | 609 | ```http 610 | Cache-Control: s-maxage=604800(单位 :秒) 611 | ``` 612 | 613 | s-maxage 指令的功能和 max-age 指令的相同,它们的不同点是 s-maxage 指令只适用于供多位用户使用的公共缓存服务器 2。也就是说,对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。 614 | 615 | **max-age 指令** 616 | 617 | ```http 618 | Cache-Control: max-age=604800(单位:秒) 619 | ``` 620 | 621 | 当客户端发送的请求中包含 max-age 指令时,如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。 622 | 623 | 另外,当指定 max-age 值为 0,那么缓存服务器通常需要将请求转发给源服务器。当服务器返回的响应中包含 max-age 指令时,缓存服务器将不对资源的 624 | 625 | **min-fresh 指令** 626 | 627 | ```http 628 | Cache-Control: min-fresh=60(单位:秒) 629 | ``` 630 | 631 | min-fresh 指令要求缓存服务器返回至少还未过指定时间的缓存资源。比如,当指定 min-fresh 为 60 秒后,过了 60 秒的资源都无法作为响应返回了。  632 | 633 | **only-if-cached 指令** 634 | 635 | ```http 636 | Cache-Control: only-if-cached 637 | ``` 638 | 639 | 使用 only-if-cached 指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本地缓存无响应,则返回状态码 504 Gateway Timeout。  640 | 641 | **5.3.2 Connection** 642 | 643 | Connection 首部字段具备如下两个作用。 644 | 645 | 1. 控制不再转发给代理的首部字段 646 | 647 | ```http 648 | # 原始请求 649 | GET HTTP/1.1 650 | Upgrade:HTTP/1.1 651 | Connection:Upgrade 652 | 653 | # 不转发首部字段 654 | GET / HTTP/1.1 655 | ``` 656 | 657 | 在客户端发送请求和服务器返回响应内,使用 Connection 首部字段,可控制不再转发给代理的首部字段(即 Hop-by-hop 首部)。  658 | 659 | 2. 管理持久连接 660 | 661 | ```http 662 | Connection: Keep-Alive 663 | 664 | # 请求数据 665 | GET / HTTP/1.1 666 | Connection: Keep-Alive 667 | 668 | # 响应数据 669 | HTTP/1.1 200 OK 670 | ... 671 | Keep-Alive:timeout=10,max=500 672 | Connection:Keep-Alive 673 | ``` 674 | 675 | **5.3.3 Via** 676 | 677 | 使用首部字段 Via 是为了追踪客户端与服务器之间的请求和响应报文的传输路径, 首部字段 Via 不仅用于追踪报文的转发, 还可以避免请求 678 | 679 | 回环的发生。所以必须在经过代理时附加该首部字段内容。  680 | 681 | ![[Pasted image 20220920101755.png]] 682 | 683 | ### 5.4 请求首部字段 684 | 685 | 请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。 686 | 687 | **5.4.1 Accept** 688 | 689 | ![[Pasted image 20220920101857.png]] 690 | 691 | Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用 type/subtype 这种形式,一次指定多种媒体类型。  692 | 693 | **5.4.2 Accept-Charset** 694 | 695 | ![[Pasted image 20220920101933.png]] 696 | 697 | Accept-Charset 首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段 Accept 相同的是可用权重 q 值来表示相对优先级。  698 | 699 | **5.4.3 Accept-Encoding** 700 | 701 | ![[Pasted image 20220920101959.png]] 702 | 703 | Accept-Encoding 首部字段用来告知服务器用户代理支持的内容编码及 内容编码的优先级顺序。可一次性指定多种内容编码。 704 | 705 | ### 5.5 响应首部字段 706 | 707 | 响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息 708 | 709 | **5.5.1 Accept-Ranges** 710 | 711 | ```http 712 | Accept-Ranges: bytes 713 | ``` 714 | 715 | 首部字段 Accept-Ranges 是用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。 可指定的字段值有两种,可处理范围请求时指定其为 bytes,反之则指定其为 none。  716 | 717 | **5.5.2 Age** 718 | 719 | ```http 720 | Age: 600 721 | ``` 722 | 723 | 首部字段 Age 能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次发起认证到认证完成的时间值。代理创建响应时必须加上首部字段Age 724 | 725 | **5.5.3 Location** 726 | 727 | ![[Pasted image 20220920102155.png]] 728 | 729 | 使用首部字段 Location 可以将响应接收方引导至某个与请求 URI 位置不同的资源。几乎所有的浏览器在接收到包含首部字段 Location 的响应后,都会强制性地尝试对已提示的重定向资源的访问。 730 | 731 | ### 5.6 实体首部字段 732 | 733 | 实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。 734 | 735 | **5.6.1 Allow** 736 | 737 | ```http 738 | Allow: GET, HEAD 739 | ``` 740 | 741 | 首部字段 Allow 用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。当服务器接收到不支持的 HTTP 方法时,会以状态码405 Method Not Allowed 作为响应返回。与此同时,还会把所有能支持的 HTTP 方法写入首部字段 Allow 后返回。  742 | 743 | **5.6.2 Content-Type** 744 | 745 | ```http 746 | Content-Type: text/html; charset=UTF-8 747 | ``` 748 | 749 | 首部字段 Content-Type 说明了实体主体内对象的媒体类型。和首部字段 Accept 一样,字段值用 type/subtype 形式赋值。  750 | 751 | **5.6.3 Expires** 752 | 753 | ```http 754 | Expires: Wed, 04 Jul 2020 08:26:05 GMT 755 | ``` 756 | 757 | 首部字段 Expires 会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段 Expires 的响应后,会以缓存来应答请求,在Expires 字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。  758 | 759 | 源服务器不希望缓存服务器对资源缓存时,最好在 Expires 字段内写入与首部字段 Date 相同的时间值。 760 | 761 | **5.6.4 Last-Modified** 762 | 763 | ```http 764 | Last-Modified: Wed, 23 May 2020 09:59:55 GMT 765 | ``` 766 | 767 | 首部字段 Last-Modified 指明资源最终修改的时间。一般来说,这个值就是 Request-URI 指定资源被修改的时间。但类似使用 CGI 脚本进 768 | 769 | 行动态数据处理时,该值有可能会变成数据最终修改时的时间。 770 | 771 | ### 5.7 为 Cookie 服务的首部字段 772 | 773 | **5.7.1 Set-Cookie** 774 | 775 | ```http 776 | Set-Cookie: status=enable; expires=Tue, 05 Jul 2020 07:26:31 777 | ``` 778 | 779 | 当服务器准备开始管理客户端的状态时,会事先告知各种信息。  780 | 781 | Set-Cookie字段值 782 | 783 | - NAME-VALUE : 赋予Cookie的名称和其值(必需项) 784 | - expires=DATE : Cookie的有效期(若不明确指定则默认为浏览器关闭前为止) 785 | - path=PATH : 将服务器上的文件目录作为Cookie的适用对象(若不指定则默 认为文档所在的文件目录) 786 | - domain=域名 : 作为Cookie适用对象的域名(若不指定则默认为创建Cookie 的服务器的域名) 787 | - Secure : 仅在HTTPS安全通信时才会发送Cookie 788 | - HttpOnly : 加以限制,使Cookie不能被JavaScript脚本访问 789 | 790 | **5.7.2 Cookie** 791 | 792 | ```http 793 | Cookie: status=enable 794 | ``` 795 | 796 | 首部字段 Cookie 会告知服务器,当客户端想获得 HTTP 状态管理支持时,就会在请求中包含从服务器接收到的 Cookie。接收到多个Cookie 时,同样可以以多个 Cookie 形式发送。  797 | 798 | ## 第六章 HTTPS 确保Web安全 799 | 800 | ### 6.1 HTTP 的缺点 801 | 802 | - 无法证明报文的完整性, 内容可能被篡改 803 | - 通信使用明文 (不加密), 内容可能被监听 804 | - 不验证通信双方的身份, 可能遭遇伪装 805 | 806 | ### 6.2 HTTP + 加密 + 认证 + 完整性保护 = HTTPS 807 | 808 | 通常在登录页面或是购物页面使用 HTTPS 通信, 使用 HTTPS 通信时, 不再使用 http:// 协议 而是使用 https:// 809 | 810 | 当浏览器访问 HTTPS 通信有效的 Web 页面时, 浏览器的地址栏内会出现一个带锁的标记, 对 HTTPS 的显示方式会因为浏览器的不同而有所改变 811 | 812 | **6.2.1 HTTPS是自身披SSL外壳的HTTP** 813 | 814 | HTTPS 并非是应用层的一种新协议. 只是 HTTP **通信接口部分用SSL**(Secure Socket Layer)和 **TLS**(Transport Layer Security)协议代替而已。当使用 SSL时,则演变成先和 SSL通信,再由 SSL和 TCP 通信了。简言之,所谓 HTTPS,其实就是身披SSL协议这层外壳的 HTTP。  815 | 816 | 在采用 SSL 后, HTTP 就拥有了 HTTPS 的加密, 证书和完整性保护这些功能 817 | 818 | SSL 是独立于 HTTP 的协议, 所以不光是 HTTP 协议, 其他运行在应用层的如 SMTP 和 Telnet 等协议均可配合 SSL 协议使用. 可以说 SSL 是当今世界上应用最为广泛的网络安全技术 819 | 820 | **6.2.2 相互交换密钥的公开加密技术** 821 | 822 | SSL 采用一种叫公开密钥加密 (Public-key cryptography) 的加密处理方式 823 | 824 | 加密和解密都会用到密钥, 如果没有密钥则无法对密码解密. 同样, 任何人只要持有密钥就能解密. 如果密钥被攻击者获得, 那加密也就失去了意义 825 | 826 | **1. 共享密钥加密的困境** 827 | 828 | 加密和解密使用同一个密钥的方式叫共享密钥加密 (Common key crypto system), 也被叫做**对称密钥加密** 829 | 830 | 以共享密钥方式加密时必须将密钥也发送给对方, 可酒精怎样才能安全的转交? 在互联网上转发密钥时,如果通信被监听那么密钥就可会落入攻击者之手,同时也就失去了加密的意义。另外还得设法安全地保管接收到的密钥。 831 | 832 | 发送密钥就有被窃听的风险,但不发送,对方就不能解密。再说,密钥若能够安全发送,那数据也应该能安全送达。 833 | 834 | **2. 使用两把密钥的公开密钥加密** 835 | 836 | 公开密钥加密方式很好的解决了共享密钥加密的困难 837 | 838 | 公开密钥加密使用一对**非对称**的密钥. 一把叫做私有密钥 (private key), 另一把叫公开密钥 (public key). 顾名思义, 任何密钥不能让其他人知道, 而公开密则可以随意发布, 任何人都可以获得. 839 | 840 | 使用公开密钥加密方式, 发送密文的一方使用对方的公开密钥进行加密处理, 对方收到被加密的信息后, 再使用自己的私有密钥进行解密. 利用这种方式, 不需要发送用来解密的私有密钥, 也不必担心密钥被攻击者窃听而盗走 841 | 842 | ![[Pasted image 20220920135726.png]] 843 | 844 | **3. HTTPS 采用混色加密机制** 845 | 846 | HTTPS 采用共享密钥加密和公开密钥加密两者并用的混合加密机制. 若密钥能够实现安全转换, 那么有可能会开率使用公开密钥加密来通信. 但是公开密钥与共享加密密钥相比, 其处理速度要更慢. 847 | 848 | 所以应充分利用两者各自的优势, 将多种方法组合起来用于通信. 在交换密钥环节使用公开密钥加密方式, 之后的建立通信交换报文阶段使用共享密钥加密方式 849 | 850 | ![[Pasted image 20220920135909.png]] 851 | 852 | **4. 证明公开密钥正确性的证书** 853 | 854 | 公开密钥加密方式还是存在一些问题的. 那就是无法证明公开密钥本手就是货真价实的公开密钥. 855 | 856 | 比如, 正准备和某台服务器建立公开密钥加密方式下的通信时, 如何证明收到的公开密钥就是原本预想的那台服务器发行的公开密钥. 或许在公开密钥传输途中, 真正的公开密钥已被攻击者替换掉了. 857 | 858 | **为了解决上述问题,可以使用由数字证书认证机构(CA,CertificateAuthority)和其相关机关颁发的公开密钥证书。** 859 | 860 | 数字证书认证机构处于客户端与服务器双方都可信赖的**第三方机构**的立场上。来介绍一下数字证书认证机构的业务流程。首先,服务器的运营人员向数字证书认证机构提出公开密钥的申请。数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。 861 | 862 | 服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信。 863 | 864 | 公钥证书也可叫做数字证书或直接称为证书。接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:一,认证服务器的公开密钥的是真实有效的数字证书认证机构。二,服务器的公开密钥是值得信赖的。  865 | 866 | 此处认证机关的公开密钥必须安全地转交给客户端。使用通信方式时,如何安全转交是一件很困难的,因此,多数浏览器开发商发布版本时,会事先在内部植入常用认证机关的公开密钥。  867 | 868 | ![[Pasted image 20220920140428.png]] 869 | 870 | **5. HTTPS 的安全通信机制** 871 | 872 | 为了更好地理解 HTTPS,我们来观察一下 HTTPS 的通信步骤。 873 | 874 | ![[Pasted image 20220920140516.png]] 875 | 876 | 步骤 1: 客户端通过发送 **Client Hello** 报文开始 SSL通信。报文中包含客户端支持的 SSL的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。 877 | 878 | 步骤 2: 服务器可进行 SSL通信时,会以 **Server Hello** 报文作为应答。和客户端一样,在报文中包含 SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。  879 | 880 | 步骤 3: 之后服务器发送 **Certificate** 报文。报文中包含公开密钥证书。 881 | 882 | 步骤 4: 最后服务器发送 **Server Hello Done** 报文通知客户端,最初阶段的 SSL握手协商部分结束。  883 | 884 | 步骤 5: SSL第一次握手结束之后,客户端以 **Client Key Exchange** 报文作为回应。报文中包含通信加密中使用的一种被称为 Pre-master secret 的随机密码串。该报文已用步骤 3 中的公开密钥进行加密。  885 | 886 | 步骤 6: 接着客户端继续发送 **Change Cipher Spec** 报文。该报文会提示服务器,在此报文之后的通信会采用 Pre-master secret 密钥加密。 887 | 888 | 步骤 7: 客户端发送 **Finished** 报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。  889 | 890 | 步骤 8: 服务器同样发送 **Change Cipher Spec** 报文。 891 | 892 | 步骤 9: 服务器同样发送 Finished 报文。 893 | 894 | 步骤 10: 服务器和客户端的 **Finished** 报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到 SSL的保护。从此处开始进行应用层协议的通信,即发送 HTTP 请求。 895 | 896 | 步骤 11: 应用层协议通信,即发送 HTTP 响应。 897 | 898 | 步骤 12: 最后由客户端断开连接。断开连接时,发送 **close_notify** 报文。上图做了一些省略,这步之后再发送 TCP FIN 报文来关闭与 TCP的通信。  899 | 900 | **下面是对整个流程的图解。图中说明了从仅使用服务器端的公开密钥证书(服务器证书)建立 HTTPS 通信的整个过程。**  901 | 902 | ![[Pasted image 20220920140817.png]] 903 | 904 | **Question: SSL 速度慢吗** 905 | 906 | HTTPS 也存在一些问题,那就是当使用 SSL时,它的处理速度会变慢。 907 | 908 | SSL的慢分两种。一种是指通信慢。另一种是指由于大量消耗CPU 及内存等资源,导致处理速度变慢。  909 | 910 | 和使用 HTTP 相比,网络负载可能会变慢 2 到 100 倍。除去和TCP 连接、发送 HTTP 请求 • 响应以外,还必须进行 SSL通信,因此整体上处理通信量不可避免会增加。  911 | 912 | 另一点是 SSL必须进行加密处理。在服务器和客户端都需要进行加密和解密的运算处理。因此从结果上讲,比起 HTTP 会更多地 913 | 914 | 消耗服务器和客户端的硬件资源,导致负载增强。 915 | 916 | 针对速度变慢这一问题,并没有根本性的解决方案,我们会使用SSL加速器这种(专用服务器)硬件来改善该问题。该硬件为SSL通信专用硬件,相对软件来讲,能够提高数倍 SSL的计算速度。仅在 SSL处理时发挥 SSL加速器的功效,以分担负载。  917 | 918 | **Question: 为什么不一直使用 HTTPS?** 919 | 920 | 既然 HTTPS 那么安全可靠,那为何所有的 Web 网站不一直使用HTTPS ? 921 | 922 | 其中一个原因是,因为与纯文本通信相比,加密通信会消耗更多的CPU 及内存资源。如果每次通信都加密,会消耗相当多的资源,平摊到一台计算机上时,能够处理的请求数量必定也会随之减少。  923 | 924 | 特别是每当那些访问量较多的 Web 网站在进行加密处理时,它们所承担着的负载不容小觑。在进行加密处理时,并非对所有内容都 925 | 926 | 进行加密处理,而是仅在那些需要信息隐藏时才会加密,以节约资源。 927 | 928 | 要进行 HTTPS 通信,证书是必不可少的。而使用的证书必须向认证机构(CA)购买。证书价格可能会根据不同的认证机构略有不同。通常,一年的授权需要数万日元(现在一万日元大约折合 600 人民币) 929 | 930 | ## 第七章 确认访问用户身份的认证 931 | 932 | 某些 Web 页面只想让特定的人浏览,或者干脆仅本人可见。为达到这个目标,必不可少的就是认证功能。下面我们一起来学习一下认证 933 | 934 | - HTTP 使用的认证方式  935 | - BASIC认证【基本认证】 936 | - DIGEST认证【摘要认证】 937 | - SSL客户端认证 938 | - FormBase认证【基于表单认证】 939 | 940 | ### 7.1 BASIC 认证 941 | 942 | BASIC 认证(基本认证)是从 HTTP/1.0 就定义的认证方式。即便是现在仍有一部分的网站会使用这种认证方式。是 Web 服务器与通信 943 | 944 | 客户端之间进行的认证步骤: 945 | 946 | ![[Pasted image 20220920141454.png]] 947 | 948 | 步骤 1: 当请求的资源需要 BASIC 认证时,服务器会随状态码 401Authorization Required,返回带 WWW-Authenticate 首部字段的响应。该字段内包含认证的方式(BASIC) 及 Request-URI 安全域字符串(realm)。  949 | 950 | 步骤 2: 接收到状态码 401 的客户端为了通过 BASIC 认证,需要将用户 ID 及密码发送给服务器。发送的字符串内容是由用户 ID 和密码构成,两者中间以冒号(:)连接后,再经过 Base64 编码处理。  951 | 952 | 步骤 3: 接收到包含首部字段 Authorization 请求的服务器,会对认证信息的正确性进行验证。如验证通过,则返回一条包含 Request-URI资源的响应。  953 | 954 | BASIC 认证虽然采用 Base64 编码方式,但这不是加密处理。不需要任何附加信息即可对其解码。换言之,由于明文解码后就是用户 ID 和密码,在 HTTP 等非加密通信的线路上进行 BASIC 认证的过程中,如果被人窃听,被盗的可能性极高。  955 | 956 | BASIC 认证使用上不够便捷灵活,且达不到多数 Web 网站期望的安全性等级,因此它并不常用。  957 | 958 | ### 7.1 DIGEST 认证 959 | 960 | 为弥补 BASIC 认证存在的弱点, 从 HTTP/1.1 起就有了 DIGEST 认证. DIGEST 认证同样使用质询/响应的方式 (challenge/response), 但不会像 BASIC 认证那样直接发送明文密码 961 | 962 | 所谓质询响应方式是指,一开始一方会先发送认证要求给另一方,接着使用从另一方那接收到的质询码计算生成响应码。最后将响应码返回给对方进行认证的方式。 963 | 964 | DIGEST 认证步骤: 965 | 966 | ![[Pasted image 20220920141731.png]] 967 | 968 | 步骤 1: 请求需认证的资源时,服务器会随着状态码 401Authorization Required,返 回带 WWW-Authenticate 首部字段的响应。 969 | 970 | 该字段内包含质问响应方式认证所需的临时质询码(随机数,nonce)。  971 | 972 | 步骤 2: 接收到 401 状态码的客户端,返回的响应中包含 DIGEST 认证必须的首部字段 Authorization 信息。  973 | 974 | 步骤 3: 接收到包含首部字段 Authorization 请求的服务器,会确认认证信息的正确性。认证通过后则返回包含 Request-URI 资源的响应。  975 | 976 | 并且这时会在首部字段 Authentication-Info 写入一些认证成功的相关信息。 977 | 978 | DIGEST 认证提供了高于 BASIC 认证的安全等级,但是和 HTTPS 的客户端认证相比仍旧很弱。DIGEST 认证提供防止密码被窃听的保护机制,但并不存在防止用户伪装的保护机制。  979 | 980 | DIGEST 认证和 BASIC 认证一样,使用上不那么便捷灵活,且仍达不到多数 Web 网站对高度安全等级的追求标准。因此它的适用范围也有所受限。  981 | 982 | ### 7.3 SSL 客户端认证 983 | 984 | SSL 客户端认证是借由 HTTPS 的客户端证书完成认证的方式. 凭借客户端证书 (在 HTTPS 一章已讲解) 认证, 服务器可确认访问是否已登录的客户端 985 | 986 | **7.3.1 SSL客户端认证的认证步骤** 987 | 988 | 为达到 SSL客户端认证的目的,需要事先将客户端证书分发给客户端,且客户端必须安装此证书。  989 | 990 | 步骤 1: 接收到需要认证资源的请求,服务器会发送 CertificateRequest 报文,要求客户端提供客户端证书。 991 | 992 | 步骤 2: 用户选择将发送的客户端证书后,客户端会把客户端证书信息以 Client Certificate 报文方式发送给服务器。  993 | 994 | 步骤 3: 服务器验证客户端证书验证通过后方可领取证书内客户端的公开密钥,然后开始 HTTPS 加密通信。 995 | 996 | **7.3.2 SSL 客户端认证采用双因素认证** 997 | 998 | 在多数情况下,SSL客户端认证不会仅依靠证书完成认证,一般会和基于表单认证(稍后讲解)组合形成一种双因素认证(Two-factor authentication)来使用 999 | 1000 | 所谓双因素认证就是指,认证过程中不仅需要密码这一个因素,还需要申请认证者提供其他持有信息,从而作为另一个因素,与其组合使用的认证方式。 1001 | 1002 | 换言之,第一个认证因素的 SSL客户端证书用来认证客户端计算机,另一个认证因素的密码则用来确定这是用户本人的行为。通过双因素认证后,就可以确认是用户本人正在使用匹配正确的计算机访问服务器。  1003 | 1004 | ### 7.4 基于表单认证 1005 | 1006 | 基于表单的认证方法并不是在 HTTP 协议中定义的。客户端会向服务器上的 Web 应用程序发送登录信息(Credential),按登录信息的验证结果认证。 1007 | 1008 | 根据 Web 应用程序的实际安装,提供的用户界面及认证方式也各不 相同。 1009 | 1010 | 多数情况下,输入已事先登录的用户 ID(通常是任意字符串或邮件 地址)和密码等登录信息后,发送给 Web 应用程序,基于认证结果 来决定认证是否成功。 1011 | 1012 | **7.4.1 认证多半为基于表单认证** 1013 | 1014 | 由于使用上的便利性及安全性问题,HTTP 协议标准提供的 BASIC 认 证和 DIGEST 认证几乎不怎么使用。另外,SSL客户端认证虽然具有 高度的安全等级,但因为导入及维持费用等问题,还尚未普及。 1015 | 1016 | 比如 SSH 和 FTP 协议,服务器与客户端之间的认证是合乎标准规范 的,并且满足了最基本的功能需求上的安全使用级别,因此这些协议的认证可以拿来直接使用。但是对于 Web 网站的认证功能能够满 足其安全使用级别的标准规范并不存在,所以只好使用由 Web 应用程序各自实现基于表单的认证方式。 1017 | 1018 | **7.4.2 Session 管理及 Cookie 应用** 1019 | 1020 | 基于表单认证的标准规范尚未有定论,一般会使用 Cookie 来管理 Session(会话)。 1021 | 1022 | 基于表单认证本身是**通过**服务器端的 **Web 应用**,将客户端发送过来的用户 ID 和密码与之前登录过的信息做匹配来进行认证的。 1023 | 1024 | 但鉴于 HTTP 是无状态协议,之前已认证成功的用户状态无法通过协 议层面保存下来。即,无法实现状态管理,因此即使当该用户下一次 继续访问,也无法区分他与其他的用户。于是我们会使用 Cookie 来 管理 Session,以弥补 HTTP 协议中不存在的状态管理功能。 1025 | 1026 | ![[Pasted image 20220920142411.png]] 1027 | 1028 | 步骤 1: 客户端把用户 ID 和密码等登录信息放入报文的实体部分, 通常是以 POST 方法把请求发送给服务器。而这时,会使用 HTTPS 通信来进行 HTML表单画面的显示和用户输入数据的发送。 1029 | 1030 | 步骤 2: 服务器会发放用以识别用户的 **Session ID**。通过验证从客户端发送过来的登录信息进行身份认证,然后把用户的认证状态与 Session ID 绑定后记录在服务器端。 1031 | 1032 | 向客户端返回响应时,会在首部字段 Set-Cookie 内写入 Session ID(如 PHPSESSID=028a8c…) 1033 | 1034 | 你可以把 Session ID 想象成一种用以区分不同用户的等位号。 1035 | 1036 | 然而,如果 Session ID 被第三方盗走,对方就可以伪装成你的身份进行恶意操作了。因此必须防止 Session ID 被盗,或被猜出。为了做到 这点,Session ID 应使用难以推测的字符串,且服务器端也需要进行有效期的管理,保证其安全性。 1037 | 1038 | 另外,为减轻跨站脚本攻击(XSS)造成的损失,建议事先在 Cookie 内加上 **httponly** 属性。 1039 | 1040 | 步骤 3: 客户端接收到从服务器端发来的 Session ID 后,会将其作为 **Cookie** 保存在本地。下次向服务器发送请求时,浏览器会自动发送 Cookie,所以 Session ID 也随之发送到服务器。服务器端可通过验证 接收到的 Session ID 识别用户和其认证状态。 1041 | 1042 | 除了以上介绍的应用实例,还有应用其他不同方法的案例。 1043 | 1044 | 另外,不仅基于表单认证的登录信息及认证过程都无标准化的方法, 服务器端应如何保存用户提交的密码等登录信息等也没有标准化。 1045 | 1046 | 通常,一种安全的保存方法是,先利用给密码加盐 (salt) 的方式增 加额外信息,再使用散列(hash)函数计算出散列值后保存。但是我们也经常看到直接保存明文密码的做法,而这样的做法具有导致密码泄露的风险。 1047 | 1048 | > salt 其实就是由服务器随机生成的一个字符串,但是要保证长度足够长,并且是真正随机生成的。然后把它和密码字符串相连接(前后都可以)生成散列值。当两个用户使用了同一个密码时,由于随机生成的 salt 值不同,对应的散列值也将 是不同的。这样一来,很大程度上减少了密码特征,攻击者也就很难利用自己手中的密码特征库进行破解。——译者注 1049 | 1050 | ## 第八章 基于 HTTP 的功能追加协议 1051 | 1052 | ### 8.1 消除 HTTPS 瓶颈的 SPDY 1053 | 1054 | Google 在 2010 年发布了 SPDY(取自 SPeeDY,发音同 speedy),其开发目标旨在解决 HTTP 的性能瓶颈,缩短 Web 页面的加载时间(50%)。 1055 | 1056 | **8.1.1 HTTP 的瓶颈** 1057 | 1058 | 为了尽可能实时地显示这些更新的内容,服务器上一有内容更新,就需要直接把那些内容反馈到客户端的界面上。虽然看起来挺简单的, 1059 | 1060 | 但 HTTP 却无法妥善地处理好这项任务。  1061 | 1062 | 使用 HTTP 协议探知服务器上是否有内容更新,就必须频繁地从客户端到服务器端进行确认。如果服务器上没有内容更新,那么就会产生徒劳的通信。 1063 | 1064 | **8.1.2 SPDY 消除 Web 瓶颈了吗** 1065 | 1066 | 希望使用 SPDY 时,Web 的内容端不必做什么特别改动,而 Web 浏览器及 Web 服务器都要为对应 SPDY 做出一定程度上的改动。有好几家 Web 浏览器已经针对 SPDY 做出了相应的调整。另外,Web 服务器也进行了实验性质的应用,但把该技术导入实际的 Web 网站却进展不佳。因为 SPDY 基本上只是将单个域名( IP 地址)的通信多路复用,所以当一个 Web 网站上使用多个域名下的资源,改善效果就会受到限制。 1067 | 1068 | SPDY 的确是一种可有效消除 HTTP 瓶颈的技术,但很多 Web 网站存在的问题并非仅仅是由 HTTP 瓶颈所导致。对 Web 本身的速度提升,还应该从其他可细致钻研的地方入手,比如改善 Web 内容的编写方式等 1069 | 1070 | ### 8.2 使用浏览器进行全双工通信的 WebSocket 1071 | 1072 | 利用 Ajax 和 Comet 技术进行通信可以提升 Web 的浏览速度。但问题在于通信若使用 HTTP 协议,就无法彻底解决瓶颈问题。WebSocket网络技术正是为解决这些问题而实现的一套新协议及 API。  1073 | 1074 | **8.2.1 WebSocket 的设计与功能** 1075 | 1076 | WebSocket,即 Web 浏览器与 Web 服务器之间全双工通信标准。其中,WebSocket 协议由 IETF 定为标准,WebSocket API 由 W3C 定为标准。仍在开发中的 WebSocket 技术主要是为了解决 Ajax 和 Comet里 XMLHttpRequest 附带的缺陷所引起的问题。 1077 | 1078 | **8.2.2 WebSocket协议与特点** 1079 | 1080 | 一旦 Web 服务器与客户端之间建立起 WebSocket 协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可互相发送JSON、XML、HTML或图片等任意格式的数据。  1081 | 1082 | 下面我们列举一下 WebSocket 协议的主要特点。 1083 | 1084 | 1. **推送功能:** 支持由服务器向客户端推送数据的推送功能。这样,服务器可直接发送数据,而不必等待客户端的请求。  1085 | 1086 | 2. **减少通信量:** 只要建立起 WebSocket 连接,就希望一直保持连接状态。和 HTTP 相比,不但每次连接时的总开销减少,而且由于 WebSocket 的首部信息很小,通信量也相应减少了。 1087 | 1088 | ### 8.3 期盼已久的 HTTP/2.0 1089 | 1090 | 目前主流的 HTTP/1.1 标准,自 1999 年发布的 RFC2616 之后再未进行过改订。SPDY 和 WebSocket 等技术纷纷出现,很难断言 HTTP/1.1仍是适用于当下的 Web 的协议。  1091 | 1092 | HTTP/2.0 围绕着主要的 7 项技术进行讨论,现阶段(2012 年 8 月 13日),大都倾向于采用以下协议的技术。但是,讨论仍在持续,所以不能排除会发生重大改变的可能性。  1093 | 1094 | ![[Pasted image 20220920143132.png]] 1095 | 1096 | ### 8.4 Web 服务器管理文件的 WebDAV 1097 | 1098 | WebDAV(Web-based Distributed Authoring and Versioning,基于万维网 的分布式创作和版本控制)是一个可对 Web 服务器上的内容直接进 行文件复制、编辑等操作的分布式文件系统。它作为扩展 HTTP/1.1 的协议定义在 RFC4918。 1099 | 1100 | 除了创建、删除文件等基本功能,它还具备文件创建者管理、文件编 辑过程中禁止其他用户内容覆盖的加锁功能,以及对文件内容修改的 版本控制功能。 1101 | 1102 | ![[Pasted image 20220920143202.png]] 1103 | 1104 | 使用 HTTP/1.1 的 PUT 方法和 DELETE 方法,就可以对 Web 服务器 上的文件进行**创建和删除**操作。可是出于安全性及便捷性等考虑,一 般不使用。 1105 | 1106 | **8.5.1 扩展 HTTP/1.1 的 WebDAV** 1107 | 1108 | 针对服务器上的资源,WebDAV 新增加了一些概念,如下所示。 1109 | 1110 | ![[Pasted image 20220920143244.png]] 1111 | 1112 | - 集合(Collection):是一种统一管理多个资源的概念。以集合为单位可进行各种操作。也可实现类似集合的集合这样的叠加。 1113 | - 资源(Resource):把文件或集合称为资源。 1114 | - 属性(Property):定义资源的属性。定义以“名称 = 值”的格式执 行。 1115 | - 锁(Lock):把文件设置成无法编辑状态。多人同时编辑时,可 防止在同一时间进行内容写入。 1116 | 1117 | **8.5.2 WebDAV 内新增的方法及状态码** 1118 | 1119 | WebDAV 为实现远程文件管理,向 HTTP/1.1 中追加了以下这些方 法。 1120 | 1121 | - PROPFIND :获取属性 1122 | - PROPPATCH :修改属性 1123 | - MKCOL :创建集合 1124 | - COPY :复制资源及属性 1125 | - MOVE :移动资源 1126 | - LOCK :资源加锁 1127 | - UNLOCK :资源解锁 1128 | 1129 | 为配合扩展的方法,状态码也随之扩展。 1130 | 1131 | - 102 Processing :可正常处理请求,但目前是处理中状态 1132 | - 207 Multi-Status :存在多种状态 1133 | - 422 Unprocessible Entity :格式正确,内容有误 1134 | - 423 Locked :资源已被加锁 1135 | - 424 Failed Dependency :处理与某请求关联的请求失败,因此不再维 1136 | - 182 持依赖关系 1137 | - 507 Insufficient Storage :保存空间不足 1138 | 1139 | WebDAV 的请求实例: 1140 | 1141 | 下面是使用 PROPFIND 方法对 http://www.example.com/file 发起 获取属性的请求。 1142 | ```http 1143 | PROPFIND /file HTTP/1.1 1144 | Host: www.example.com 1145 | Content-Type: application/xml; charset="utf-8" 1146 | Content-Length: 219 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | ``` 1158 | 1159 | WebDAV 的响应实例: 1160 | 1161 | 下面是针对之前的 PROPFIND 方法,返回 http://www.example.com/file 的属性的响应。 1162 | 1163 | ```http 1164 | HTTP/1.1 207 Multi-Status 1165 | Content-Type: application/xml; charset="utf-8" 1166 | Content-Length: 831 http://www.example.com/file Box type A 1167 | 1168 | 1169 | 1170 | 1171 | http://www.example.com/file 1172 | 1173 | 1174 | Box type A 1175 | 1176 | 1177 | J.J. Johnson 1178 | 1179 | 1180 | HTTP/1.1 200 OK 1181 | 1182 | 1183 | 1184 | HTTP/1.1 403 Forbidden 1185 | The user does not have access to the DingALing property. 1186 | 1187 | 1188 | 1189 | There has been an access violation error. 1190 | 1191 | 1192 | ``` 1193 | 1194 | 1195 | > 为何 HTTP 协议受众如此广泛 1196 | > 1197 | > 本章讲解了几个与 HTTP 相关联的协议使用案例。为什么 HTTP 协 议受众能够如此广泛呢? 1198 | > 1199 | > 过去,新编写接入互联网的系统或软件时,还需要同时编写实现与必要功能对应的新协议。但最近,使用 HTTP 的系统和软件占了绝大多数。 1200 | > 1201 | > 这有着诸多原因,其中与企业或组织的防火墙设定有着莫大的关系。防火墙的基本功能就是禁止非指定的协议和端口号的数据包通过。因此如果使用新协议或端口号则必须修改防火墙设置。 1202 | > 1203 | > 互联网上,使用率最高的当属 Web。不管是否具备访问 FTP 和 SSH 的权限,一般公司都会开放对 Web 的访问。Web 是基于 HTTP 协议运作的,因此在构建 Web 服务器或访问 Web 站点时,需事先设置防火墙 HTTP(80/tcp)和 HTTPS(443/tcp)的权限。 1204 | > 1205 | > 许多公司或组织已设定权限将 HTTP 作为通信环境,因此无须再修改防火墙的设定。可见 HTTP 具有导入简单这一大优势。而这也是基于 HTTP 服务或内容不断增加的原因之一。 1206 | > 1207 | > 还有一些其他原因,比如,作为 HTTP 客户端的浏览器已相当普遍,HTTP 服务器的数量已颇具规模,HTTP 本身就是优异的应用等。 1208 | 1209 | ## 第九章 构建 Web 内容的技术 1210 | 1211 | ### 9.1 HTML 1212 | 1213 | **9.1.1 Web页面几乎全由 HTMl 构建** 1214 | 1215 | HTML(HyperText Markup Language,超文本标记语言)是为了发送 Web 上的超文本(Hypertext)而开发的标记语言。超文本是一种文档系统,可将文档中任意位置的信息与其他信息(文本或图片等)建立关联,即超链接文本。标记语言是指通过在文档的某部分穿插特别的字符串标签,用来修饰文档的语言。我们把出现在 HTML文档内的 这种特殊字符串叫做 HTML标签(Tag)。 1216 | 1217 | 平时我们浏览的 Web 页面几乎全是使用 HTML写成的。由 HTML构 成的文档经过浏览器的解析、渲染后,呈现出来的结果就是 Web 页 面。 1218 | 1219 | 以下就是用 HTML编写的文档的例子。而这份 HTML文档内这种被 < > 包围着的文字就是标签。在标签的作用下,文档会改变样式,或插 入图片、链接。 1220 | 1221 | ```html 1222 | 1223 | 1224 | 1225 | hackr.jp 1226 | 1232 | 1233 | 1234 | 1235 | 1240 | 1241 | 1242 | ``` 1243 | **9.1.2 HTMl 的版本** 1244 | 1245 | 目前的最新版本是 HTML5 标准 1246 | 1247 | HTML5 标准不仅解决了浏览器之间的兼容性问题,并且可把文本作 为数据对待,更容易复用,动画等效果也变得更生动。 1248 | 1249 | 时至今日,HTML仍存在较多悬而未决问题。有些浏览器未遵循 HTML标准实现,或扩展自用标签等,这都反映了 HTML的标准实际 上尚未统一这一现状。 1250 | 1251 | **9.1.3 设计应用 CSS** 1252 | 1253 | CSS(Cascading Style Sheets,层叠样式表)可以指定如何展现 HTML 内的各种元素,属于样式表标准之一。即使是相同的 HTML文档, 通过改变应用的 CSS,用浏览器看到的页面外观也会随之改变。CSS 的理念就是让文档的结构和设计分离,达到解耦的目的。 1254 | 1255 | CSS 实例 1256 | 1257 | ```css 1258 | .logo { 1259 | padding: 20px; 1260 | text-align: center; 1261 | } 1262 | ``` 1263 | 1264 | 可在**选择器**(selector)`.logo` 的指定范围内,使用 {} 括起来的声明块 中写明的 `padding: 20px` 等声明语句应用指定的样式。 可通过指定 HTML元素或特定的 `class`、`ID` 等作为选择器来限定样式 的应用范围。 1265 | 1266 | ### 9.2 动态 HTML 1267 | 1268 | **9.2.1 让 Web 页面动起来的动态 HTMl** 1269 | 1270 | 所谓动态 HTML(Dynamic HTML),是指使用客户端脚本语言将静态的 HTML 内容变成动态的技术的总称。鼠标单击点开的新闻、 Google Maps 等可滚动的地图就用到了动态 HTML。 1271 | 1272 | 动态 HTML技术是通过调用客户端脚本语言 **JavaScript**,实现对 HTML的 Web 页面的动态改造。利用 DOM(Document Object Model,文档对象模型)可指定欲发生动态变化的 HTML元素。 1273 | 1274 | **9.2.2 更易控制 HTML 的 DOM** 1275 | 1276 | DOM 是用以操作 HTML 文档和 XML 文档的 API(Application Programming Interface,应用编程接口)。使用 DOM 可以将 HTML 内的元素当作对象操作,如取出元素内的字符串、改变那个 CSS 的属 性等,使页面的设计发生改变。 1277 | 1278 | 通过调用 JavaScript 等脚本语言对 DOM 的操作,可以以更为简单的方式控制 HTML 的改变。 1279 | 1280 | ```html 1281 | 1282 |

繁琐的Web安全

1283 |

第Ⅰ部分 Web的构成元素

1284 |

第Ⅱ部分 浏览器的安全功能

1285 |

第Ⅲ部分 接下来发生的事

1286 | 1287 | ``` 1288 | 1289 | 比如,从 JavaScript 的角度来看,将上述 HTML文档的第 3 个 P 元素 (P 标签)改变文字颜色时,会像下方这样编写代码。 1290 | 1291 | ```html 1292 | 1296 | ``` 1297 | 1298 | 1. `document.getElementsByTagName('P')` 语句调用 `getElementsByTagName` 函数,从整个 HTML文档 `(document object)` 内取出 P 元素 1299 | 2. 接下来 的 `content[2].style.color = '#FF0000'` 语句指定 `content` 的索引为 2(第 3 个)的元素的样式颜色改为红色(#FF0000) 1300 | 1301 | DOM 内存在各种函数,使用它们可查阅 HTML中的各个元素。 1302 | 1303 | ### 9.3 Web 应用 1304 | 1305 | **9.3.1 通过 Web 提供功能的 Web 应用** 1306 | 1307 | Web 应用是指通过 Web 功能提供的应用程序。比如购物网站、网上 银行、SNS、BBS、搜索引擎和 e-learning 等。互联网(Internet)或企 业内网(Intranet)上遍布各式各样的 Web 应用。 1308 | 1309 | 原本应用 HTTP 协议的 Web 的机制就是对客户端发来的请求,返回事前准备好的内容。可随着 Web 越来越普及,仅靠这样的做法已不 足以应对所有的需求,更需要引入由程序创建 HTML内容的做法。 1310 | 1311 | 类似这种由程序创建的内容称为动态内容,而事先准备好的内容称为静态内容。Web 应用则作用于动态内容之上。 1312 | 1313 | ![[Pasted image 20220920161405.png]] 1314 | 1315 | **9.3.2 与 Web 服务器及程序协作的 CGI** 1316 | 1317 | CGI(Common Gateway Interface,通用网关接口)是指 Web 服务器在接收到客户端发送过来的请求后转发给程序的一组机制。在 CGI 的作用下,程序会对请求内容做出相应的动作,比如创建 HTML等动态内容。 1318 | 1319 | 使用 CGI 的程序叫做 CGI 程序,通常是用 Perl、PHP、Ruby 和 C 等 编程语言编写而成。 1320 | 1321 | ![[Pasted image 20220920161514.png]] 1322 | 1323 | **9.3.3 因 Java 而普及的 Servlet** 1324 | 1325 | Servlet 是一种能在服务器上创建动态内容的程序。Servlet 是用 Java 语言实现的一个接口,属于面向企业级 Java(JavaEE,Java Enterprise Edition)的一部分。 1326 | 1327 | > Servlet 没有对应中文译名,全称是 Java Servlet。名称取自 Servlet=Server+Applet,表示 轻量服务程序。——译者注 1328 | 1329 | 之前提及的 CGI,由于每次接到请求,程序都要跟着启动一次。因此 一旦访问量过大,Web 服务器要承担相当大的负载。而 Servlet 运行 在与 Web 服务器相同的进程中,因此受到的负载较小。Servlet 的运 行环境叫做 Web 容器或 Servlet 容器。 1330 | 1331 | > Servlet 常驻内存,因此在每次请求时,可启动相对进程级别更为轻量的Servlet,程序的执行效率从而变得更高。——译者注 1332 | 1333 | Servlet 作为解决 CGI 问题的对抗技术,随 Java 一起得到了普及。 1334 | 1335 | > 说对抗的原因在于,这个方向上已存在用 Perl 编写的 CGI,实现在 Apache HTTP Server 上内置 mod_php 模块后可运行 PHP 程序、微软主导的 ASP 等技术。 ——译者注 1336 | 1337 | 随着 CGI 的普及,每次请求都要启动新 CGI 程序的 CGI 运行机制逐 渐变成了性能瓶颈,所以之后 Servlet 和 mod_perl 等可直接在 Web 服 务器上运行的程序才得以开发、普及。 1338 | 1339 | ### 9.4 数据发布的格式及语言 1340 | 1341 | **9.4.1 可拓展标记语言** 1342 | 1343 | XML(eXtensible Markup Language,可扩展标记语言)是一种可按应用目标进行扩展的通用标记语言。旨在通过使用 XML,使互联网数 据共享变得更容易。 1344 | 1345 | XML和 HTML都是从标准通用标记语言 SGML(Standard Generalized Markup Language)简化而成。与 HTML相比,它对数据的记录方式做了特殊处理。 1346 | 1347 | 下面我们以 HTML编写的某公司的研讨会议议程为例进行说明。 1348 | 1349 | ```html 1350 | 1351 | 1352 | T公司研讨会介绍 1353 | 1354 | 1355 |

T公司研讨会介绍

1356 |
    1357 |
  • 研讨会编号:TR001 1358 |
      1359 |
    • Web应用程序脆弱性诊断讲座
    • 1360 |
    1361 |
  • 1362 |
  • 研讨会编号:TR002 1363 |
      1364 |
    • 网络系统脆弱性诊断讲座
    • 1365 |
    1366 |
  • 1367 |
1368 | 1369 | 1370 | ``` 1371 | 1372 | 用浏览器打开该文档时,就会显示排列的列表内容,但如果这些数据被其他程序读取会发生什么?某些程序虽然具备可通过识别布局特征取出文本的方法,但这份 HTML的样式一旦改变,要读取数据内容 也就变得相对困难了。可见,为了保持数据的正确读取,HTML不适 合用来记录数据结构。 1373 | 1374 | 接着将这份列表以 XML的形式改写就成了以下的示例。 1375 | 1376 | ```html 1377 | <研讨会 编号="TR001" 主题="Web应用程序脆弱性诊断讲座"> 1378 | <类别>安全 1379 | <概要>为深入研究Web应用程序脆弱性诊断必要的… 1380 | 1381 | <研讨会 编号="TR002" 主题="网络系统脆弱性诊断讲座"> 1382 | <类别>安全 1383 | <概要>为深入研究网络系统脆弱性诊断必要的… 1384 | 1385 | ``` 1386 | 1387 | XML和 HTML一样,使用标签构成树形结构,并且可自定义扩展标签. 1388 | 1389 | 从 XML 文档中读取数据比起 HTML更为简单。由于 XML 的结构基本上都是用标签分割而成的树形结构,因此通过语法分析器 (Parser)的解析功能解析 XML结构并取出数据元素,可更容易地对 数据进行读取。 1390 | 1391 | 更容易地复用数据使得 XML在互联网上被广泛接受。比如,可用在 2 个不同的应用之间的交换数据格式化。 1392 | 1393 | **9.4.2 发布更新信息的 RSS/Atom** 1394 | 1395 | RSS(简易信息聚合,也叫聚合内容)和 Atom 都是发布新闻或博客 日志等更新信息文档的格式的总称。两者都用到了 XML。 1396 | 1397 | RSS 有以下版本,名称和编写方式也不相同。 1398 | 1399 | - RSS 0.9(RDFSite Summary):最初的 RSS 版本。1999 年 3 月由网 景通信公司自行开发用于其门户网站。基础构图创建在初期的 RDF 规格上。 1400 | - RSS 0.91(Rich Site Summary):在 RSS0.9 的基础上扩展元素,于 1999 年 7 月开发完毕。非 RDF 规格,使用 XML方式编写。 RSS 1.0(RDFSite Summary):RSS 规格正处于混乱状态。2000 年 12 月由 RSS-DEV 工作组再次采用 RSS0.9 中使用的 RDF 规格发布。 1401 | - RSS2.0(Really Simple Syndication):非 RSS1.0 发展路线。增加支 持 RSS0.91 的兼容性,2000 年 12 月由 UserLand Software 公司开发完 成。 1402 | 1403 | Atom 具有以下两种标准。 1404 | 1405 | - Atom 供稿格式(Atom Syndication Format):为发布内容而制定的 网站消息来源格式,单讲 Atom 时,就是指此标准。 1406 | - Atom 出版协定(Atom Publishing Protocol):为 Web 上内容的新增 或修改而制定的协议。 1407 | 1408 | 用于订阅博客更新信息的 RSS 阅读器,这种应用几乎支持 RSS 的所 有版本以及 Atom。 1409 | 1410 | RSS1.0 示例 1411 | 1412 | ```rss 1413 | 1414 | 1415 | 1421 | 1422 | 兔子的文学日记 1423 | http://d.hatena.ne.jp/sen-u/ 1424 | 兔子的文学日记 1425 | 1426 | 1427 | 1428 | [security]提供脆弱性悬赏奖金计划的网站一览 1429 | http://d.hatena.ne.jp/sen-u/20121215/p1 1430 | 正是所谓“是所谓 Bounty Programs”、处理接受Web脆弱性的相关信息,并提供奖金的计划 ... 1431 | sen-u 1432 | 2012-12-15 1433 | security 1434 | 1435 | ``` 1436 | 1437 | **9.4.3 JavaScript 衍生的轻量级易用 JSON** 1438 | 1439 | JSON(JavaScript Object Notation)是一种以 JavaScript(ECMAScript)的对象表示法为基础的轻量级数据标记语 言。能够处理的数据类型有 false/null/true/ 对象 / 数组 / 数字 / 字符 串,这 7 种类型。 1440 | 1441 | `{"name": "Web Application Security", "num": "TR001"}` 1442 | 1443 | JSON 让数据更轻更纯粹,并且 JSON 的字符串形式可被 JavaScript 轻易地读入。当初配合 XML使用的 Ajax 技术也让 JSON 的应用变得 更为广泛。另外,其他各种**编程语言**也提供丰富的**库**类,以达到轻便操作 JSON 的目的。 1444 | 1445 | ## 第十章 Web 的攻击技术 1446 | 1447 | ### 10.1 针对 Web 的攻击技术 1448 | 1449 | 简单的 HTTP 协议本身并不存在安全性问题,因此协议本身几乎不会成为攻击的对象。应用 HTTP 协议的服务器和客户端,以及运行在服务器上的 Web 应用等资源才是攻击目标。  1450 | 1451 | **10.1.1 HTTP 不具备必要的安全功能** 1452 | 1453 | 与最初的设计相比,现今的 Web 网站应用的 HTTP 协议的使用方式 已发生了翻天覆地的变化。几乎现今所有的 Web 网站都会使用会话 (session)管理、加密处理等安全性方面的功能,而 HTTP 协议内并 不具备这些功能。 1454 | 1455 | 从整体上看,HTTP 就是一个通用的单纯协议机制。因此它具备较多优势,但是在安全性方面则呈劣势。 1456 | 1457 | 就拿远程登录时会用到的 SSH 协议来说,SSH 具备协议级别的认证及会话管理等功能,HTTP 协议则没有。另外在架设 SSH 服务方面,任何人都可以轻易地创建安全等级高的服务,而 HTTP 即使已架设好服务器,但若想提供服务器基础上的 Web 应用,很多情况下都需要重新开发。 1458 | 1459 | 开发者需要自行设计并开发认证及会话管理功能来满足 Web 应用的安全。而自行设计就意味着会出现各种形形色色的实现。结果,安全等级并不完备,可仍在运作的 Web 应用背后却隐藏着各种容易被攻击者滥用的安全漏洞的 Bug。 1460 | 1461 | **10.1.2 在客户端即可篡改请求** 1462 | 1463 | 在 Web 应用中,从浏览器那接收到的 HTTP 请求的全部内容,都可以在客户端自由地变更、篡改。所以 Web 应用可能会接收到与预期数据不相同的内容。 1464 | 1465 | 在 HTTP 请求报文内加载攻击代码,就能发起对 Web 应用的攻击。 通过 **URL** **查询字段或表单**、**HTTP 首部**、**Cookie** 等途径把攻击代码传 入,若这时 Web 应用存在安全漏洞,那内部信息就会遭到窃取,或被攻击者拿到管理权限。 1466 | 1467 | ![[Pasted image 20220920163224.png]] 1468 | 1469 | **10.1.3 针对 Web 的应用攻击模式** 1470 | 1471 | **以服务器为目标的主动攻击** 1472 | 1473 | 主动攻击 (active attack) 是指攻击者通过直接访问 Web 应用, 把攻击代码传入的攻击模式. 由于该模式是直接针对服务器上的资源进行攻击, 因此攻击者需要能够访问到那些资源 1474 | 1475 | 主动攻击力最具有代表性的攻击是 SQL 注入和 OS 命令注入攻击 1476 | 1477 | ![[Pasted image 20220920163435.png]] 1478 | 1479 | **以服务器为目标的被动攻击** 1480 | 1481 | 被动攻击(passive attack)是指利用圈套策略执行攻击代码的攻击模式。在被动攻击过程中,攻击者不直接对目标 Web 应用访 问发起攻击。 1482 | 1483 | 被动攻击通常的攻击模式如下所示。 1484 | 1485 | - 步骤 1: 攻击者诱使用户触发已设置好的陷阱,而陷阱会启动发送已嵌入攻击代码的 HTTP 请求。 1486 | - 步骤 2: 当用户不知不觉中招之后,**用户的浏览器或邮件客户端**就会**触发这个陷阱**。 1487 | - 步骤 3: 中招后的**用户**浏览器会把含有攻击代码的 HTTP 请求发送给作为攻击目标的 Web 应用,**运行攻击代码**。 1488 | - 步骤 4: 执行完攻击代码,存在安全漏洞的 Web 应用会成为攻击者的跳板,可能导致用户所持的 **Cookie** 等**个人信息被窃取**, 登录状态中的用户权限遭恶意滥用等后果。 1489 | 1490 | 被动攻击模式中具有代表性的攻击是跨站脚本攻击和跨站点请求伪造。 1491 | 1492 | ![[Pasted image 20220920163717.png]] 1493 | 1494 | **利用用户的身份攻击企业内部网络** 1495 | 1496 | 利用被动攻击, 可发起对原本从互联网上无法直接访问的企业内网等网络的攻击。只要用户踏入攻击者预先设好的陷阱,在用户能够访问到的网络范围内,即使是企业内网也同样会受到攻击。 1497 | 1498 | 很多企业内网依然可以连接到互联网上,访问 Web 网站,或接收互联网发来的邮件。这样就可能给攻击者以可乘之机,诱导用 户触发陷阱后对企业内网发动攻击。 1499 | 1500 | ![[Pasted image 20220920192003.png]] 1501 | 1502 | ### 10.2 因输出值转义不完全引发的安全漏洞 1503 | 1504 | 实施 Web 应用的安全对策可大致分为以下两部分。 1505 | 1506 | - 客户端的验证 1507 | - Web 应用端 (服务器端) 的验证 1508 | - 输入值验证 1509 | - 输出值转义 1510 | 1511 | ![[Pasted image 20220920192058.png]] 1512 | 1513 | 多数情况下采用 **JavaScript** 在客户端验证数据。可是在客户端允许**篡改数据**或**关闭 JavaScript**,不适合将 JavaScript 验证作为安全的防范对策。保留客户端验证只是为了尽早地辨识输入错误,起到**提高 UI 体验**的作用。 1514 | 1515 | Web 应用端的输入值验证按 Web 应用内的处理则有可能被误认为是具有攻击性意义的代码。输入值验证通常是指检查是否是符合系统业务逻辑的数值或检查字符编码等预防对策。 1516 | 1517 | 从数据库或文件系统、HTML、邮件等输出 Web 应用处理的数据之际,针对输出做值转义处理是一项至关重要的安全策略。当输出值转义不完全时,会因触发攻击者传入的攻击代码,而给输出对象带来损害。 1518 | 1519 | **10.2.1 跨站脚本攻击** 1520 | 1521 | 跨站脚本攻击(Cross-Site Scripting,XSS)是指通过存在安全漏洞的 Web 网站注册用户的浏览器内运行非法的 **HTML 标签**或 **JavaScript** 进行的一种攻击。动态创建的 HTML部分有可能隐藏着安全漏洞。就这样,攻击者编写脚本设下陷阱,用户在自己的浏览器上运行时,一 不小心就会受到被动攻击。 1522 | 1523 | 跨站脚本可能造成以下影响 1524 | 1525 | - 利用虚假输入表单骗取用户个人信息 (钓鱼) 1526 | - 利用脚本窃取用户 Cookie 值, 被害者在不知情的情况下, 帮助攻击者发送恶意请求 1527 | - 显示伪造的文章或图片 1528 | 1529 | **跨站脚本攻击案例** 1530 | 1531 | 在动态生成 HTML 处发生 1532 | 1533 | 下面以编辑个人信息页面为例讲解跨站脚本攻击. 下方界面显示了用户输入的个人信息内容 1534 | 1535 | ![[Pasted image 20220920193018.png]] 1536 | 1537 | 确认界面按原样在编辑界面输入的字符串. 此处输入带有山口一郎这样的 HTML 标签的字符串 1538 | 1539 | ![[Pasted image 20220920193059.png]] 1540 | 1541 | 此时的确认界面上, 浏览器会把用户输入的 `` 解析成 html 标签, 然后显示删除线爱你 1542 | 1543 | 删除线显示出来并不会造成什么后果, 但如果换成 script 标签, 就有可能被利用而设置 XSS 陷阱 1544 | 1545 | 跨站脚本攻击属于被动攻击模式, 需要受害者点击陷阱才会触发. 1546 | 1547 | 下面是网站拖过地址栏 URI 的查询字段指定 ID, 即相当于在表单内自动填写字符串的功能. 而就在这地方, 隐藏着可执行跨站脚本攻击的漏洞 1548 | 1549 | ![[Pasted image 20220920193252.png]] 1550 | 1551 | 充分熟知此处漏洞特点的攻击者,于是就创建了下面这段嵌入恶 意代码的 URL。并隐藏植入事先准备好的欺诈邮件中或 Web 页 面内,诱使用户去点击该 URL。 1552 | 1553 | `http://example.jp/login?ID=">` 1554 | 1555 | 用户打开浏览器页面后, 即执行 `` 弹出窗口 1556 | 1557 | 正常访问时的 HTML 源代码 1558 | 1559 | ```html 1560 | 1563 |
1564 |
1565 | ID 1566 |
1567 | ``` 1568 | 1569 | 访问恶意链接时的 HTML 源代码 1570 | 1571 | ```html 1572 |