asciidoc_parser/parser/safe_mode.rs
1/// Describes the safe mode under which a document is parsed and rendered.
2///
3/// Safe modes provide a security model that controls how much a document is
4/// allowed to reach outside of itself. They mirror the safe modes defined by
5/// [Ruby Asciidoctor], and the discriminant values are chosen so that the
6/// modes compare in order of increasing safety (`Unsafe` < `Safe` < `Server` <
7/// `Secure`). Features that could expose the host environment (for example,
8/// embedding the contents of a file directly in the output) are only enabled
9/// when the safe mode is below a threshold.
10///
11/// The default safe mode is [`SafeMode::Secure`], matching the most
12/// conservative setting. A client may relax it via
13/// [`Parser::with_safe_mode`](crate::Parser::with_safe_mode).
14///
15/// [Ruby Asciidoctor]: https://docs.asciidoctor.org/asciidoc/latest/safe-modes/
16#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
17pub enum SafeMode {
18 /// A safe mode level that disables any of the security features enforced by
19 /// Asciidoctor (Ruby or otherwise). This mode is intended for use when the
20 /// document is entirely trusted.
21 Unsafe = 0,
22
23 /// A safe mode level that closely parallels [`Unsafe`](Self::Unsafe),
24 /// except it prevents access to files which reside outside of the
25 /// parent directory of the source file.
26 Safe = 1,
27
28 /// A safe mode level that disallows the document from attempting to read
29 /// files from the file system and including their contents into the
30 /// document. It also disables certain macros that pose a security risk.
31 ///
32 /// This is the most fitting safe mode for server deployments (hence the
33 /// name).
34 Server = 10,
35
36 /// A safe mode level that disallows the document from attempting to read
37 /// files from the file system and including their contents into the
38 /// document, and it prevents access to file system paths.
39 ///
40 /// This mode allows the AsciiDoc document to be processed in a shared,
41 /// server-side environment, such as a wiki, where the document should not
42 /// be able to embed the contents of arbitrary files.
43 ///
44 /// This is the default safe mode.
45 #[default]
46 Secure = 20,
47}
48
49impl SafeMode {
50 /// The lowercase name of this safe mode (`unsafe`, `safe`, `server`,
51 /// `secure`).
52 ///
53 /// This is the value exposed through the `safe-mode-name` intrinsic
54 /// attribute and is also used to build the `safe-mode-<name>` flag
55 /// attribute. It matches the (lowercased) name reported by Ruby
56 /// Asciidoctor.
57 pub(crate) fn name(self) -> &'static str {
58 match self {
59 Self::Unsafe => "unsafe",
60 Self::Safe => "safe",
61 Self::Server => "server",
62 Self::Secure => "secure",
63 }
64 }
65
66 /// The numeric level of this safe mode (`0`, `1`, `10`, or `20`).
67 ///
68 /// This is the value exposed through the `safe-mode-level` intrinsic
69 /// attribute. Higher numbers indicate a more restrictive (safer) mode.
70 pub(crate) fn level(self) -> u8 {
71 self as u8
72 }
73}