Here is a general encode procedure:
var lt = /</g,
gt = />/g,
ap = /'/g,
ic = /"/g;
value = value.toString().replace(lt, "<").replace(gt, ">").replace(ap, "'").replace(ic, """);
If your user doesn't submit anything to your server you don't even need the above. If the user submits and you are using the user input then the above should be safe. As long as the '<' and '>' are globally sanitized and the parenthesis also are you are good to go.
Answer from Konstantin Dinev on Stack OverflowHere is a general encode procedure:
var lt = /</g,
gt = />/g,
ap = /'/g,
ic = /"/g;
value = value.toString().replace(lt, "<").replace(gt, ">").replace(ap, "'").replace(ic, """);
If your user doesn't submit anything to your server you don't even need the above. If the user submits and you are using the user input then the above should be safe. As long as the '<' and '>' are globally sanitized and the parenthesis also are you are good to go.
Considering https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
Here is an implementation of their recommendations :
function escapeOutput(toOutput){
return toOutput.replace(/\&/g, '&')
.replace(/\</g, '<')
.replace(/\>/g, '>')
.replace(/\"/g, '"')
.replace(/\'/g, ''')
.replace(/\//g, '/');
}
Also make sure you use this function only when necessary or you might break some stuff.
But I suggest you to take a look at already made libraries for sanitizing output :
https://github.com/ecto/bleach
javascript - How to avoid "Cross-Site Script Attacks" - Stack Overflow
jquery - How to prevent cross-site scripting using javascript - Stack Overflow
xss - How to prevent cross site script attacks using javascript - Stack Overflow
c# - How to prevent XSS (Cross Site Scripting) whilst allowing HTML input - Stack Overflow
Videos
I'm sure it can be done fx. in PHP by validating forms
Not really. The input stage is entirely the wrong place to be addressing XSS issues.
If the user types, say <script>alert(document.cookie)</script> into an input, there is nothing wrong with that in itself. I just did it in this message, and if StackOverflow didn't allow it we'd have great difficulty talking about JavaScript on the site! In most cases you want to allow any input(*), so that users can use a < character to literally mean a less-than sign.
The thing is, when you write some text into an HTML page, you must escape it correctly for the context it's going into. For PHP, that means using htmlspecialchars() at the output stage:
<p> Hello, <?php echo htmlspecialchars($name); ?>! </p>
[PHP hint: you can define yourself a function with a shorter name to do echo htmlspecialchars, since this is quite a lot of typing to do every time you want to put a variable into some HTML.]
This is necessary regardless of where the text comes from, whether it's from a user-submitted form or not. Whilst user-submitted data is the most dangerous place to forget your HTML-encoding, the point is really that you're taking a string in one format (plain text) and inserting it into a context in another format (HTML). Any time you throw text into a different context, you're going to need an encoding/escaping scheme appropriate to that context.
For example if you insert text into a JavaScript string literal, you would have to escape the quote character, the backslash and newlines. If you insert text into a query component in a URL, you will need to convert most non-alphanumerics into %xx sequences. Every context has its own rules; you have to know which is the right function for each context in your chosen language/framework. You cannot solve these problems by mangling form submissions at the input stageโthough many naรฏve PHP programmers try, which is why so many apps mess up your input in corner cases and still aren't secure.
(*: well, almost any. There's a reasonable argument for filtering out the ASCII control characters from submitted text. It's very unlikely that allowing them would do any good. Plus of course you will have application-specific validations that you'll want to do, like making sure an e-mail field looks like an e-mail address or that numbers really are numeric. But this is not something that can be blanket-applied to all input to get you out of trouble.)
Cross-site scripting attacks (XSS) happen when a server accepts input from the client and then blindly writes that input back to the page. Most of the protection from these attacks involves escaping the output, so the Javascript turns into plain HTML.
One thing to keep in mind is that it is not only data coming directly from the client that may contain an attack. A Stored XSS attack involves writing malicious JavaScript to a database, whose contents are then queried by the web application. If the database can be written separately from the client, the application may not be able to be sure that the data had been escaped properly. For this reason, the web application should treat ALL data that it writes to the client as if it may contain an attack.
See this link for a thorough resource on how to protect yourself: http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
Peter, I'd like to introduce you to two concepts in security;
Blacklisting - Disallow things you know are bad.
Whitelisting - Allow things you know are good.
While both have their uses, blacklisting is insecure by design.
What you are asking, is in fact blacklisting. If there had to be an alternative to <script> (such as <img src="bad" onerror="hack()"/>), you won't be able to avoid this issue.
Whitelisting, on the other hand, allows you to specify the exact conditions you are allowing.
For example, you would have the following rules:
- allow only these tags: b, i, u, img
- allow only these attributes: src, href, style
That is just the theory. In practice, you must parse the HTML accordingly, hence the need of a proper HTML parser.
Microsoft have produced their own anti-XSS library, Microsoft Anti-Cross Site Scripting Library V4.0:
The Microsoft Anti-Cross Site Scripting Library V4.0 (AntiXSS V4.0) is an encoding library designed to help developers protect their ASP.NET web-based applications from XSS attacks. It differs from most encoding libraries in that it uses the white-listing technique -- sometimes referred to as the principle of inclusions -- to provide protection against XSS attacks. This approach works by first defining a valid or allowable set of characters, and encodes anything outside this set (invalid characters or potential attacks). The white-listing approach provides several advantages over other encoding schemes. New features in this version of the Microsoft Anti-Cross Site Scripting Library include:- A customizable safe list for HTML and XML encoding- Performance improvements- Support for Medium Trust ASP.NET applications- HTML Named Entity Support- Invalid Unicode detection- Improved Surrogate Character Support for HTML and XML encoding- LDAP Encoding Improvements- application/x-www-form-urlencoded encoding support
It uses a whitelist approach to strip out potential XSS content.
Here are some relevant links related to AntiXSS:
- Anti-Cross Site Scripting Library
- Microsoft Anti-Cross Site Scripting Library V4.2 (AntiXSS V4.2)
- Microsoft Web Protection Library
Escape quotes, filter out the word javascript, restrict the allowed letters, etc.
You might want to just read through the OWASP guidelines on XSS.
This additional page at OWASP should be useful to, it deals with the encoding issues in our discussions below.
Since you want current best practices and the latest answer here is August 2012, I thought I might as well weigh in and update this.
Best practises to prevent any type of XSS attack (persistent, reflected, DOM, whatever).
- Strictly validate all input. For example, if you're asking for a UK postcode ensure that only letters, numbers and the space character is allowed. Do this server-side and if validation fails, display a message to the user so that they can correct their input. Do this for all variables outside of your control, including query string, POST data, headers and cookies.
- Add yourself some security headers. Namely
X-XSS-Protection: 1; mode=blockto activate reflective XSS browser protection into blocking mode instead of filtering mode. Blocking mode stops attacks like this. Edit 2021-01-28: This header is now deprecated due to browsers like Chrome discontinuing their inclusion of XSS auditors.X-Content-Type-Options: nosniffto prevent JavaScript being inserted into images and other content types.Content-Security-Policy:with strictscript-srcandstyle-src's at least. Do not allowunsafe-inlineorunsafe-eval. This is the daddy of headers for killing off XSS.
- Follow the rules in the OWASP XSS (Cross Site Scripting) Prevention Cheat Sheet when outputting values, however for rule #3 I'd do the following instead:
- Use HTML data attributes to output anything dynamic on the page.
- e.g.
<body data-foo="@foo" /> - Where
@foowill output an HTML encoded version of the variable. e.g." />would give<body data-foo="" />" /> - Grab these values out using JQuery or JavaScript:
var foo = $("body").data("foo"); - This way you don't need to worry about any double encoding, unless your JavaScript later inserts as HTML, however things are still simpler as you deal with the encoding there too instead of mixing it all together.
- Use a function like below to HTML encode if you're using
document.write, otherwise you could introduce a vulnerability. Ideally though usetextContentor JQuery'stext()andattr()functions.
Tackle these in reverse order. Concentrate on #3 as this is the primary mitigation for XSS, #2 tells the browser not to execute anything that slips through and #1 is a good defence-in-depth measure (if special characters can't get in, they can't get out). However, #1 is weaker because not all fields can be strictly validated and it can impair functionality (imagine Stack Exchange without the ability to allow "<script>" as an input).
function escapeHtml(str) {
return String(str)
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'")
.replace(/\//g, "/")
}
No. The best way to prevent it is to ensure that all the information you output onto the page is appropriately encoded.
Some possible examples of why angle brackets (and other special character blocking) is insufficient:
https://security.stackexchange.com/questions/36629/cross-site-scripting-without-special-chars
One of the biggest problems with preventing XSS is that a single webpage has many different encoding contexts, some of which may or may not overlap. There's a reason double-encoding is considered inherently dangerous.
Let's see an example. You prohibit < and >, so I can no longer input a HTML element in your page, right? Well, not quite. For example, if you put the text I loaded into an attribute, it will be interpreted differently:
onload="document.write('<script>window.alert("Gotcha!")</script>')"
There's plenty of such opportunities, and each needs their own variant of correct encoding. Even encoding the input as proper HTML text (e.g. turning < into <) may be a vulnerability if the text is then taken in javascript, and used in something like innerHTML, for example.
The same kind of issue occurs with any kind of URL (img src="javascript:alert('I can't let you do that, Dave')"), or with embedding user input in any kind of script (\x3C). URL is especially dangerous, since it does triple encoding - URL encoding, (X)HTML encoding and possibly JavaScript encoding. I'm not sure if it's even possible to have user input that is safe under those conditions :D
Ideally, you want to limit your area of exposure as much as you can. Do not read from the generated document unless you trust the user (e.g. an admin). Avoid multiple encoding, and always make sure you know exactly where each potentially unsafe encoding goes. In XHTML, you have a great option in CDATA sections, which make encoding potentially dangerous code easy, but that might be interpreted incorrectly by browsers that don't support XHTML correctly. Otherwise, use a proper documented encoding method - in JS, this would be innerText. Of course, you need to make sure that your JS script isn't compromised due to user data.
Greetings, I am working on web app where i have back end utilizing spring And front end utilizing JavaScript And jQuery. I need to implement total xss protection on the front end side. How do you handle xss to make your app Safe? Would you recommend any libraries which can be used to filter input And other things related to xss (these libraries should be safe) Or how do you usually defend against xss when you Are developing such application ? Thank you