diff options
author | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2017-09-07 20:42:55 +0200 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2017-09-07 20:42:55 +0200 |
commit | 7c29bf765fd666e61b9bc7d0eb40909b8e9002da (patch) | |
tree | 450263b920a0239ab6d4734dd385e2c1978d068e | |
parent | df2637c0324d2cb3f5925b8595417b08496de4a5 (diff) | |
download | askama-7c29bf765fd666e61b9bc7d0eb40909b8e9002da.tar.gz askama-7c29bf765fd666e61b9bc7d0eb40909b8e9002da.tar.bz2 askama-7c29bf765fd666e61b9bc7d0eb40909b8e9002da.zip |
Extend escaping according to OWASP recommendations
-rw-r--r-- | askama/src/lib.rs | 11 | ||||
-rw-r--r-- | askama_shared/src/escaping.rs | 7 | ||||
-rw-r--r-- | testing/tests/filters.rs | 7 |
3 files changed, 16 insertions, 9 deletions
diff --git a/askama/src/lib.rs b/askama/src/lib.rs index d56326c..04c73f6 100644 --- a/askama/src/lib.rs +++ b/askama/src/lib.rs @@ -44,10 +44,13 @@ //! (`none`), the parsed syntax tree (`ast`), the generated code (`code`) //! or `all` for both. The requested data will be printed to stdout at //! compile time. -//! * `escape` (as `escape = "none"`): disable escaping of expression output. -//! By default, Askama escapes `&`, `<` and `>` to their corresponding -//! HTML character entities. This can be enabled explicitly by setting this -//! value to `html` or disabled by setting it to `none`. +//! * `escape` (as `escape = "none"`): change escape mode for expression +//! output. By default, Askama escapes content according to the [OWASP +//! escaping recommendations][owasp]. This can be enabled explicitly by +//! setting this value to `html` or disabled by setting it to `none`. +//! +//! [owasp]: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content +//! //! //! ## Variables //! diff --git a/askama_shared/src/escaping.rs b/askama_shared/src/escaping.rs index ed4b3d7..a8a3559 100644 --- a/askama_shared/src/escaping.rs +++ b/askama_shared/src/escaping.rs @@ -42,7 +42,7 @@ impl<T> Display for MarkupDisplay<T> where T: Display { fn escapable(b: &u8) -> bool { - *b == b'<' || *b == b'>' || *b == b'&' + *b == b'<' || *b == b'>' || *b == b'&' || *b == b'"' || *b == b'\'' || *b == b'/' } pub fn escape(s: String) -> String { @@ -57,7 +57,7 @@ pub fn escape(s: String) -> String { } let bytes = s.as_bytes(); - let max_len = bytes.len() + found.len() * 3; + let max_len = bytes.len() + found.len() * 5; let mut res = Vec::<u8>::with_capacity(max_len); let mut start = 0; for idx in &found { @@ -69,6 +69,9 @@ pub fn escape(s: String) -> String { b'<' => { res.extend(b"<"); }, b'>' => { res.extend(b">"); }, b'&' => { res.extend(b"&"); }, + b'"' => { res.extend(b"""); }, + b'\'' => { res.extend(b"'"); }, + b'/' => { res.extend(b"/"); }, _ => panic!("incorrect indexing"), } } diff --git a/testing/tests/filters.rs b/testing/tests/filters.rs index 8e558ba..fe218e3 100644 --- a/testing/tests/filters.rs +++ b/testing/tests/filters.rs @@ -16,15 +16,16 @@ struct TestTemplate { #[test] fn filter_escape() { let s = TestTemplate { - strvar: "my <html> is unsafe & should be escaped".to_string(), + strvar: "// my <html> is \"unsafe\" & should be 'escaped'".to_string(), }; assert_eq!(s.render().unwrap(), - "my <html> is unsafe & should be escaped"); + "// my <html> is "unsafe" & \ + should be 'escaped'"); } #[derive(Template)] -#[template(path = "format.html")] +#[template(path = "format.html", escape = "none")] struct FormatTemplate<'a> { var: &'a str, } |