1

In my website I noticed my developers had set it up so certain form data was past from the URL to the content of the website. E.G

?email="email"

The obvious vulnerability means that I can put ?email="XSS vector" in the domain and XSS Vector would be displayed in the email field.

Another was that when only one form data was present extra data could be added to the end of the url. e.g

?email="email" XSS vector

I told the developer about this vulnerability and they told me that the website was secure as all text is sanitised. For example, if I was to add an external link or file through the url

?email="email"  <script src="https://myscripts.js"></script> 

what is rended in html is

<script src="\"https://myscripts.js""></script>

And the link leads to

https://mysite.com/\https://myscripts.js

Which means that the script can only be loaded if it is located on my domain.

However I only know basic HTML, JS. So can't verify myself if this is safe.

I would prefer this not to happen at all but don't have the skills to rectify it myself. But if I do have it like this I need to know it is secure.

4
  • How does the system handle inline scripts, or use of the base tag?
    – jrtapsell
    Jun 9, 2019 at 14:39
  • Hi @jrtapsell, not sure about what your asking regarding inline scripts. As far as I can tell no base tag has been set. It cant be manipulated through XSS such as <base href="attacker.com"> as it will render the base href as mysite.com\attacker.com Jun 10, 2019 at 16:16
  • You don't need a script "src" for XSS. You can write code directly inside the <script></script> tag. Jun 11, 2019 at 12:00
  • Well If all text is sanitized - the xss wouldn’t work. That’s the main defense against xss. If you want to investigate this further - look at how the text is sanitized and whether truly all of it is sanitized. Jun 11, 2019 at 12:01

4 Answers 4

1

No, this is not enough.

An attacker does not necessarily need to call an external script. They can dump the payload directly into the inline script too. Depending on the length restrictions in place, this can become quite tricky, but still manageable.

The main takeaway from this is that custom-made solutions are not very secure. Every now and then I see people trying to ask if their new ingenious solution just stopped all XSS, CSRF, SQL Injections, etc...

The answer to all of these questions is no. XSS Protection is a problem that has been solved already, with proper output encoding and additionally possible input validation.

This means that every output needs to be encoded for its intended destination. Don't do this yourself either, but use a framework or library which provides this for you.

Input validation verifies if input is in the expected format. For example, if you expect an email address, RFC-822 offers a very large regex, which is guaranteed to validate all standard-conform email addresses. Is this overkill and unnecessary? Probably. But for simpler things like numbers, you can implement input validation in addition to output encoding:

if (input.matches("^(0|[1-9]\d*)$"))
{
    // "input" is a valid integer
    return true;
}
else
{
    // "input" is not a valid integer
    return false;
}

This example code would allow all integers without zero-prefixes. Any other input will be rejected.

Summary

  1. Never use your own custom method to implement security! This is the golden rule of security and breaking it will get you hacked.
  2. Use output encoding for the target context! If untrusted data is written into the DOM, then encode it for the DOM. If it's written for an attribute value, then encode it as attribute value. Encoding is the only way to be sure.
  3. Optionally use input validation alongside output encoding! By ensuring that input is what you expect it to be, you can save yourself multiple headaches down the line.
0

If adding a slash is the only thing they are doing I'd be willing to bet there is a bypass ... perhaps try simply adding a second script tag. Or xss doesn't require script tags so try injecting other html elements and putting onclick or on hover events , etc. or using single ticks instead of quotes , etc. many options .

A better solution for the developers would be to whitelist with a regular expression the email address format so that things like less than , greater than , slash, and quotes aren't even allowed in an email thus preventing xss.

0

Your schema is not enough. It can defend against generic, non targeted attacks, but a deliberated attacker will not be blocked.

You need 2 things: sanitization and escaping. Sanitize on input, store, escape on the output.

Sanitization is more than running a regex and calling the day. If the field expects a birth date for a living person, ensure the person is less than 140 years old. If it's an email, properly parse the field to ensure it contains only an email and nothing else. Inspect not only the contents, but the context too, not only is the field is valid, but if it makes sense too.

Escaping takes into account the output medium. If the output is an SQL statement, properly escape the quotes, dashes, and so on. If it's HTML, neutralize all the tags (replacing < for &lt; is a start). If it's plain text, pay attention to the proper encoding. Not only for plain text, but for everything.

Combining both sanitization and escaping makes way harder to an attacker to break your code, even if makes harder for your programmers to implement. But it will save you a lot of trouble in the future, as your developers will evolve a security mindset.

0

No. It is not.

You should be escaping the content in relation the context it is present in.

So, let's suppose the variable is printed on:

<p>Where should I spam you? <input type="email" value="tasha@email" /></p>

Where tasha@email is the attacker-controlled parameter.

Since we are in a html context inside a double-quoted parameter of a html tag, we should be escaping all " (as &quot; or &#32;) and & Other characters like '<' or '>' might be escaped as well but on this specific case are not required.

Please note that we are escaping characters if you are inserting bytes you should take into account that you are not inserting invalid bytes that nullify the closing ".

I think what they mean is that they change " to \", which is the wrong escaping. If we were in a string context inside, we could escape a " by prepending a backslash, but here we are inside html.

An easy way to show it would be to use single quotes instead of double, but let's pretend your developer also put a backslash in front of them. Well, there are other ways:

<p>Where should I spam you? <input type="email" value="tasha@email\"><script>window.location=Array(104,116,116,112,115,58,47,47,115,101,99,117,114,105,116,121,46,115,116,97,99,107,101,120,99,104,97,110,103,101,46,99,111,109,47,113,47,50,49,49,53,56,52,47,52,57,52,56,57).map(x=>String.fromCharCode(x)).join(String())</script>" /></p>

The above code uses no quotes other than the one that was thought to be "sanitised", yet it executes a random javascript that, quite benignly, simply redirects to this stackexchange question.

The "escaped" quote is actually not escaped inside the context it is in, and is closing the parameter. Then the ><script> (which are not filtered) let us enter a script tag, and we are using an array to set a string without explicitly typing it as such.

Thus we are showing the website to be insecure and the approach of the developer to be completely wrong.

‏‎

Note 1: Some browsers try to detect XSS attempts and disable them. This doesn't mean that the application isn't vulnerable, just that it is somewhat harder to exploit. Note that (a) Clients using other browsers are still vulnerable (b) Generally, the application will still vulnerable even in those browsers, although bypassing the filter would needs extra work, and the error is still the same: the original failure of the application to properly validate the parameters.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .