This attack is called CSS Injection and it can be quite a beast.
What is CSS Injection?
With HTML 5 becoming the shiny new thing for web developers, CSS has learned a few new tricks as well. You can do quite powerful things with CSS selectors, things that many web developers will look at and thing "What? CSS can do that!?".
As CSS became ever more powerful, various hackers started to take a look at it and found interesting ways of exploiting it.
For instance, if an attacker is able to inject arbitrary CSS code, they could run the following:
This exploit code takes advantage of several CSS features. It selects an
<input> element with two attributes. The first is "name" and the second is "value". (e.g.
<input name="csrf_token" value="a5c319fabb...">). Any such input field starting with a value of "
a" would then cause the background-image of said input field being set to be loaded from
http://attacker/log?a. The attacker could log this and thus get information about the CSRF token being sent.
This alone would not be enough to read the CSRF token, but with enough rules covering every possible CSRF token (or password), an attacker could reliably read out CSRF tokens of any user who is served this custom CSS.
Of course, an attacker would need more to actually exploit this vulnerability, but it's a start.
Why have I never heard of CSS Injection before?
A burglar does not care about your super high-end nigh-pickproof lock core if the door in the back is made out of glass and can be smashed with a big rock.
Similarly, would-be hackers on the internet looking to make a quick profit don't care about the most sophisticated exploits possible, but rather about something that will work quite reliably on many websites they try it on.
As such, CSS Injection is an exploitation technique that is somewhat obscure, as your average "y0u be3n h4xx3d"-actor will probably use XSS or SQL-Injection to get what they want.
How can I prevent CSS Injections?
Don't let anyone inject CSS.
The best way to prevent CSS Injections is to not let users ever inject anything into a CSS file that you serve. If you would like to allow users to customize their UI, give them selections (e.g. "color1", "color2", etc.) and turn them into concrete values on the server side (e.g. "color1" would match with "#490088").
Use Input-Validation to ensure sane input.
If you absolutely must let users inject their CSS - which I heavily recommend against - then you have to validate the input. This means if you have to let a user use their own color for an element, validate it against the following RegEx:
Any input that deviates from being a six-digit hexadecimal input with optional
# prepended will be rejected.
What about including malicious code like
.svg files as background image?
As mentioned above, I would always beware of allowing users to do anything "custom".