Skip to main content

for_css_url

Function for_css_url 

Source
pub fn for_css_url(input: &str) -> String
Expand description

encodes input for safe embedding in a CSS url() value.

identical to for_css_string except parentheses ( and ) are not encoded (they are part of the url() syntax, not the value).

the URL must be validated before encoding (e.g., ensure the scheme is allowed). encoding only prevents syntax breakout, not malicious URLs.

§examples

use contextual_encoder::for_css_url;

assert_eq!(for_css_url("image.png"), "image.png");
// b is a hex digit, so trailing space after \27
assert_eq!(for_css_url("a'b"), r"a\27 b");
assert_eq!(for_css_url("a(b)"), "a(b)");
Examples found in repository?
examples/contexts.rs (line 85)
17fn main() {
18    let input = r#"<script>alert("xss")</script>"#;
19
20    println!("input: {input}");
21    println!();
22
23    // -----------------------------------------------------------------------
24    // comparison: same input across all encoders
25    // -----------------------------------------------------------------------
26
27    // html text content AND quoted attributes (safe default when unsure)
28    println!("--- html ---");
29    println!("  for_html:                     {}", for_html(input));
30
31    // html text nodes only — does NOT encode quotes, so never use in attributes
32    println!(
33        "  for_html_content:             {}",
34        for_html_content(input)
35    );
36
37    // quoted attribute values only — does NOT encode >, slightly more minimal
38    println!(
39        "  for_html_attribute:           {}",
40        for_html_attribute(input)
41    );
42
43    // unquoted attribute values — most aggressive, encodes whitespace/grave/etc.
44    println!(
45        "  for_html_unquoted_attribute:  {}",
46        for_html_unquoted_attribute(input)
47    );
48    println!();
49
50    // universal js encoder — safe in event attrs, <script> blocks, and .js files
51    println!("--- javascript ---");
52    println!("  for_javascript:               {}", for_javascript(input));
53
54    // html event attributes (onclick="...") — does not escape /
55    println!(
56        "  for_javascript_attribute:     {}",
57        for_javascript_attribute(input)
58    );
59
60    // <script> blocks — uses \" and \' (not safe in html attributes)
61    println!(
62        "  for_javascript_block:         {}",
63        for_javascript_block(input)
64    );
65
66    // standalone .js / json files — minimal, NOT safe in any html context
67    println!(
68        "  for_javascript_source:        {}",
69        for_javascript_source(input)
70    );
71
72    // ES6 template literals (`...`) — escapes backtick and ${} interpolation
73    let template_input = r#"`Hello ${name}`, welcome</script>"#;
74    println!(
75        "  for_js_template:              {}",
76        for_js_template(template_input)
77    );
78    println!();
79
80    // quoted css string values, e.g., content: "..." or font-family: "..."
81    println!("--- css ---");
82    println!("  for_css_string:               {}", for_css_string(input));
83
84    // css url() values — like for_css_string but parens pass through
85    println!("  for_css_url:                  {}", for_css_url(input));
86    println!();
87
88    // uri component (query params, path segments) — NOT for full urls
89    println!("--- uri ---");
90    println!(
91        "  for_uri_component:            {}",
92        for_uri_component(input)
93    );
94    println!();
95
96    // xml 1.0 aliases — identical to the html encoders
97    println!("--- xml 1.0 ---");
98    println!("  for_xml:                      {}", for_xml(input));
99    println!("  for_xml_content:              {}", for_xml_content(input));
100    println!(
101        "  for_xml_attribute:            {}",
102        for_xml_attribute(input)
103    );
104
105    // xml-only contexts
106    println!("  for_xml_comment:              {}", for_xml_comment(input));
107    println!("  for_cdata:                    {}", for_cdata(input));
108    println!();
109
110    // xml 1.1 — restricted chars get &#xHH; instead of space
111    println!("--- xml 1.1 ---");
112    let xml11_input = "a\x01b<c>";
113    println!("  for_xml11:                    {}", for_xml11(xml11_input));
114    println!(
115        "  for_xml11_content:            {}",
116        for_xml11_content(xml11_input)
117    );
118    println!(
119        "  for_xml11_attribute:          {}",
120        for_xml11_attribute(xml11_input)
121    );
122    println!();
123
124    // rust literals — \xHH escapes, UTF-8 byte encoding for byte strings
125    println!("--- rust ---");
126    println!("  for_rust_string:              {}", for_rust_string(input));
127    println!("  for_rust_char:                {}", for_rust_char(input));
128    println!(
129        "  for_rust_byte_string:         {}",
130        for_rust_byte_string(input)
131    );
132    println!();
133
134    // json string value — \\uXXXX escapes for control chars and specials
135    println!("--- json ---");
136    println!("  for_json:                     {}", for_json(input));
137    println!();
138
139    // sql string literals — single-quote doubling (standard) or backslash escaping (mysql)
140    println!("--- sql ---");
141    println!("  for_sql:                      {}", for_sql(input));
142    println!(
143        "  for_sql_backslash:            {}",
144        for_sql_backslash(input)
145    );
146
147    // -----------------------------------------------------------------------
148    // practical: one realistic input per sink, correct encoder for each
149    // -----------------------------------------------------------------------
150
151    let user_name = r#"Bob <img src=x onerror="alert(1)">"#;
152    let user_query = "hello world & goodbye";
153    let user_text = r#"hi from </script><script>alert(1)</script>"#;
154    let user_css_text = r#"hello "css" \ test"#;
155
156    println!("--- practical usage ---");
157
158    // html text node — for_html_content is the right encoder
159    println!(r#"  <p>{}</p>"#, for_html_content(user_name));
160
161    // nested context: uri component inside an html attribute.
162    // encode from inside out: first percent-encode the query value,
163    // then html-attribute-encode the entire href.
164    let href = format!("/search?q={}", for_uri_component(user_query));
165    println!(r#"  <a href="{}">search</a>"#, for_html_attribute(&href),);
166
167    // actual css string context: a quoted content value in a stylesheet
168    println!(
169        r#"  <style>.msg::after {{ content: "{}"; }}</style>"#,
170        for_css_string(user_css_text),
171    );
172
173    // javascript string inside an event-handler attribute
174    println!(
175        r#"  <button onclick="greet('{}');">hi</button>"#,
176        for_javascript_attribute(user_text),
177    );
178}