Blazor with SignalR - how is an XSS or other attack possible when storing and rendering plain string text? - security

In a Blazor Server with SignalR chat app, I'm taking user input in an <input> element, binding it to a string in the #code section, and storing that string in the db as a parameterized query. I believe this is enough to prevent a 1st order sql injection.
I'm displaying the same string back to the user on the frontend, and all other users connected to the chat app, both via SignalR and also later on page reload from the string being retrieved from the db, via simply rendering it as a string again (the strings are saved to a string array, loops in the .razor file, and rendered in a <p> tag), example:
<ul id="messagesList">
#foreach (var message in userInputtedMessages)
{
<li>#message</li>
}
</ul>
From all the research I've done, I believe my implementation may be vulnerable to XSS attacks, but I can't see how, since whatever HTML or javascript, or C# code I input there as a message, it's simply rendered as plain text.
I'm not using any form of input/output sanitzation, but merely storing the input as a string, parsing it as a parameterized query into the sql db, where its only use is to be used for the frontend again as a displayed message (also a string).
Is this vulnerbable to XSS? And in particular if it is, could an example please be given as to how this is so? My understanding of an actual XSS attack like this is limited and I cannot see what the issue is other than many posts saying "always sanitize output", etc.
My question is why? How is this vulnerable?

As a general rule of thumb, you should always take steps when processing user input, so the advice is sound. Some frameworks (such as ASP.NET Core) put protections in place on your behalf.
By default, Razor HTML encodes all strings that it is asked to render. This mitigates against XSS attacks. You have to take steps to bypass this protection to render the string as raw HTML by casting to MarkupString in Blazor or using HTML.Raw() in Razor Pages/MVC. At that point, you should take responsibility for any sanitising that your application requires.

Related

Prevent XSS in NodeJS API output

I'm familiar with using templates in NodeJS like EJS to escape data for an HTML context.
However what would be the recommended way to safely output from an API? Given the intended usage is not known, it couldn't be escaped using HTML encoding.
Since I'm currently basically just doing res.json({}) for the output.
I'm thinking while some fields of incoming data can be validated (like 'email'), other fields that are more vague (like 'description') could contain any of the characters someone might use for XSS. Like < and ;. The options on OWASP seem limited https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html Like this, but it was last updated 7 years ago https://github.com/ESAPI/node-esapi
Is it up to the recipient to handle? So if someone sends "alert(0);" as their description, I allow it through, as that is a valid JSON {"description":"alert(0);"}
If someone wants to send <script>tweet(document.cookie)</script> in a description let them do so. They may have perfectly valid and legitimate reasons to do that. Perhaps they're writing an article about security and this is just an example of an XSS attack.
This isn't a threat to your database but to your web pages.
Security is neither a server-only nor a client-only job. It's a bit of both and the way you mitigate threats depends on the context.
When writing to a database, it's not XSS you have to worry about but things like SQL injection for example.
XSS is a threat for web applications and the way to mitigate that threat is to properly encode and/or escape any user-controlled input before it gets into the DOM.

Where to prevent HTML and script injection?

In web applications in order to prevent HTML and script injection, should I escape user input:
On the client before sending it to the server.
On the server before saving it to the database (on which layer - business, data, web interface?).
On the server before sending it back to the client.
On the client before rendering.
All or some of the above.
?
Escape all input at point of entry, also use a class based structure. If you have functions which are reused often, also escape here.
Any point where the server gets information from the client is a vunerable point, so protect each one you find.
You should treat all user input as dirty and do either:
Validate input strictly (only white listed values accepted)
Validate input loosely every time you intend to use it. This means you validate it for sql injections when you insert it into the db everytime, not just the first time. This means that if you get something from the db which was once user input, the next time you re-insert it into the db, you must still treat it as user input as validate it. And when you push it to the client you need to validate it as client safe (xss, js, html, css) as well.

what's the scenario of stealing information with XSS on a POST request

I understand the scenario of stealing information with XSS on a GET post as below workflow:
Hacker identifies a page from a web application with vulnerability of being XSS injected through query string parameters.
Hacker composes a url with XSS injected query string appended.
Hacker sends the url to a victim, for example, by email.
Victim receives the mail and clicks on the url (suppose the victim has less knowledge of security).
The opened web page has XSS injected, any further action on the page could result in a security issue.
This is possible because clicking on the url link will open the web page in GET mode. So, I am wondering if the page is XSS vulnerable for POST request, will it be a security issue? I could not figure out a "reasonable" attack workflow.
So, I am wondering if the page is XSS vulnerable for POST request, will it be a security issue?
Of course it would be. Why should the method via which external code is embedded matter at all? That it does happen is the problem, not how.
I could not figure out a "reasonable" attack workflow.
Consider a simple HTML form, that gets pre-populated with the previous user input after a failed server-side validation.
If this pre-popuplating allows XSS (basically meaning, escaping all data before outputting it in an HTML context was neglected) – then I could easily set up a form in my own page, have its action attribute point to your form handling address, and pass any data I like via hidden fields – and have to user send that data to your server via a simple submit button, that is maybe formated to look just like a normal link, and only saying “click here to go to example.com”. The user expects that to just ”normally” open a page like any other link – but in reality it send values that triggers displaying the form with pre-populated fields again.
Et voilà, XSS attack successfully performed.
(All that under the premise that the target site does not have additional security against “foreign” form data in place.)
The attacker could also build a 'data:' URL containing an auto-submitting form:
data:text/html;base64,PGh0bWw+CiAgPGJvZHkgb25sb2FkPSJkb2N1bWVudC5mb3Jtc1swXS5zdWJtaXQoKSI+CiAgICA8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iaHR0cDovL2xvY2FsaG9zdCI+CiAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImVybnN0IiB2YWx1ZT0iPHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4iPgogICAgPC9mb3JtPgo8L2h0bWw+
which is equivalent to navigating to a page containing this markup:
<html>
<body onload="document.forms[0].submit()">
<form method="post" action="...">
<input type="hidden" name="ernst" value="<script>alert('XSS')</script>">
</form>
</html>
Just went through this exact issue while performing a penetration test for a client. When reporting, we usually try to show a proof of concept exploit using a GET request as this is much easier. Remember too that some servers may allow you to change a POST to a GET request. Some servers will also accept POST parameter values in a URL. In my most recent experience, the server would only accept a request as a POST with the input entered into the form fields. The only thing that stopped an XSS attack was the fact that they had Cross Site Request Forgery prevention in place (via ViewState). So, in this case, it is simply a reflection fault. Still not good, but not as bad. You should ALWAYS use both ingress and egress filtering and NEVER trust user-controllable data.

What is cross site scripting?

On this site (archived snapshot) under “The Theory of XSS’, it says:
the hacker infects a legitimate web page with his malicious client-side script
My first question on reading this is: if the application is deployed on a server that is secure (as is the case with a bank for example), how can the hacker ever get access to the source code of the web page? Or can he/she inject the malicious script without accessing the source code?
With cross-site scripting, it's possible to infect the HTML document produced without causing the web server itself to be infected. An XSS attack uses the server as a vector to present malicious content back to a client, either instantly from the request (a reflected attack), or delayed though storage and retrieval (a stored attack).
An XSS attack exploits a weakness in the server's production of a page that allows request data to show up in raw form in the response. The page is only reflecting back what was submitted in a request... but the content of that request might hold characters that break out of ordinary text content and introduce HTML or JavaScript content that the developer did not intend.
Here's a quick example. Let's say you have some sort of templating language made to produce an HTML page (like PHP, ASP, CGI, or a Velocity or Freemarker script). It takes the following page and substitutes "<?=$name?>" with the unescaped value of the "name" query parameter.
<html>
<head><title>Example</title></head>
<body>Hi, <?=$name?></body>
</html>
Someone calling that page with the following URL:
http://example.com/unsafepage?name=Rumplestiltskin
Should expect to see this message:
Hi, Rumplestiltskin
Calling the same page with something more malicious can be used to alter the page or user experience substantially.
http://example.com/unsafepage?name=Rumplestiltskin<script>alert('Boo!')</script>
Instead of just saying, "Hi, Rumplestiltskin", this URL would also cause the page to pop up an alert message that says, "Boo!". That is, of course, a simplistic example. One could provide a sophisticated script that captures keystrokes or asks for a name and password to be verified, or clears the screen and entirely rewrites the page with shock content. It would still look like it came from example.com, because the page itself did, but the content is being provided somewhere in the request and just reflected back as part of the page.
So, if the page is just spitting back content provided by the person requesting it, and you're requesting that page, then how does a hacker infect your request? Usually, this is accomplished by providing a link, either on a web page or sent to you by e-mail, or in a URL-shortened request, so it's difficult to see the mess in the URL.
<a href="http://example.com?name=<script>alert('Malicious content')</script>">
Click Me!
</a>
A server with an exploitable XSS vulnerability does not run any malicious code itself-- its programming remains unaltered-- but it can be made to serve malicious content to clients.
That attacker doesn't need access to the source code.
A simple example would be a URL parameter that is written to the page. You could change the URL parameter to contain script tags.
Another example is a comment system. If the website doesn't properly sanitize the input/output, an attacker could add script to a comment, which would then be displayed and executed on the computers of anyone who viewed the comment.
These are simple examples. There's a lot more to it and a lot of different types of XSS attacks.
It's better to think of the script as being injected into the middle of the conversation between the badly coded web page and the client's web browser. It's not actually injected into the web page's code; but rather into the stream of data going to the client's web browser.
There are two types of XSS attacks:
Non-persistent: This would be a specially crafted URL that embeds a script as one of the parameters to the target page. The nasty URL can be sent out in an email with the intent of tricking the recipient into clicking it. The target page mishandles the parameter and unintentionally sends code to the client's machine that was passed in originally through the URL string.
Persistent: This attack uses a page on a site that saves form data to the database without handling the input data properly. A malicious user can embed a nasty script as part of a typical data field (like Last Name) that is run on the client's web browser unknowingly. Normally the nasty script would be stored to the database and re-run on every client's visit to the infected page.
See the following for a trivial example: What Is Cross-Site Scripting (XSS)?

Cakephp Security

I am new to Security of Web apps. I am developing an application in Cakephp and one of my friends told me about the Cross-site request forgery (CSRF) and cross-site scripting (XSS) attacks etc. not sure how many more are there.
I need some help in understanding how to make Cakephp defend my web app against these. we are low budget and we cant hire a security consulant as of now. We are still developing the app and plan to release in by the end of the month. so wanna take care of the initial stuff that can help me stand un hacked ;)
There is not (and cannot be) one tool you can deploy and then never have to think about security again. Deploying ‘anti-XSS’ hacks like CakePHP's Sanitize::clean will get in users' way by blocking valid input, whilst still not necessarily making the app secure. Input filtering hacks are at best an obfuscation measure, not a fix for security holes.
To have a secure web application, you must write a secure web application, from the ground up. That means, primarily, attention to detail when you are putting strings from one context into another. In particular:
any time you write a string to HTML text content or attribute value, HTML-escape it (htmlspecialchars()) to avoid HTML-injection leading to XSS. This isn't just a matter of user input that might contain attacks, it's the correct way to put plain text into HTML.
Where you are using HTML helper methods, they should take care of HTML-escaping of those elements by default (unless you turn off escape); it is very unfortunate that the CakePHP tutorial includes the bad practice of echoing unescaped strings into HTML for text outside of HTML helpers.
any time you create SQL queries with string values, SQL-escape it (with an appropriate function for your database such as mysql_real_escape_string).
If you are using CakePHP's ORM and not writing your own SQL you don't have to worry about this.
avoid using user input (eg file upload names) to name files on the filesystem (generate clean unique IDs instead) or as any part of a system() command.
include the Security component to add a form submission token scheme that will prevent XSRF on forms generated by CakePHP.
Cake can be secured relatively easy (compared to self written php scripts):
http://www.dereuromark.de/2010/10/05/cakephp-security/

Resources