cmark-gfm is a popular library used by GitHub for parsing and rendering Markdown, a lightweight markup language with plain-text-formatting syntax. Recently, a critical security vulnerability known as CVE-2022-24724 was discovered in this library, affecting versions before .29..gfm.3 and .28.3.gfm.21. This vulnerability is related to an integer overflow in cmark-gfm's table row parsing, which exists in the table.c:row_from_string function. This issue may result in heap memory corruption, potentially leading to information leak, arbitrary code execution, and even remote code execution (RCE) in certain cases. The vulnerability has already been addressed in the mentioned patched versions of cmark-gfm. This post aims to provide an in-depth analysis of the vulnerability, including code snippets, original references, and exploit details.

Code Snippet

The vulnerable code is present in the table.c file of the cmark-gfm library, specifically in the row_from_string function. The problem occurs when parsing tables where the marker rows contain more than UINT16_MAX columns, which leads to an integer overflow. Below is the relevant code snippet:

// table.c
static cmark_table_row *row_from_string(const unsigned char *buffer, bufsize size,
                                        int *parsed_as_row, cmark_syntax_extension *table_ext) {
    ...
    cell_widths = (uint16_t *)calloc(column_count, sizeof(uint16_t));
    ...
    for (;;) {
      ...
      unsigned int col_width = (end - buffer);
      if (col_width > UINT16_MAX) {
        goto BAIL;
      }
      ...
      off += (int)col_width;
      current_cell = cmark_table_cell_new(table_ext->parser->mem);

      if (colpos < column_count) {
        cell_widths[colpos] = (uint16_t)col_width;
      } else {
        sprintf(msg, "Table row too wide; trimming");
        table_ext->parser->mem->report_error(table_ext->parser->mem->memory_reporting_context, msg);
      }
    ...
}

Exploit Details

An attacker can exploit this vulnerability by crafting a malicious Markdown document containing a table with more than UINT16_MAX columns. When cmark-gfm attempts to parse such a table, an integer overflow will occur, resulting in heap memory corruption. Depending on the application context and how cmark-gfm is used, this issue might lead to information leak, arbitrary code execution, or even remote code execution (RCE), particularly if the Markdown document is under the control of a remote user.

The vulnerability was reported and patched by the cmark-gfm team. For detailed information, refer to the following resources:

- GitHub cmark-gfm repository: https://github.com/github/cmark-gfm
- CVE-2022-24724 Details: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24724
- NVD details: https://nvd.nist.gov/vuln/detail/CVE-2022-24724

Workaround

If you cannot immediately update to the patched versions of cmark-gfm (.29..gfm.3 and .28.3.gfm.21), disabling the table extension in the library will prevent this vulnerability from being triggered. This does mean, however, that your application will no longer be able to parse and render Markdown tables.

Conclusion

The CVE-2022-24724 vulnerability is a critical issue affecting cmark-gfm's Markdown table parsing functionality, with potential consequences including heap memory corruption, information leak, arbitrary code execution, and remote code execution. It's essential for users of the affected cmark-gfm versions to update as soon as possible or disable the table extension as a workaround. As always, it's crucial to keep your libraries and applications up-to-date and follow security best practices to mitigate the risk of such vulnerabilities.

Timeline

Published on: 03/03/2022 20:15:00 UTC
Last modified on: 04/18/2022 18:37:00 UTC