天方夜

不患人之不己知,患不知人也

  • Home
  • Archives
  • Tags
  • Categories
  • About

CSRF 原理、攻击、防御及其他

Posted on 2022-03-19   |   In 编程

CSRF 概述:

CSRF 就是 Cross Site Request Forgery,跨站请求伪造。这种攻击利用了浏览器端状态(Cookie)管理规则与服务端鉴权规则。CSRF 在攻击过程中不需要获取到用户的登录凭据,而是借用户之手发出恶意请求。

CSRF 的存在是由于 Cookie 架构的设计“非常古老”,已经有些不适应网络安全的需要。但是如下文所述,现代浏览器已经给 Cookie 规则打了很多“补丁”,安全性大大提升。实际上,现代浏览器条件下,很多“传统的” CSRF 攻击手段已经失效,但是由于网络安全的短板效应,永远不能放松警惕,只有深入理解攻击方式的来龙去脉,才能从整体上尽可能确保安全。

另一个 Web 开发者常听说的攻击方式叫 XSS(Cross Site Scripting),跨站脚本,了解它的人应该更多一些。相比而言,CSRF 攻击构造起来可以更简单,更低成本,但是攻击方式更精巧,背后的原理的也更复杂一些。更容易导致混乱的地方在于,不同的攻击方式可能混合出现。比如考虑到 UGC(User-generated content)场景下可能出现的 CSRF,就变得比典型的 CSRF 要复杂。对于整体防御思路来说,是很大的挑战。

狭义上的 CSRF 知识不难理解,但要深入理解就比较繁琐,因为网络安全的事情往往都是很多不同层面的知识互相关联,CSRF 尤其如此。

与 CSRF 关系密切的领域:

  1. 网络协议
  2. 浏览器特性
  3. API设计
  4. 认证方式
  5. 密码学
  6. 社会工程

可见,CSRF 本身不复杂,甚至看起来比较简单,但是每个相关的领域,都是个非常深的坑,本文会尽可能设计到足够广的领域。阅读本文之后,会发现每个领域的知识都有很多可以继续探索的地方。

Read more »

JavaScript await 进阶指南

Posted on 2022-03-11   |   In 编程

如果了解 Promise 以及 async/await 的基本使用,就已经足以写出异步流程控制代码,但还有一些略微反直觉、容易记错的点,这些点基本都与 await 有关,本文是对此的一些整理和解析(示例代码大部分来自 MDN,对这些示例代码的解析并非照搬 MDN 原文)。

Promise 正常处理完成

await 关键字用于在 async function 的局部上下文中挂起(交出局部程序的执行权),直至右边的 Promise 返回。

最常规的情况是,await 操作符右边是一个 Promise,由于 await 将异步函数上下文中的执行权切换到了这个 Promise,这个 Promise 正常处理完成并返回其处理结果后,异步函数后续的语句才开始执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}

async function f1() {
var x = await resolveAfter2Seconds(10);
console.log(x); // 10
}

f1();
Read more »

JavaScript 中的继承:ES3、ES5 和 ES6

Posted on 2017-12-31   |   In 编程

选择一种继承方式

JavaScript 是一门动态语言,动态意味着高灵活性,而这尤其可以体现在继承上面。JavaScript 中的继承有很多种实现方式,可以分成下面四类:

  1. Mixin 模式,即属性混入,从一个或多个对象中复制属性到新的对象中
  2. 方法借用模式,即通过 call 或 apply 实现方法的重用
  3. 原型模式,使用 Object.create 方法直接以一个对象为原型创造新的对象
  4. 类模式,实际上是使用构造函数或 ES6 class

前三种有一个共同点,就是没有“类”的概念,它们在适当的场景下非常有用,不过也因为没有类,缺失了很多经典面向对象继承的要素。例如父子对象之间没有严格的传承关系,即不一定是 is-a 的关系,这决定了无法将它们直接应用在面向对象分析与设计方面,可以说它们并不是真正的继承,而是介于继承和组合之间的代码复用方案。

而第四种,类式继承,无论是使用构造函数还是 ES6 加入的 class,都能表达明确的继承关系,在需要对继承重度使用的场景下,应该使用类式继承。接下来,本文讨论的都是类式继承。

有一点需要牢记:继承是一种强耦合,应该谨慎使用。

Read more »

归并排序与快速排序的简明实现及对比

Posted on 2017-12-07   |   In 编程

前言

归并排序与快速排序是两种有实际应用的排序算法,它们有一些共同的特点,整体思路上也比较相近。本文会从更简单的一些排序算法开始,过渡到归并排序和快速排序的实现,并对它们做一些简单的对比思考和总结。在这之前,先简单介绍一下排序算法的意义。

排序算法就是将一串数据依照特定排序方式进行排列,它们在计算机科学中有大量研究以及应用。

想象一下下列场景:

  1. 从通讯录中寻找某个联系人
  2. 从一大堆文件中寻找某个文件
  3. 到了影厅之后,寻找电影票上指定的座位

如果以上情况中,联系人、文件、影厅座位这些“数据”没有按照需要的顺序组织,如何找到想要的特定“数据”呢?会非常麻烦!所以说,对于需要搜索的数据,往往应该先排个序!

热身一:选择排序

本文的示例都是数值排序,对于这个问题,最简单直观的方法是:先找出最小的、再找出第二小的、接着找出第三小的……这就是选择排序的思路。

Read more »

二叉搜索树的简明实现(ES5 & ES6)

Posted on 2017-11-24   |   In 编程

二叉树 & 二叉搜索树

二叉树(Binary Tree)是 n(n >= 0)个节点的有限集合,集合为空集时,叫作空二叉树;不为空时,由根节点及左子树、右子树组成,左子树、右子树也都是二叉树。

从这个描述,可以看出树的结构与递归之间存在密切关系,这种密切关系在树的遍历时能够得到充分体现。

二叉搜索树(Binary Search Tree),又叫二叉查找树;也称为有序二叉树(Ordered Binary Tree),排序二叉树(Sorted Binary Tree)。

这是维基百科上归纳的一些二叉搜索树的性质:

  1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  3. 任意节点的左、右子树也分别为二叉查找树;
  4. 没有键值相等的节点。

本次实现中有点不一样的地方,右节点是大于或等于父节点的。不过对示例没有影响,而且很容易改成只能大于父节点。

Read more »

想象一双结实而富有弹性的大腿:理解 Flexbox 布局

Posted on 2017-11-19   |   In 编程

Flexbox 让人困惑

有很多谈及 Flexbox 的文章,但依然有不少前端对此感到困惑。一方面,flex 相关的 CSS 属性繁多,影响到的具体效果也包含多个方面;另一方面,CSS 可以使用 Shorthand properties 风格的写法(例如最常见的 background: url(images/bg.gif) no-repeat left top;),很容易让新手弄不清具体含义。

这篇文章要讲的 Flexbox 当然还是 CSS3 规范中的弹性盒模型,不过写出前面一段,是因为我希望这篇文章可以解决那些问题——简单说,就是 Flexbox 让人困惑这样的问题。解决的方法,就是理解它。

Read more »

从上下文,到作用域(彩蛋:理解闭包)

Posted on 2017-10-14   |   In 编程

前言

近几天在编程群中的聊天,让我发现了很多人并不清楚什么是上下文(context)、什么是作用域(scope),而且纠结在其中。我当初对这两个概念也只有粗浅的理解,不过我从一开始就不怎么困惑,因为我清楚自己对这一问题的认识边界。现在,我对它们的认识也只加深了一点点。不过,群聊中小伙伴的热情鼓舞了我——很多最最初学的小伙伴,想到和思考的是很多我从没考虑过的问题,小伙伴们真是达到了“进一寸有一寸的欢喜”这一境界。见贤思齐,我决定把这一点点进步记录下来。

上下文与作用域的关系

很多人弄不清除,原因当然是既不了解上下文,也不了解作用域——我是说,几乎没有人明白上下文是什么而不明白作用域是什么,反之亦然。上下文(context)和作用域(scope)都是编译原理的知识,具体编程语言有具体的实现规则,本文关注 JavaScript 语言的实现。首先需要关注的是,这两个概念的关系非常密切,所以先了解它们的关系,有助于理解它们到底是什么。

上下文(context)和作用域(scope)的关系:

上下文是一段程序运行所需要的最小数据集合;作用域是当前上下文中,按照具体规则能够访问到的标识符(变量)的范围。

后文是对上下文和作用域更详细的解释,知道了上面指出的关系,往下阅读时就可以加深对这一关系的理解了。

Read more »

浏览器的渲染:过程与原理

Posted on 2017-09-17   |   In 编程

内容说明

本文不是关于浏览器渲染的底层原理或前端优化具体细节的讲解,而是关于浏览器对页面的渲染——这一过程的描述及其背后原理的解释。这是因为前端优化是一个非常庞大且零散的知识集合,一篇文章如果要写优化的具体方法恐怕只能做一些有限的列举。

然而,如果了解清楚浏览器的渲染过程、渲染原理,其实就掌握了指导原则。根据优化原则,可以实现出无数种具体的优化方案,各种预编译、预加载、资源合并、按需加载方案都是针对浏览器渲染习惯的优化。

关键渲染路径

提到页面渲染,有几个相关度非常高的概念,最重要的是关键渲染路径,其他几个概念都可以从它展开,下面稍作说明。

关键渲染路径(Critical Rendering Path)是指与当前用户操作有关的内容。例如用户刚刚打开一个页面,首屏的显示就是当前用户操作相关的内容,具体就是浏览器收到 HTML、CSS 和 JavaScript 等资源并对其进行处理从而渲染出 Web 页面。

了解浏览器渲染的过程与原理,很大程度上是为了优化关键渲染路径,但优化应该是针对具体问题的解决方案,所以优化没有一定之规。

Read more »

从状态模式看 JavaScript 与 Java

Posted on 2016-10-29   |   In 编程

这篇文章缘起于前几天微博上有关动态语言与静态语言的讨论,因为有几个编程高手参加,所以能看到一些特别有启发性的发言。本文主要是下面这一条微博的读后感,也是我的练习与思考。

@有个梨UGlee:如果你去看四人帮的Design Pattern里,就有State Pattern;State Pattern用类型编码State,就是我们说的问题;但是动态语言里写出来非常简单,类型语言里写得极其繁琐。

关于动态语言与静态语言,有很多比较和讨论它们的文章,但大部分都没有抓住重点。而上面一条微博,提到了一个很好的切入点,那就是「状态模式(State Pattern)」。

状态模式:蝙蝠侠/布鲁斯·韦恩

蝙蝠侠(英语:Batman)是一名出现于DC漫画的虚构超级英雄角色,由鲍勃·凯恩和比尔·芬格创作。他的名字叫 Bruce,是一位美国亿万富翁,这是他的正常身份,用于正常生活,例如进行参加宴会之类的活动。他的另一个身份是 Batman,是打击犯罪的黑暗骑士。

这是一个状态模式的好示例,我用 Java 和 JavaScript 各写了一个示例,体会体会「极其繁琐」与「非常简单」。

Read more »

宅男视角看朱鹮

Posted on 2016-10-23   |   In 杂文

阿部和重的《朱鹮》大概是目前最严肃的有关御宅族的小说了。书中的宅男鸨谷春生将现今社会的运转规则理解为“人类书写的剧本”。那么,如果这个剧本不够好,有办法改进它吗?

“正常的人”在自己的社会生活中相互约束,形成一种互相制衡的稳态。它的形成需要很长时间,可以称作“中年人的稳态”——年轻人是不适应它的。互联网的普及给了年轻人一种新的选择——成为御宅族——用宅着这种活动了解世界。

Read more »
12…4
天方夜

天方夜

天方夜的博客

36 posts
2 categories
70 tags
RSS
© 2022 天方夜
Powered by Hexo
Theme - NexT.Muse