Web工作机制
网页就是我们可以通过浏览器上网看到的精美页面,一般都是经过浏览器渲染过的.html页面,HTML语言在浏览器中渲染。其中包含了CSS、JavaScript等前端技术。只要是通过浏览器访问的Web页面都是HTML页面。
网站多个网页的集合就是网站。
Web服务器,也叫Web容器,主要是提供Web服务,也就是常说的httpd服务,常见的Web容器有:Apache、IIS、Nginx等。
静态的网页
静态的网页,都是一些.html文件,是纯文本文件。这些文件中包含html代码。
HTML(HyperText Markup Language,超文本标记语言),浏览器会通过渲染引擎解释执行HTML 语言。
HTML 语言对于Web 容器来讲就是纯文本字符串。Web 服务器只负责将HTML 语言或其他字符串(字节流)从服务器传输给浏览器。 静态的页面,只能将信息从Web 服务器传递到浏览器、客户端、用户。
中间件服务器
以上这种,只能单向地给用户展示信息。随着Web 的发展,信息要双向流动,产生了交互的需求,也就是动态网页的概念。
所谓动态就是利用Flash、PHP、ASP、JAVA、JavaScript 等技术在网页中嵌入一些可运行的脚本,用户浏览器在解释页面时,遇到脚本就启动运行它。脚本的使用让Web 服务模式有了双向交流的能力,
Web 服务模式也可以像传统软件一样进行各种事务处理,如编辑文件、利息计算、提交表单等,Web 架构的适用面大大扩展。
这些脚本可以嵌入在页面中,如JS等。也可以以文件的形式单独存放在Web 服务器的目录里,如.asp 、.php 、jsp 文件等。我们看到的虽然是纯文本 HTML,它后端脚本的输出(运行结果)。
这样功能性的脚本越来越多,形成常用的工具包,单独管理,Web 业务开发时,直接使用就可以了,这就是中间件服务器,它实际上是Web 服务器处理能力的扩展。
数据库的出现
静态网页与脚本都是事前设计好的,一般不经常改动,但网站上很多内容需要经常的更新,如新闻、博客文章、互动游戏等,这些变动的数据放在静态的程序中显然不适合,传统的办法是数据与程序分离,采用专业的数据库。
Web 开发者在Web 服务器后边增加了一个数据库服务器,这些经常变化的数据存进数据库,可以随时更新。当用户请求页面时,脚本根据用户请求的页面,涉及到动态数据的地方,利用SQL 数据库语言,从数据中读取最新的数据,生成“完整”页面,最后送给用户。
HTTP 协议
在整个Web 工作机制中有一个重要的问题:通信。客户端是用户和浏览器,服务端是Web 容器+中间件+数据库。也就是说,客户端与服务器端要进行通信,得准守同一个标准。这个标准就是HTTP 协议。协议就是标准,规则,规范,要求。
HTTP 协议概述
HTTP(HyperText Transfer Protocol,超文本传输协议)是浏览器(Browser)与Web 服务器(Web Server)之间的通信协议,是传递消息的规范和要求。
HTTP 协议是1990 年提出的,当前版本1.1 。HTTP 是用来将HTML 文档从Web 服务器传输到Web 浏览器。即使访问PHP 文件,浏览器端接收到并不是PHP 文件的源代码,而是PHP 脚本的运行结果,这个结果就是HTML 文档。
HTTP 是一个请求和响应的协议。客户端发出请求,服务器端对请求给出回应。(一般情况下)就像学生问老师问题一样,学生问一个,老师解答一个。
HTTP 使用可靠的TCP 连接,默认端口80。明文传输漏洞,使用加强版的HTTP 协议 - HTTPS,在HTTP 的基础上加了一个安全套接字层SSL ,使用默认端口443 。HTTPS 也会有一些安全性问题,比如HTTPS 降级,“心脏滴血” 漏洞等。
HTTP 协议特点
- 支持浏览器/服务器模式(B/S)。
- 简单快速:浏览器向服务器提出请求时,只需要传送请求方法和请求路径。
- 灵活:HTTP 允许传输任意类型的数据对象
文件后缀名 | 文件类型 | MIME 类型 |
---|---|---|
.html | 纯文本 | text/html |
.jpg | 图片 | image/jpeg |
.mp3 | 音频 | audio/mpeg |
- HTTP 协议是无状态的协议。
URL
统一资源定位符(网址,全球唯一),用来告诉Web 容器,浏览器所请求资源(文件)的路径。例如
http://10.9.65.213/cms/show.php?id=35
ftp://fptuser:ftpuser@10.9.65.212
schema://login:password@address:port/path/to/resource/?query_string#fragment
schema | 😕/ | login | : | password | @ | address | : | port | /path/to/resource/ | ? | query_string | # | fragment |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
协议 | 😕/ | 用户名 | : | 密码 | @ | 域名 IP 地址 | : | 端口号 | 请求资源的路径 | ? | 查询字符串 | # | 锚点 |
http | 😕/ | - | - | - | - | 10.10.10.1 | - | - | /cms/show.php | ? | id=35 | - | - |
锚点:在<a>
标签中实现页面内定位的,#
后面的内容是不会传递服务器的。
URL 编码:(浏览器或服务器)URL 所允许出现的字符是有限制的。URL 中从path 开始只允许出现A-Za-z0-9,半角减号(-),下划线(_),句点(.),波浪号(~)。其他字符均会被URL 编码(编码规则)。
符号 | URL 编码 |
---|---|
# | %23 |
空格 | %20 |
- encode 编码,decode 解码
- URL 编码是一种编码规则,它会将所有字符进行URL 编码。
- 浏览器或服务器中对URL 的要求,特殊字符进行URL 编码。
- URL 中的空格可用
%20
,也可以用+
来代替。
http://10.9.65.213/cms/show.php?id=34 and 1=1
http://10.9.65.213/cms/show.php?id=34%20and%201=1
http://10.9.65.213/cms/show.php?id=34+and+1=1
报文分析工具
- 管理控制台(F12),浏览器自带工具
- Wireshark,可以抓取每层数据包
- fiddler,可以非常方便抓取HTTPS 的数据包
…
HTTP 工作模式
REQUEST
请求报文,如下:
GET /cms/show.php?id=34 HTTP/1.1
Host: 10.9.65.213
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
HTTP 请求由请求行、请求头、请求正文三个部分组成。
请求行
HTTP 报文的第一行,由空格字符分成三部分(空格、回车和换行符不能随便出现)。
实例 | 说明 | |
---|---|---|
第一段 | GET | 请求方法 |
第二段 | /cms/show.php?id=34 | 资源的路径 |
第三段 | HTTP/1.1 | 协议/版本 |
常见请求方法如下:
请求方法 | 说明 |
---|---|
GET | 通常用于请求服务器发送的某个资源。 |
POST | 通常用于表单提交或文件上传等功能 |
HEAD | 与GET 方法类似,但在服务器响应中只返回首部(头部) |
PUT | PUT 方法会向服务器写入文档 |
DELETE | 请求服务器删除指定的资源 |
TRACE | 回显浏览器的请求 |
OPTIONS | 用来测试服务器所支持的方法 |
请求头
从请求报文第二行开始到第一个空行为止之间的内容。其中包含很多字段:
主要字段 | 含义 |
---|---|
Host | 主要用于指定被请求资源的服务器地址和端口号 |
User-Agent | 客户端浏览器信息,浏览器指纹 |
Referer | 包含一个URL,代表当前URL的上一个URL |
Cookie | 记录请求者的身份认证信息,身份证 |
Accept-Charset | 用于指定浏览器接收的字符集 |
Content-Type | 用于向接收方(浏览器或服务器)指示实体的介质类型(数据类型,MIME) |
Content-Length | 用于指明实体正文的长度,以字节方式存储的十进制数字来表示 |
Last-Modified | 用于指示资源的最后修改时间 |
请求正文
第一个空行开始以后的所有内容。
POST /cms/admin/login.action.php HTTP/1.1
Host: 10.9.65.213
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 52
Origin: http://10.9.65.213
Connection: close
Referer: http://10.9.65.213/cms/admin/login.php
Upgrade-Insecure-Requests: 1
username=admin&image.x=39&image.y=21&password=123456
常见传参方式
GET 传参
- 向服务器提交的参数在URL 中,
http://10.9.65.213/cms/show.php?id=38
。?id=33 就是通过GET 方式向服务器提交的参数。通过GET 向服务器传递多个参数用& 连接?name=AJEST&pass=123456
,以此类推即可。
POST 传参 - 向服务器提交的参数在请求正文中,如以上POST 数据包所示,向服务器提交了4个参数,分别为:
username=admin
image.x=39
image.y=21
password=123456
有人所,POST 传参“不可见”的,所以比GET 传参更安全?
RESPONSE
响应报文,如下:
HTTP/1.1 302 Found
Date: Mon, 08 Mar 2021 17:42:27 GMT
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45
X-Powered-By: PHP/5.4.45
Set-Cookie: PHPSESSID=dfhp8mkjoem48h48pvl926ugh4; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: username=admin; expires=Tue, 08-Mar-2022 17:42:28 GMT
Set-Cookie: userid=1
Location: index.php
Content-Length: 318
Connection: close
Content-Type: text/html; charset=utf-8
<br />
<b>Notice</b>: Use of undefined constant username - assumed 'username' in <b>D:\phpStudy_2016\WWW\cms\admin\login.action.php</b> on line <b>16</b><br />
<br />
<b>Notice</b>: Use of undefined constant userid - assumed 'userid' in <b>D:\phpStudy_2016\WWW\cms\admin\login.action.php</b> on line <b>22</b><br />
响应报文由状态行(响应行) 、响应头 、响应正文 三部分组成。
状态行
响应报文的第一行
示例 | 解释 | |
---|---|---|
第一个字段 | HTTP/1.1 | 协议/版本 |
第二个字段 | 302 | 响应状态码 |
第三个字段 | Found | 描述短语 |
常见状态码,如下:
状态代码 | 类型 | 常见状态码 |
---|---|---|
1XX | 信息性状态码 | – |
2XX | 成功状态码 | 200|201… |
3XX | 重定向状态码 | 302|304… |
4XX | 客户端错误状态码 | 404|403… |
5XX | 服务器错误状态码 | 500 |
响应头
响应报文第二行开始到第一个空行为止的所有内容,其中包含了关于HTTP 响应的重要字段。
字段 | 含义 |
---|---|
Data | 时间和日期 |
Server | Web 服务器指纹 |
Last-Modified | 服务器通过这个头信息告诉浏览器,资源的最后修改时间 |
Content-Length | 响应正文的长度 |
Content-Type | 响应正文的类型 |
Set-Cookie | 服务器向浏览器端写入Cookie 信息 |
Location | 重定向目标页面 |
Refresh | 服务器通过Refresh 头告诉浏览器定时刷新浏览器 |
响应正文
响应报文从第一个空行开始到最后的所有内容。服务器返回资源的内容,即浏览器接收到的HTML 代码。
Web 会话简述
会话就是类似于浏览商品、加入购物车到支付,这样一个完整的业务流程,要求有一个账号始终保持登录状态,也就是说这个账号完成了购买商品的业务。
HTTP 协议本身是无状态的协议,也就是说,HTTP 协议不会记录会话状态,不同的请求之间是没有任何联系的。很多种情况,浏览器与服务器之间的会话不是一个动作(请求)就完成了的。
希望在浏览器与服务器之间的这个交互的会话期间内,服务器能够保持对浏览器会话的识别,也就是保持HTTP 的状态性。
Cookie 应运而生
Cookie(Cookies) 就是指网站为了辨别用户身份,进行会话跟踪而存储在用户本地终端(浏览器)上一小段文本(数据,通常进行加密的)。
Cookie 机制提供事务管理的功能,为服务器提供会话状态管理。例如:购物车可以为每个用户实现统计;实现授权策略等。
Cookie 是服务器向浏览器写入的一段文本(在响应报文的Set-Cookie
字段中),并存储在浏览器中。另外,浏览器在访问该网站时会自动发送Cookie(在请求报文的Cookie
字段中),如果服务器识别这个自动发送的Cookie 信息,也就是说,服务器识别了会话。
浏览器在访问网站的时候,会自动携带与该网站相关联的Cookie 信息。
固定会话攻击
窃取
alert(document.cookie)
Cookie 信息:
username=admin; userid=1; PHPSESSID=7sgu6k54sqtd5vebluu767dcb6
欺骗
document.cookie='username=admin';
document.cookie='userid=1';
document.cookie='PHPSESSID=7sgu6k54sqtd5vebluu767dcb6';