CVE-2023-0159漏洞利用与Node.js堆栈追踪技术解析

本文详细介绍了CVE-2023-0159漏洞利用信息,并深入解析了Node.js stack-trace模块的技术实现,包括CallSite对象的API方法和堆栈追踪的实际应用场景。

stack-trace

将v8堆栈追踪获取为CallSite对象数组。

安装

1
npm install stack-trace

使用

stack-trace模块让您可以轻松捕获当前堆栈:

1
2
3
4
import { get } from 'stack-trace';
const trace = get();

expect(trace[0].getFileName()).toBe(__filename);

但有时您已经弹出了感兴趣的堆栈,只剩下一个Error对象。此模块可以提供帮助:

1
2
3
4
5
import { parse } from 'stack-trace';
const err = new Error('something went wrong');
const trace = parse(err);

expect(trace[0].getFileName()).toBe(__filename);

请注意,解析Error#stack属性并不完美,只能检索到某些属性,如下面的API文档所述。

长堆栈追踪

stack-trace与long-stack-traces配合使用效果很好,当解析跨越事件循环边界的err.stack时,会创建一个返回'----------------------------------------'作为getFileName()CallSite对象。事件循环边界调用站点的所有其他方法都返回null

API

stackTrace.get([belowFn])

返回一个CallSite对象数组,其中元素0是当前调用站点。

当将当前堆栈上的函数作为belowFn参数传递时,返回的数组将仅包括此函数下方的CallSite对象。

stackTrace.parse(err)

Error对象的err.stack属性解析为与stackTrace.get()返回的数组兼容的数组。但是,返回的CallSite对象上仅实现了以下方法。

  • getTypeName
  • getFunctionName
  • getMethodName
  • getFileName
  • getLineNumber
  • getColumnNumber
  • isNative

注意:除了getFunctionName(),所有上述方法返回的值与stackTrace.get()得到的值完全相同。getFunctionName()有时略有不同,但仍然有用。

CallSite

官方的v8 CallSite对象API可以在[这里][https://github.com/v8/v8/wiki/Stack-Trace-API#customizing-stack-traces]找到。简要摘录:

CallSite对象定义了以下方法:

  • getThis: 返回this的值
  • getTypeName: 以字符串形式返回this的类型。这是存储在this的构造函数字段中的函数名称(如果可用),否则是对象的[[Class]]内部属性。
  • getFunction: 返回当前函数
  • getFunctionName: 返回当前函数的名称,通常是其name属性。如果name属性不可用,将尝试从函数的上下文中推断名称。
  • getMethodName: 返回this或其原型中保存当前函数的属性名称
  • getFileName: 如果此函数在脚本中定义,则返回脚本的名称
  • getLineNumber: 如果此函数在脚本中定义,则返回当前行号
  • getColumnNumber: 如果此函数在脚本中定义,则返回当前列号
  • getEvalOrigin: 如果此函数是通过调用eval创建的,则返回表示调用eval位置的CallSite对象
  • isToplevel: 这是顶级调用吗?即,这是全局对象吗?
  • isEval: 此调用是否发生在通过调用eval定义的代码中?
  • isNative: 此调用是否在本地V8代码中?
  • isConstructor: 这是构造函数调用吗?

许可证

stack-trace根据MIT许可证授权。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计