CVE-2022-23602 (Other, published 2022-02-01T11:15Z)
Description: value: Nimforum is a lightweight alternative to Discourse written in Nim. In versions prior to 2.2.0 any forum user can create a new thread/post with an include referencing a file local to the host operating system. Nimforum will render the file if able. This can also be done silently by using NimForum's post "preview" endpoint. Even if NimForum is running as a non-critical user, the forum.json secrets can be stolen. Version 2.2.0 of NimForum includes patches for this vulnerability. Users are advised to upgrade as soon as is possible. There are no known workarounds for this issue.
Severity: MEDIUM (CVSS v3 base score: 8.1)
Weakness: CWE-22 \u2014 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
Repository: https://github.com/nim-lang/Nim
Files changed:
compiler/docgen.nim
lib/packages/docutils/rst.nim
tests/stdlib/trstgen.nim
Commit message: Merge pull request from GHSA-ggrq-h43f-3w7m

This fixes a CVE (currently
https://github.com/nim-lang/Nim/security/advisories/GHSA-ggrq-h43f-3w7m)

Vulnerable code:
  var options= {roSupportRawDirective, roSupportMarkdown, roPreferMarkdown}
    mwRstStyle = "RST style: $1"
  ## file.
    let tok = p.tok[p.idx-2]  # report on directive in ".. directive::"
    check(input.toHtml == expected)
    let output = input.toHtml(warnings=warnings)
    let output0 = input0.toHtml
    let output1 = input1.toHtml
    let output2 = input2.toHtml
    let output3 = input3.toHtml
    let output1 = input1.toHtml

Fixed code:
  var options= {roSupportRawDirective, roSupportMarkdown, roPreferMarkdown, roSandboxDisabled}
    roSandboxDisabled         ## this option enables certain options
                              ## (e.g. raw, include)
                              ## which are disabled by default as they can
                              ## enable users to read arbitrary data and
                              ## perform XSS if the parser is used in a web
                              ## app.
    mwRstStyle = "RST style: $1",
    meSandboxedDirective = "disabled directive: '$1'",
  SandboxDirAllowlist = ["image", "code", "code-block"]
  ## file. This behaviour is disabled in sandboxed mode and can be re-enabled
  ## with the `roSandboxDisabled` flag.
    if roSandboxDisabled notin p.s.options:
      let tok = p.tok[p.idx-2]
      rstMessage(p, meSandboxedDirective, "file", tok.line, tok.col)
  let tok = p.tok[p.idx-2] # report on directive in ".. directive::"
  if roSandboxDisabled notin p.s.options:
    if d notin SandboxDirAllowlist:
      rstMessage(p, meSandboxedDirective, d, tok.line, tok.col)

const
  NoSandboxOpts = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled}


    check(
      input.toHtml(NoSandboxOpts) == expected
    )
    let output = input.toHtml(
      NoSandboxOpts,
      warnings=warnings
    )
    let output0 = input0.toHtml(
      NoSandboxOpts
    )
    let output1 = input1.toHtml(
      NoSandboxOpts
    )
    let output2 = input2.toHtml(
      NoSandboxOpts
    )
    let output3 = input3.toHtml(
      NoSandboxOpts
    )
    let output1 = input1.toHtml(
      NoSandboxOpts
    )

suite "local file inclusion":
  test "cannot include files in sandboxed mode":
    var error = new string
    discard ".. include:: ./readme.md".toHtml(error=error)
    check(error[] == "input(1, 11) Error: disabled directive: 'include'")

  test "code-block file directive is disabled":
    var error = new string
    discard ".. code-block:: nim\n    :file: ./readme.md".toHtml(error=error)
    check(error[] == "input(2, 20) Error: disabled directive: 'file'")