I know how anti-forgery token in ASP.NET MVC works.But still not clear about few scenarios. One I mentioned below.
submit a post request with below information
cookie token(antiforgerytoken)
form data(first name & last name)
form input hidden token(antiforgerytoken)
Before reaching server a hacker modified form data(first name & last name) leaving token info unchanged.
In this scenario, how we can make sure the data submitted securely reached server without any modification
Actually this question is asked by an interviewer. I discussed with my colleagues and I searched in Google too. Since I couldn't find a clarity on this I thought to ask here.
I am not sure if this is a valid question.If yes,any help would be appreciated
Multiple things are mixed here. The confusion is around the purpose of different protections, so let me try and get that straight.
CSRF, and antiforgerytoken
The basic threat is the following. A victim user is logged on to the victim website victim.com. Meanwhile (say in another browser tab) he visits a malicious website malicious.com that wants to exploit CSRF in victim.com. For that, malicious.com has the user post the required parameters to victim.com to call a certain function which obviously victim user did not want to perform. This is the base case of CSRF, exploiting an existing user session, malicious.com performed something on victim.com via a victim user.
This is prevented, if for example antiforgerytoken is used, because malicious.com will not be able to send the right token to victim.com, so the request will be denied.
Note that this has nothing to do with legitimate request content.
Integrity of requests
A different problem is making sure the request is received as sent, ie. data is the same. This is usually achieved by using HTTPS, which provides message integrity and encryption (among others). So if HTTPS is used, such change of data in transit is not possible.
Of course if the attacker controls either the client or the server (more precisely, the TLS endpoint, which is not always the server), ie. anything outside the TLS channel, then the attacker can modify data. But that would mean having control over the client. For example you can do this if you run a local proxy (Fiddler, Burp, ZAP Proxy, etc.) on your client - you can then change any data in the request, that's how penetration testers work. However, an attacker not having this level of control would not be able to do this.
Without HTTPS, request (and btw also response) integrity and encryption are problems that are hard to solve. The solution is HTTPS. :)
Related
I know that Request.Headers["Origin"] gets the origin header of a request, but this is changeable on the client-side by setting the header manually. Thus not that safe.
Is there such a value that contains the original, readonly/unchangeable origin of a request? Like the one CORS is using?
I need this value to check if the request is officially coming from the site it's supposed to come from. The trick is that I need it in the controller method to search an object in the database based on this value and a key only used for that site.
The problem with CORS is that it can whitelist a list of URLs but not check if the site and the key belong to each other, thus can whitelisted site 1 access the data of whitelisted site 2 if it mimics the Request.Headers["Origin"] and the key of site 2
Unfortunately (or perhaps fortunately?) there is no reliable way to check this from the data that the browser sends to your server. The user is able to forge any and all information that you receive from the browser.
This is why mechanisms that need to reliably determine the origin of a user use some sort of token mechanism, public/private signatures, certificates and the sort to determine it. Unfortunately this is never as simple as looking up some information that the browser provides you with, so it seems like you might need to redesign your whitelisting mechanism by relying on something else than origin, possibly implicating single-sign-on measures (like SAML). It's hard to provide further suggestions without more information on the underlying problem that the origin-check is intended to solve.
This question already has an answer here:
how AntiForgeryToken() works in MVC and how to retrieve value at server action method from AntiForgeryToken?
(1 answer)
Closed 7 years ago.
I'm a relatively new developer working on a C# MVC app, and serving different views to different people depending on what fields they should be able to see. That is, user 1 might see (and be able to enter data into) fields A, B, and C, whereas user 2 may only see field A.
My plan at the moment is to post the form back to a single action in my controller, but I was trying to figure out whether or not I need to protect against the possibility of user 1 modifying the form when (s)he gets it, adding fields B and C in the browser, and then sending it back to the server, in an effort to set values in the database that (s)he shouldn't have access to.
I'm told by someone else in the area that the AntiForgeryToken should protect against this type of attack, but my research implies that it only protects against a cross-site forgery attack, and I don't think this falls into that category. My question is this: Does the AntiForgeryToken protect against this situation? Or do I need to continue with the idea of "don't trust what the user sends you" and explicitly ignore those fields that the user doesn't have rights to use?
You are absolutely right that this is a problem. All the anti-forgery token does is to ensure the form is generated by your application, as opposed to being handcrafted. However, that doesn't mean it can't be tampered with afterwards.
As an example, say you have 2 users, who both have accounts with your application: GoodUser and NaughtyUser. They both use your application to request a specific form, that allows them to do something on the site (e.g. edit an auction). The difference between them is that GoodUser is only interested in editing an auction, but, as the 2 users are in direct competition with each other, NaughtyUser wants to sabotage GoodUser's auction.
To do that, NaughyUser decides to open a form to edit one of his own auctions. At this point, he has received a valid anti-forgery token in the form. So now NaughtyUser modifies the data on the form, the idea being to intentionally edit GoodUser's auction, and POSTs it to the server. The anti-forgery token on its own will absolutely not protect against that, because the token itself was generated via a legitimate source.
This is a different kind of attack, and something you definitely should be protecting against on the server-side.
It is quit simple. In order to protect our server from illegal requests we allow to submit forms that were made only by our server. It means that once ASP.NET server executes action method and prepare HTML for the client, it would sign your form with a encrypted token. When form submits, this server-generated token will be sent with form's data, and if you mark your action with validateantiforgerytoken attribute, then server will check form for this unique token. If it exists and token generated on this server, validation will be passed.
In the latest Asp.Net December 2013 Security updates Microsoft released a patch for ASP.Net - 'Insecure ASP.NET Web Forms (.aspx) configuration could allow remote code execution'. Related KB is 2905247
As I know ViewStateMac just used to be sure that this ViewState was generated by server, and not an attacker. But in security updates article they say:
If a web developer sets EnableViewStateMac=false for any page in his
site, an attacker could leverage this to upload and invoke arbitrary
executable code within the context of the web service account. This is
an example of a remote code execution (RCE) attack.
For example if I disable EnableViewStateMac for some aspx page, how it allows attacker to execute malicious code in context of my web application? As I understand in the worst case an attacker can spoof ViewState for some fake data\events\validation. But it will affect just this page. And I can't upload any malicious C# code via ViewState that will be executed. What are they mean by RCE attack in that case?
I can't find any further details of this vulnerability, so my answer only speculates to a possible attack vector.
The MAC is a signature of the ViewState value, and with EnableViewStateMac=true ASP.NET will check whether the MAC signature actually signs the ViewState value as authentic. This means that the ViewState value sent from the client in the __VIEWSTATE hidden field has been verified to come from the server.
Now imagine that the code processing the ViewState value is vulnerable to say object deserialisation. The Microsoft advisory states:
An unauthenticated attacker could send specially crafted HTTP content to the targeted server, potentially allowing the attacker to run code on the server in the context of the service account running on the ASP.NET site.
With EnableViewStateMac=true this vulnerability cannot be exploited because the MAC is validated before the ViewState value is processed. Any value that has not come from the server will be met with a Validation of viewstate MAC failed exception message.
However, with EnableViewStateMac=false the whole ViewState value could be manipulated by an attacker to exploit the buffer overflow/escape attack with privilege escalation and execute arbitrary code that is injected as a payload into the __VIEWSTATE field.
So in summary, as the ViewState value is no longer being validated it opens up the field to attack by this unpublicised attack vector.
By itself, it doesn't necessarily allow an attacker to run code, but if you act upon some input expecting it to be valid -- hidden field with values or something similar, then it could be the key they need.
I'm designing a site using ASPx and IIS, where clients can sign up and then offer services to their clients. For example:
if you go to http://www.mywebsite.com you can sign up for your mywebsite.com account as a business owner. When you sign up, you are given a Site ID (Example: AA1234).
http://www.mywebsite.com/AA1234
What I want to do is always include the Site ID in every url (Inbound and Outbound). The Site ID is stored in a session variable based on the initial incoming request.
Does anyone know of a good way to do this - or a different design that works better than this?
Thanks
Your question is nebulous at best. However...
Wouldn't this be what cookies are used for?
In particular, if your user is authenticated (this is generally achieved in asp.net with an auth cookie), then at the server, you would have tools at your disposal that allow you to recognize the user and provide a different experience according to whatever criteria you choose. Most likely, these details might be stored in a database.
Found the answer in this topic: http://www.tek-tips.com/viewthread.cfm?qid=1149673
The last response from BoulderBum is exactly what I needed.
Using the HTTP module I will take the /AA1234/ URL and point it to /Company/.
On the way out, I replace all instances of /Company/ with the site id again
I'm using a C# WebClient to post login details to a page and read the all the results.
The page I am trying to load includes flash (which, in the browser, translates into HTML). I'm guessing it's flash to avoid being picked up by search engines???
The flash I am interested in is just text (not an image/video) etc and when I "View Selection Source" in firefox I do actually see the text, within HTML, that I want to see.
(Interestingly when I view the source for the whole page I do not see the text, within HTML, that I want to see. Could this be related?)
Currently after I have posted my login details, and loaded the HTML back, I see the page which does NOT show the flash HTML (as if I had viewed source for the whole page).
Thanks in advance,
Jim
PS: I should point out that the POST is actually working, my log in is successful.
Fiddler (or similar tool) is invaluable to track down screen-scraping problems like this. Using a normal browser and with fiddler active, look at all the requests being made as you go through the login and navigation process to get to the data you want. In between, you will likely see one or more things that your code is doing differently which the server is responding to and hence showing you different HTML than a real client.
The list of stuff below (think of it as "scraping 101") is what you want to look for. Most of the stuff below is probably stuff you're already doing, but I included everything for completeness.
In order to scrape effectively, you may need to deal with one or more of the following:
cookies and/or hidden fields. when you show up at any page on a site, you'll typically get a session cookie and/or hidden form field which (in a normal browser) would be propagated back to the server on all subsequent requests. You will likely also get a persistent cookie. On many sites, if a requests shows up without a proper cookie (or form field for sites using "cookieless sessions"), the site will redirect the user to a "no cookies" UI, a login page, or another undesirable location (from the scraper app's perspective). always make sure you capture the cookies set on the initial request and faithfully send them back to the server on subsequent requests, except if one of those subsequent requests changes a cookie (in which case propagate that new cookie instead).
authentication tokens a special case of above is forms-authentication cookies or hidden fields. make sure you're capturing the login token (usually a cookie) and sending it back.
POST vs. GET this is obvious, but make sure you're using the same HTTP method that a real browser does.
form fields (esp. hidden ones!) I'm sure you're doing this already, but make sure to send all form fields that a real browser does, not just the visible fields. make sure fields are HTML-encoded properly.
HTTP headers. you already checked this, but it may make sense to check again just to make sure the (non-cookie) headers are identical. I always start with the exact same headers and then start pulling out headers one by one, and only keep the ones that cause the request to fail or return bogus data. this approach simplifies your scraping code.
redirects. These can either come from the server, or from client script (e.g. "if user doesn't have flash plug-in loaded, redirect to a non-flash page"). See WebRequest: How to find a postal code using a WebRequest against this ContentType="application/xhtml+xml, text/xml, text/html; charset=utf-8"? for a crazy example of how redirection can trip up a screen-scraper. Note that if you're using .NET for scraping, you'll need to use HttpWebRequest (not WebClient) for redirect-dependent scraping, because by default WebClient doesn't provide a way for your code to attach cookies and headers to the second (post-redirect) request. See the thread above for more details.
sub-requests (frames, ajax, flash, etc.) - often, page elements (not the main HTTP requests) will end up fetching the data you want to scrape. you'll be able to figure this out by looking which HTTP response contains the text you want, and then working backwards until you find what on the page is actually making the request for that content. A few sites do really crazy things in sub-requests, like requesting compressed or encrypted text via ajax, and then using client-side script to decrypt it. if this is the case, you'll need to do a bit more work like reverse-engineering what the client script is doing.
ordering - this one is obvious: make HTTP requests in the same order that a browser client does. that doesn't mean you need to make every request (e.g. images). Typically you only need to make the requests which return text/html content type, unless the data you want is not in the HTML and is in an ajax/flash/etc. request.
(Interestingly when I view the source for the whole page I do not see the text, within HTML, that I want to see. Could this be related?)
This usually means that the discrepancy is caused by some DOM manipulations via javascript after the page has loaded. Try turning off javascript and see what it looks like.