
What I learned from suffering my first and last XSS attack - WillieStevenson
https://livesshattack.net/blog/2016-02-28/what-i-learned-from-suffering-my-first-and-last-xss-attack
======
jacobparker
Some modern tools to mitigate XSS/make XSS virtually impossible:

\- Content-Security-Policy [https://developer.mozilla.org/en-
US/docs/Web/Security/CSP/In...](https://developer.mozilla.org/en-
US/docs/Web/Security/CSP/Introducing_Content_Security_Policy)

\- The sandbox attribute on iframes:
[https://developer.mozilla.org/en/docs/Web/HTML/Element/ifram...](https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#Attributes)

XSS is one of the hardest things to keep under control at scale.

~~~
ingenter
A _much_ better way to mitigate XSS/HTML injections is not using string
functions to generate HTML.

CSP prevents an attacker from executing scripts, but the attacker can still
corrupt your HTML.

~~~
minitech
Yep. XSS isn’t at all hard to prevent if you’re using tools that are safe by
default. Unfortunately, popular ones like jQuery aren’t. (This, more than any
other, is a reason to prefer the DOM API.)

~~~
paulddraper
I'm not sure the DOM API is safer. innerHtml vs html()

~~~
eridius
If you're assigning untrusted text to a property called `innerHTML`, you
shouldn't be surprised to learn that you're vulnerable to XSS.

APIs like jQuery are worse because you end up treating strings as HTML without
even realizing it. Example from the article:

    
    
      $("#tail-here").prepend(newlines);
    

There's no hint on that line that the `newlines` variable is interpreted as
HTML instead of text.

~~~
Sacho
Pfft. Straight from the documentation of the method:

    
    
      content
      Type: >>htmlString<< or Element or Array or jQuery
    

You could argue that the API is bad for allowing HTML strings as arguments,
but it's not really surprising that a function does what it is documented to
do. Especially since these are _DOM manipulation_ , not string manipulation
functions.

~~~
minitech
> You could argue that the API is bad for allowing HTML strings as arguments

That is _exactly_ what I’m arguing, yes.

> but it's not really surprising that a function does what it is documented to
> do

It doesn’t have to be surprising or undocumented to be stupid.

~~~
rimantas

      > You could argue that the API is bad for allowing HTML strings as arguments
      That is exactly what I’m arguing, yes.
    

And how native DOM helps there?

~~~
masklinn
There are relatively few DOM APIs which take a trusted string. innerHTML and
outerHTML are two and clearly state that they take _HTML_ so it's no surprise
for the stuff you give them to be interpreted thus. But if you use e.g.
textContent or createTextNode to insert text into your document, they will
correctly sanitise it.

jQuery has text()[0], but because most of its API takes strings to start with,
it's very convenient to do the wrong thing and shove untrusted strings into
unsafe methods.

[0] [http://api.jquery.com/text/#text2](http://api.jquery.com/text/#text2)

~~~
rimantas
yes, API takes strings, but it calls native DOM at the end anyway, so I still
don't get what's your point.

~~~
masklinn
> yes, API takes strings, but it calls native DOM at the end anyway

jQuery calls _unsafe API_ which should only be handled _trusted strings_ but
makes it easy and convenient to give them _untrusted string_ and thus
introduce _exploit vectors_.

Furthermore it's also significantly more difficult to _audit the code_ , using
the regular DOM there are only a pair of attributes to check, whereas pretty
much _any jQuery method call_ is a potential security hole.

tldr: jQuery makes doing things wrong very easy, much easier than doing things
right.

------
laumars
The HTML framework I created for personal projects has a special string type
that cannot be output (nor even compiled) without specifically selecting which
format you want the string encoded as (eg HTML, URL, plain text, etc). While
this does produce some arguably uglier code and creates a little additional
development overhead (ie code fails to compile by default), it has caught
numerous instances where I would have accidentally left myself open to this
kind of attack. So I've found it to be highly effective in the long run.

~~~
pluma
Python's Jinja templating language has the concept of "safe" and "unsafe"
strings. By default all strings are unsafe (meaning they will be escaped
wherever they are rendered) and you need to explicitly mark them as safe in
order to be able to treat them as HTML.

React and Angular (and maybe Ember too?) similarly auto-escape any strings to
be rendered and only provide very explicit ways to circumvent that (in React
it's even called "dangerouslySetInnerHTML" and takes an object with a property
called "__html" rather than a string[0]).

You can avoid XSS in dynamically typed languages. You just need to make it
easier to do the safe thing than the difficult thing.

[0]: I really like React's approach to naming APIs you should think twice
about using. For legacy reasons ReactDOM is still bundled as part of React and
exposed with a property but the name of that property is
"__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED" (presumably to prevent React
maintainers / Facebook employees from using it).

~~~
laumars
I wasn't implying dynamically typed languages were worse that statically typed
languages. I was just discussing the approach I used to mitigate human error
when building web UIs in hope it might inspire other people (or other people
might offer additional feedback that inspire improvements in my own
framework).

It is interesting to see that other frameworks are using similar ideas to my
own though. Maybe not surprising; but at least reassuring to know that my own
quirky API design isn't as leftfield as it felt when I was developing it.

~~~
pluma
The "dynamic typing" remark was directed more at the sibling comment than
yours directly.

------
jameshart
I have always been nervous about clicking on links to sites that say 'we were
hacked, but we're safe now.' When that link also includes the hubristic 'and
we'll never be hacked again,' which paints a target on you big enough for the
entire darknet to see... I'm sorry but I'm not clicking on that link.

~~~
gcr
The site's giving me a 503 Bad Gateway now, so you might be onto something.

------
pramodliv1
Is there a tool that tries XSS and other common attacks on a web page?

Similar to how Google Page Speed Insights and SEO tools which detect errors
such as "You haven't minified your CSS", "You haven't set a title and
description for your page" etc.

~~~
sahreeg
Vulnerability scanners are usually premium (paid) products. Some offer free
trials such as Qualys:
[https://www.qualys.com/forms/freescan/](https://www.qualys.com/forms/freescan/)

Other famous tools are nessus, and accunetix:
[https://www.tenable.com/products/nessus-vulnerability-
scanne...](https://www.tenable.com/products/nessus-vulnerability-scanner),
[http://www.acunetix.com/vulnerability-
scanner/](http://www.acunetix.com/vulnerability-scanner/)

These scanners are usually used by security consultants to test a complete
internal network of a client.

For a full list, some of which are open source, check this link:
[https://www.owasp.org/index.php/Category:Vulnerability_Scann...](https://www.owasp.org/index.php/Category:Vulnerability_Scanning_Tools)

~~~
pramodliv1
Thank you!

------
a_c
What is that tool you used for realtime traffic monitoring?

~~~
WillieStevenson
Google analytics?

~~~
a_c
Thanks. I never really programmed for the web

~~~
WillieStevenson
You're welcome.

------
chei0aiV
Anyone know of static analysis tools that find potential XSS/etc issues in
your frontend (such as the innerHtml message) and backend code?

