CVE-2021-32773 (Other, published 2021-07-20T00:15Z)
Description: value: Racket is a general-purpose programming language and an ecosystem for language-oriented programming. In versions prior to 8.2, code evaluated using the Racket sandbox could cause system modules to incorrectly use attacker-created modules instead of their intended dependencies. This could allow system functions to be controlled by the attacker, giving access to facilities intended to be restricted. This problem is fixed in Racket version 8.2. A workaround is available, depending on system settings. For systems that provide arbitrary Racket evaluation, external sandboxing such as containers limit the impact of the problem. For multi-user evaluation systems, such as the `handin-server` system, it is not possible to work around this problem and upgrading is required.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-610 \u2014 Externally Controlled Reference to a Resource in Another Sphere
The product uses an externally controlled name or reference that resolves to a resource that is outside of the intended control sphere.
Repository: https://github.com/racket/racket
Files changed:
pkgs/racket-doc/scribblings/reference/sandbox.scrbl
pkgs/racket-test-core/tests/racket/sandbox.rktl
Commit message: racket/sandbox: documentation and tests for reader and require checking


Vulnerable code:
                            [#:allow-read allow-read (listof (or/c module-path? path-string?)) null])
                                   [#:language   lang  (or/c #f module-path?) #f]
                                   [#:allow-read allow-read (listof (or/c module-path? path-string?)) null])
@racket[allow-for-load], and @racket[allow-read] arguments.  When
@racket[allow-for-require] list. (For backward compatibility,
non-@racket[module-path?] path strings are allowed in
in its language position --- use the optional @racket[lang] argument
to specify such a restriction (the default, @racket[#f], means no
restriction is enforced). When the program is specified as a path, then
}

Fixed code:
                            [#:allow-read allow-read (listof (or/c module-path? path-string?)) null]
                            [#:allow-syntactic-requires allow-syntactic-requires (or/c #f (listof module-path?)) #f])
                                   [#:language  lang  (or/c #f module-path?) #f]
                                   [#:readers   readers  (or/c #f (listof module-path?)) (and lang (default-language-readers lang))]
                                   [#:allow-read allow-read (listof (or/c module-path? path-string?)) null]
                                   [#:allow-syntactic-requires allow-syntactic-requires (or/c #f (listof module-path?)) #f])
@racket[allow-for-load], and @racket[allow-read] arguments; collection-based
module files typically do not need to be included in those lists.  When
@racket[allow-for-require] list. When @racket[allow-syntactic-requires]
is not @racket[#f], it constraints the set of modules that can be directly
referenced in a module; see below for more information.
(For backward compatibility,
non-@racket[module-path?] path strings are allowed in arguments like
The @racket[allow-syntactic-requires] argument, if non-@racket[#f],
constrains @racket[require] references expanded in the module when the
@racket[language] argument implies a @racket[module] wrapper; more
precisely, it constrains the module paths that can be resolved when a
syntax object is provided to the @tech{module name resolver}, which
will include @racket[require] forms that are created by macro
expansion.
in its language position; use the optional @racket[lang] argument
to specify such a restriction, where @racket[#f] means that no
restriction is enforced. The @racket[readers] argument similarly
constrains the paths that can follow @hash-lang[] or @schememetafont{#reader}
if it is not @racket[#f], and the default is based on @racket[lang].
The @racket[allow-syntactic-requires] argument is treated the same as
for @racket[make-evaluator] in the module-wrapper case.

When the program is specified as a path, then
@history[#:changed "1.2" @elem{Added the @racket[#:readers] and
         @racket[#:allow-syntactic-require] arguments.}]}
@defproc[(default-language-readers [lang module-path?]) (listof module-path?)]{

Creates a default list of readers that should be allowed to produce a
module that uses @racket[lang] as the language.

This default list includes the following (and more paths may be added
in the future):

@itemlist[

 @item{@racket[`(submod ,lang reader)]}

 @item{@racketvalfont{'}@racket[lang]@racketvalfont{/lang/reader} if @racket[lang] is a symbol}

 @item{the module path producing by adding the relative path @racket["lang/reader.rkt"]
       to @racket[lang] if @racket[lang] is not a symbol}

 @item{@racket['(submod at-exp reader)]}

 @item{@racket['at-exp/lang/reader]}

]

@history[#:added "1.2"]}

;; Check reader guard on a sandbox:
(err/rt-test (make-module-evaluator "#lang s-exp something-bad" #:language 'racket/base)
             exn:fail?
             #rx"disallowed reader module path: [(]submod s-exp reader[)]")

(void (make-module-evaluator "#lang at-exp racket/base"
                             #:language 'racket/base))
(void (make-module-evaluator "#lang s-exp racket/base"
                             #:language 'racket/base
                             #:readers '((submod s-exp reader)
                                         s-exp/lang/reader
                                         racket/base
                                         (submod racket/base reader))))

;; ----------------------------------------

;; Check require guard on a sandbox:

(err/rt-test (make-module-evaluator "#lang racket/base (require json)"
                                    #:allow-syntactic-requires '(racket/runtime-config))
             exn:fail?
             #rx"disallowed `require` module path: json")
(void
 (make-module-evaluator "#lang racket/base (require json)"
                        #:allow-syntactic-requires '(racket/runtime-config json)))

;; ----------------------------------------