Skip to content

image.png

HTTPS握手过程?

很早以前我画过一张图,如上,大家可以根据图示,了解具体过程。

  1. 客服端发送 Client Hello 消息,
    1. 包含TSL协议版本
    2. 客户端随机数 Client Random
    3. 客户端支持的加密套件列表, 很多 Cipher Suites
  2. 服务端收到消息后,发送一个 Server Hello,返回协商的结果
    1. 数字证书(包含公钥)
    2. 服务端生成的随机数 Server Random
    3. 服务端选择的加密套件(方法)Cipher Suite
  3. 客服端对证书合法性进行验证,通过后生成一个新的随机数 pre-master secret
  4. 客户端用证书中的公钥pre-master secret加密,发送到服务端,服务端接收后通过私钥解密出 pre-master
  5. 三次握手此时完成,之后客户端和服务器都会根据这三个随机数,生成一个随机对称秘钥 master-secret,以后的对话过程使用这个秘钥来进行加密传输

刨根问底系列之https详细握手过程 - 掘金 - 可参考,good!

HTTP Question?

HTTP/1.0 HTTP/1.1 HTTP/2.0 的主要区别

HTTP/1.0

每进行一次 HTTP 通信,都需要经历建立 TCP 连接、传输 HTTP 数据和断开 TCP 连接三个阶段

HTTP/1.1

http/1.1中的一个tcp链接同时只能发起一个http请求!(前面请求延迟会导致后面请求阻塞,即队头阻塞)浏览器中对于同一个域名,默认允许同时建立 6 个 TCP 持久连接

  1. HTTP/1.1 引入持久连接,默认开启,Connection: keep-alive
  2. 为了解决队头阻塞问题,引入不成熟的管线化,将多个 HTTP 请求整批提交给服务器的技术,虽然可以整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器的请求。

HTTP/1.1的缺陷

  1. TCP慢启动
  2. 同时开启多条TCP连接竞争带宽
  3. HTTP/1.1队头阻塞问题(基于管道机制,同一个TCP连接,所有HTTP请求按照顺序进行,排队处理)

HTTP/2.0

  1. 引入二进制分帧层,实现HTTP的多路复用: 当个TCP连接可以同时处理多个HTTP请求和响应。数据经过二进制分帧层处理之后,会被转换为一个个带有请求 流 ID 编号的帧。这些帧可以交织在一起,顺序也可以被打乱,相同ID的帧最后会重新组装成完整的请求和响应
    1. 流 Stream 是独立的,双向的数据传输通道,相当于是高速公路,每个流有唯一标志id,一个TCP连接中可以有多个流并行传输。
    2. 帧 Frame 是HTTP/2.0 数据传输的最基本单位,相当于是公路上跑的车辆,每个车辆(帧)都有明确的目的地(流)
  2. 可以设置请求优先级
  3. 头部压缩
  4. 服务器推送

HTTP/1.1 长连接 和 HTTP/2.0 多路复用的区别

  1. HTTP /1.1 同一个时间一个TCP连接只能处理一个请求,采用一问一答的形式,上一个请求响应后才能处理下一个请求

  2. HTTP /2.0 同域名下所有的通信都在单个TCP连接上完成。在 HTTP/2 中,多路复用通过使用一个单一的 TCP 连接,并将请求和响应分割成独立的帧来实现。每个帧都有一个流 ID,用于识别所属的请求和响应,这样,这些帧都可以同时在一个 TCP 连接上进行传输

HTTP/2.0中流的是什么?

流(Stream)流是独立的、双向的数据传输通道。即可以向两个方向发送或接收数据。每个流都有唯一的标识符,这样可以让同一个 TCP 连接中的多个流独立地进行数据传输。流之间是并行的,可以同时进行数据的发送和接收。


帧(Frame):帧则是 HTTP/2 数据传输的最基本单位。无论是请求还是响应的 HTTP 报文,都会被分割为多个帧,并在一个流的上下文中进行发送。每个帧都包含一个帧头,其中帧头标明了该帧属于哪个流(通过流标识符),以及其他一些控制信息。数据帧也包含一段数据。 总的来看,流就像是高速公路,帧则是在公路上跑的车辆,每个车辆(帧)都有明确的目的地(流)。因为这些车辆可以并行行驶,所以通信效率大大提高。每个流(公路)上运输的帧(车辆)可以被服务器端按照接收顺序重新组装成完整的 HTTP 请求或响应。这就是 HTTP/2 的多路复用特性。 image.pngimage.png流跟流之间的顺序可以是错乱的,但是流里面的帧的顺序是不可以错乱的


HTTP 和 HTTPS 主要区别

  1. HTTP 是明文传输,不安全的,HTTPS 是加密传输,更加安全。
  2. HTTP 默认端口 80, HTTPS 默认端口 443,HTTPS 浏览器上会显示安全锁。
  3. HTTP 不用认证证书 ,HTTPS 需要认证证书
  4. HTTP 是连接简单,无状态的,HTTPS = HTTP + SSL/ TLS
  5. HTTPS对搜索引擎更友好,利于 SEO;谷歌、百度优先索引 HTTPS 网页

  1. 协议安全性:HTTP 是超文本传输协议(Hypertext Transfer Protocol),信息是明文传输,它本身不具备任何安全性。HTTPS 则是具有安全性的 SSL 加密传输协议,可以防止数据在传输过程中被窃取或篡改,保证了数据的完整性和隐私性。
  2. 传输端口:HTTP 的默认端口号是80,HTTPS 的默认端口号是443。
  3. URL显示:HTTPS 在浏览器的地址栏会显示一个带锁的小图标,也会在 URL 开头显示 https:// ,表示当前连接已经是加密连接。
  4. 证书认证:HTTP 不需要 CA(数字证书认证机构)的数字证书。HTTPS 需要⽤用 CA 证书来进行身份验证。只有当证书中信息和访客所看到网址的信息一致,用户的浏览器才会接受证书。如果证书不被信任,浏览器会给出警告,用户可以选择是否继续。
  5. 性能开销:由于 HTTPS 需要进行数据加密处理,因此它的网络性能会略低于 HTTP。

总的来说,HTTPS 确实对服务器的资源消耗稍大一些,但它的信息安全性大大超过了 HTTP,尤其对于处理敏感信息(如信用卡信息,个人身份信息等)的网站,HTTPS 的使用是必不可少的。

HTTP常见状态码

  • 101 Switching Protocols
    • 在HTTP升级为WebSocket的时候,如果服务器同意变更,就会发送状态码 101
  • 103 Early Hints:
    • 此状态代码主要用于与 Link 链接头一起使用,以允许用户代理在服务器准备响应阶段时开始预加载 preloading 资源
typescript
 <link rel="preload" href="style.css" as="style" />
  • 301 :永久重定向。场景是使用域名跳转,新的URL在响应中给出
  • 302:
    • HTTP/1.0 中的状态码,临时重定向。表示请求的资源临时移动到了由Location头部指定的URL上。
    • 场景是未登陆的用户跳转登录;即使原始请求是 POST,浏览器也会默认使用get方式重新发出请求,会导致第一次以post请求的参数丢失;(才衍生出了307状态码)
  • 303 see other:
    • 强制浏览器将请求方法从POST改到GET;
    • 表示服务器已处理完客户端的请求,但客户端应该采用 GET 方法去获取另一个由 Location 响应头部字段指定的 URL。常用于 POST、PUT 请求后将用户重定向到一个新的页面,常见的例子如提交表单后重定向到一个确认页或状态条等。
  • 304 Not Modified: 资源未修改,可使用缓存(协商缓存)
  • 307 Temporary Redirect:
    • 307 和 302 一样是临时重定向,唯一的区别在于,307 状态码不允许浏览器将原本为 POST 的请求重定向到 GET 请求上
    • 但用户代理 不能 更改所使用的 HTTP 方法:如果在第一个请求中使用了 POST,则在第二个请求中必须使用 POST
  • 308 Permanent Redirect:
    • 308 和 301 一样是永久重定向,唯一的区别在于,308 状态码不允许浏览器将原本为 POST 的请求重定向到 GET 请求上
  • 400 Bad Request
    • 客户端错误(例如,错误的请求语法、无效的请求消息帧或欺骗性的请求路由),服务器无法或不会处理请求
  • 401 Unauthorized
    • 未授权,要求客户端进行身份验证才能获得请求的响应
  • 403 Forbidden
    • 客户端没有访问内容的权限;也就是说,它是未经授权的,因此服务器拒绝提供请求的资源。与 401 Unauthorized 不同,服务器知道客户端的身份
  • 404 Not Found
    • 服务器找不到请求的资源。在浏览器中,这意味着无法识别 URL。在 API 中,这也可能意味着端点有效,但资源本身不存在。
  • 405 Method Not Allowed
    • 请求方法不允许
  • 500 Internal Server Error
    • 服务器错误
  • 503 Service Unavailable
    • 服务不可用
    • 服务器没有准备好处理请求。常见原因是服务器因维护或重载而停机。

详细说说103状态码

  • 正常情况下,我们需要等待 HTML 页面的返回后,才可以知道下一步需要去加载哪些 JS、CSS文件,这中间有一段的等待时间就被浪费掉了;这尤其在SSR项目中尤为明显;
  • HTTP 103 状态码可以返回一个初步的 HTTP 响应,浏览器可以使用这些提示来预连接,并在等待资源响应的同时请求子资源。
  • 它在 SSR 项目里面会非常有用;在SPA项目里面,大部分的逻辑都在客户端,HTML 很小,这时候我们只需要用常规的preload、preconnect之类的手段就可以了;

在发送103状态码的同时,服务器会在响应头部中包含一些有用的信息,例如预加载资源的 Link 头部。也就是说,即使完整的响应尚未准备就绪,客户端也可以开始预加载必要的资源,从而优化用户体验,减少加载时间。

103状态码 和 HTTP2 服务端推送的

  1. 103 Early Hints 状态码:
  • 服务器在开始处理请求,但尚未准备好完整响应时发送。
  • 可提前在响应头部发送有用的信息,比如预加载资源的链接。
  • 客户端可开始预加载这些资源以优化性能,无需等待完整响应。

  1. HTTP/2 服务器推送:
  • 功能是服务器主动将可能用到的资源推送给客户端。
  • 客户端在渲染页面时无需再向服务器请求这些资源,降低加载延迟。
  • 如果推送的资源在客户端已有缓存,可能浪费资源。

  1. 区别:
  • 103 状态码是建议客户端预加载资源,客户端可以选择是否预加载。
  • 服务器推送则是直接将资源发送给客户端,但有可能导致资源浪费。

TCP 和 UDP 的区别

  1. TCP 是面向连接的,UDP 是无连接的即发送数据前不需要先建立链接
  2. TCP 是可靠传输,保证数据正确且有序;UDP是不可靠的,可能丢包或乱序
  3. TCP 是面向字节流,UDP 面向报文,并且网络出现拥塞不会使得发送速率降低
  4. TCP 首部开销大,最小20字节最大60字节,而 UDP 首部开销小,仅8字节
  5. TCP 只能是 1 对 1 的,UDP 支持 1 对 1,1 对多;

TCP如何保证数据的可靠性

TCP (Transmission Control Protocol) 是一种面向连接的、可靠的、基于字节流的传输层通信协议。它通过以下几种机制来确保数据的可靠性:

  • 确认应答(Acknowledgement):TCP 提供了确认应答机制。每当发送出去一个数据包,发送者都会等待接收者的确认(ACK)。如果在指定的时间内未收到确认,发送者会假设该数据包已丢失,并会进行重传。
  • 序列号(Sequencing):TCP 在发送数据包时,会对每一个数据包分配一个序列号。接收者在收到数据包后,会根据这个序列号对数据包进行排序。这样即使网络情况导致数据包到达的顺序与发送顺序不一致,也能够确保数据包在接收端被正确顺序地处理。
  • 差错检测:TCP 段的头部包含校验和。这使得接收端可以检查数据的一致性。如果发现数据传输中出现差错(比如由于网络噪声导致的数据更改),那么接收端将抛弃这个数据包,并请求重传。
  • 流量控制:流量控制是通过滑动窗口机制实现的。滑动窗口的大小可变,通常与接收方的缓冲区大小以及网络拥塞情况有关。这样可以防止发送者发送速率过快导致接收者无法接收,造成数据丢失。
  • 拥塞控制:为防止过多的数据注入到网络中,从而引起网络的性能降低,TCP 还必须提供拥塞控制机制。

XSS

XSS (跨站脚本攻击):

XSS Cross-Site Scripting,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie等。


常见的注入方式

  1. input输入框 内嵌 script标签
  2. 在标签href,src等属性上,包含javascript:

分类

存储型 XSS

存储型的 XSS 将脚本存储到了服务端的数据库,然后在客户端执行这些脚本,从而达到攻击的效果。 常见的场景就是评论区提交一段脚本代码,如果前后端没有做好转义,存储到数据库后,在客户端渲染时直接执行;

反射型 XSS

  • 反射形 XSS 攻击指的是恶意脚本作为请求URL的参数,经过服务器解析响应,拼接在 HTML 中传回给客户端,然后浏览器解析执行恶意脚本。
  • 和存储型不一样的是,服务器并不会存储这些XSS恶意脚本

DOM型 XSS

  • 文档形的 XSS 攻击其实也是恶意脚本被作为请求URL的参数,浏览器解析后作为脚本执行。
  • 反射形的区别在于:由前端JS取出 URL 中的恶意代码并执行

DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞 前端面试查漏补缺--(七) XSS攻击与CSRF攻击 - 掘金XSS 和 CSRF 攻击详解 - 掘金

XSS的防御

  1. 最普遍的做法就是转义和过滤:对引号,尖括号,斜杠进行转义,让代码在html解析的过程中无法执行;过滤就是把 script标签给删除;
  2. 利用HttpOnly
    1. cookie 设置 httponly 后,会禁止 javascript 脚本来访问 cookie,这样,XSS攻击之后也无法获取用户的cookie
  3. 其次就是使用 CSP:CSP也就是浏览器内容安全策略,只允许加载指定域的脚本和样式,相当于白名单。

CSRF

基本概念

  • CSRF(跨站请求伪造) 就是黑客诱导用户跳转恶意网站,然乎利用用户的登录态发起恶意请求;
  • 原理就是http请求会自动携带 Cookie,而且是 HTTP 请求目标域名的 Cookie
  • 攻击者并不能拿到Cookie,也看不到Cookie内容。

攻击流程

一个典型的CSRF攻击有着如下的流程:

  • 受害者登录a.com,并保留了登录凭证(Cookie)。
  • 攻击者引诱受害者访问了b.com。
  • b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会携带a.com的cookie
  • a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
  • a.com以受害者的名义执行了act=xx。
  • 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作。

防范措施

  1. 验证HTTP请求头的RefererOrigin,只接收同源站点的请求。阻止第三方网站请求接口,但是它可以被ajax自定义请求头的方式被伪造
  2. Chrome Cookie 的SameSite属性,设置为strict。该属性可以让 Cookie 在跨站请求时不会被发送,从而抵御 CSRF 攻击;它有Strict(浏览器将只发送相同站点(完全一致)请求的 Cookie)、Lax(第三方get方法可以携带Cookie) 和 None (任何情况下都会发送 Cookie)三个值
  3. 终极方案:CSRF Token
    1. 客户端向服务端请求token,然后在所有的请求中带上

Chrome80 版本的 CSRF 例子

讲到 CSRF 的 cookie,不得不提一下 Chrome 80 版本的的一个默认设置;Chrome 80 版本将 SameSite 的值设置为了 Lax;这导致之前公司有一些业务产生了跨域;

XSS 和 CSRF的原理区别

  • CSRF 是利用 网站A 本身的漏洞,去请求 网站A 的 api。而 XSS 是向网站A 注入 JS代码,然后执行 JS 里的代码,篡改网站A的内容。
  • CSRF仅仅是利用了http携带cookie的特性进行攻击的,但是无法得到被攻击站点的cookie。这个和XSS不同,XSS一般是直接通过拿到Cookie等信息进行攻击的

SQL注入

概念

就是通过把SQL命令插入到Web表单、页面请求的查询字符串里面提交到服务器,最终达到欺骗服务器执行恶意的SQL命令。

原理

服务端在执行sql操作时,没有对用户的输入进行验证,直接将其拼接到了SQL语句中。

比如登录的场景,前端输入用户名和密码,后端查询SQL语句可能是这么拼接的

sql
string sql = "select * from users where username = '" + username + "' and password = '" + password + "'";

而sql中会将#以及--之后的字符串当做注释处理。


在正常使用的情况下,比如:用户名为 "Bob",密码为 "123456",SQL语句就是

sql
select * from users where username = 'Bob' and password = '123456'

攻击者在认识到 SQL 注入的风险后,可能会在用户名或密码栏输入以下字符 Bob'; drop table users; --, SQL语句就会被解释为

sql
select * from users where username = 'Bob'; drop table users; --' and password = ''

第一条正常查询用户信息,第二条是删除整个用户表,后面的 -- 是注释符,注释掉了后面的内容,防止语句报错。如果网站没有防护措施和错误处理机制,这条语句将直接被数据库执行。

防范

  1. 输入检查:永远不要信任用户的输入,对所有的用户输入进行严格的过滤和检查。应尽可能去除输入中的特殊字符, 同时限制输入类型,格式和长度。
  2. 限制数据库权限:永远不要使用管理员权限的数据库连接,避免攻击者对数据库有过多的控制
  3. 不要把机密信息明文存放,加密或者hash掉密码和敏感信息
  4. 使用查询化参数:可以确保用户输入被当做字符串处理,而不是SQL语句的一部分。

点击劫持

概念

点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中,并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击

防范

使用 X-Frame-Options HTTP 响应头


这是一种 HTTP 响应头,能够声明网页不允许通过 <frame><iframe> 或者 <object> 的方式被其他页面嵌入。这对防止点击劫持非常有用,因为大多数点击劫持攻击都是通过嵌入页面的方式进行的。 这个 HTTP 响应头 就是为了防御用iframe 嵌套的点击劫持攻击。


该响应头有三个值可选,分别是

  • DENY,表示页面不允许通过 iframe 的方式展示
  • SAMEORIGIN,表示页面可以在相同域名下通过 iframe 的方式展示
  • ALLOW-FROM,表示页面可以在指定来源的 iframe 中展示

资源预加载 & 预连接

prefetch

prefetch 是一个低优先级的资源加载提示,其利用浏览器空闲时间来下载用户在不久的将来可能访问的资源(比如下一个页面)

html
<link href="/js/xx.js" rel="prefetch">

preload

指明哪些资源是在页面加载完成后就需要的,这一机制使得指定资源可以更早的得到加载并可用,且更不易阻塞页面的初步渲染,进而提升性能。

html
<link rel="preload" href="style.css" as="style" />
<link rel="preload" href="main.js" as="script" />

需要用as指定资源类型,如 font 字体文件, style 样式表


  • preload、prefetch仅仅是加载资源,并不会执行;

preconnect

在我们下载资源时,要先建立链接,然后才能下载资源。 建立连接会涉及到DNS解析,TCP握手,TSL握手等,使用了这个参数后,浏览器会提前做好连接工作,从而减少请求资源时建立连接所需的时间

html
<link rel="preconnect" href="https://example.com">

dns-prefetch 和 preconnect 区别

dns-prefetch:dns-prefetch 是最轻量级的优化方式,它告诉浏览器预先进行 DNS 解析,将域名解析为 IP 地址,这样在真正需要从该域名下载资源时,可以省去 DNS 解析的时间


preconnect 包括 dns-prefetch 的全部工作,同时,它还会预先进行 TCP 握手和建立 TLS 连接。当需要从某个源下载资源时,如果已经预先建立了连接,那么可以更快的开始数据的下载。