When submitting an HTTP post using Objective-C to a server, the required form data entries include __VIEWSTATE, __EVENTVALIDATION, username, and password. I get the user's username and password programmatically through the iOS application, but I hard-code the __VIEWSTATE and __EVENTVALIDATION parameters by looking at their entries through Google Chrome Developer Tools. The problem is that once the __VIEWSTATE and __EVENTVALIDATION parameters change, my app is defunct.
Is it possible to get the __VIEWSTATE and __EVENTVALIDATION parameters programmatically, possibly by storing them in a cookie, or can I send a POST request without them? Do I need to integrate a JavaScript function into my Xcode project?
It's strongly related to your server-side logic because it's a deal of client and server applications how to use this parameters, but in in most cases VIEWSTATE paramater is given to you at previous request. You should not send it with first request. For example:
request1, authorization — sending username, password. This will (may) return you VIEWSTATE.
request2 — sending VIEWSTATE from request1 and other parameters. This will (may) return you new VIEWSTATE.
request3 — sending VIEWSTATE from request2 and other parameters. This will (may) return you new VIEWSTATE.
...
I'm not aware about __EVENTVALIDATION parameter but you can inspect actual traffic from browser using debugging proxy tool such as Fiddler and try to find out logic of it's usage.
Related
This tutorial for building API's with Devise recommends using headers to send over the login email and API token vs. embeding them as URL parameters.
Rather than sending the data over parameters, we're expecting the client application to send it via two headers: "X-API-EMAIL" and "X-API-TOKEN"; this cleans up the endpoint URIs.
Can someone elaborate on what it means to "clean up" theWhat are the the advantages of requiring authentication via headers vs. having the client embed them as parameters in the URL?
I think by "clean up" they just mean that the URLs are tidier and only contain information about the resource being requested/updated/...
It's common to use this approach -- it can be argued that it's conceptually nicer to keep what you are requesting somewhat separate from the details of your credentials for making the request. The "Authorization" HTTP header is a standard one to use for credentials (e.g. HTTP Basic Auth http://en.wikipedia.org/wiki/Basic_access_authentication#Client_side, AWS API http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#ConstructingTheAuthenticationHeader and many more).
It also removes the possibility of clashes between your credential parameters and other parameters. For a trivial example, imagine you use password for your credential password and also want a normal parameter called password for a particular API call (when you're updating another user perhaps). You can't have that - one of them has to be named differently. Ok, you can easily do that, but it's a little artificial, and if you instead supply the password for the credentials in the Authorization header, you are free to have a parameter called password which relates to the actual request you are making (e.g. the new password you're setting for some other user).
I use asp.net mvc controller instead of Web Service in my project.
When I call the controller from my client app,there will be a authentication problem. If I use Web Service ,I can use SOAP Header , but now in asp.net mvc, There is no soap header.
Please help.
I am really know a little about the web security.
Normal way of doing this when you come to http services is to pass it in authorization header in following format (if you are doing request from fiddler)
Authorization: Basic user123:pass123
user123:pass123 string is normally base64 encoded and you have to decode it on server side, check it against user store and authenticate the user. One example can be found here
You have several options.
Use a request header to contain some security token.
Include security tokens in the message that you send in the request body.
If your application uses something like Forms Authentication, you can ask consumers to call a login action, then grab the Forms Auth cookie and include that cookie in subsequent calls.
Since you are not using soap. You may use a simple http way. Which means you start a HttpRequest and handle result via HttpResponse. Thus you have to simulate a authenticate action as signing in from web browser.
You need to get the security token or cookie from the reponse. And put them into your following request. Thus your controller will recognize the request's identity.
I am using MVC3. I have a couple of pages which does not require authentication but these pages have querystrings which could be tampered. I am planning to encrypt these urls when sending to users and decrypting it back when they hit it, what is the best way to encrypt and decrypt query strings in MVC3? Send me a pointer If there is any module that I can reuse...
Why dont you trust in another kind of storage mechanism instead of a query string?. You could pass the information over a POST operation, there are several ways to do that, such as cache or other. Post automatically puts that information on the request header, and its hidden to the ussers, also if your site is over SSL connection, that information is encripted.
You could improve security to your site against malware petitions with integrated MVC security features, such #Html.AntiForgeryToken(), this prevents that a malitious site tries to bypass your system impersonating a real petition. In a nut shell this means that a unique ID is printed on the form header when the form is sent to the client, and if the ID does not equals the one that the server expects, simply the request is ignored.
Heres an interesting post that could help you.
https://sites.google.com/site/muazkh/asp-net-mvc-security-and-hacking-defense-in-depth
Best regards!
I have a problem with the anti CRSF MVC mechanism. The cookie and the form input returned does not match. I'm getting an error every single time, only in one specific page. In the rest of the application it works well.
The server is returning HTTP 500 Internal Server Error and I can see on the log this exception:
[System.Web.Mvc.HttpAntiForgeryException]: {"A required anti-forgery
token was not supplied or was invalid."}
This is the hidden input that the server is generating is:
<input name="__RequestVerificationToken" type="hidden" value="QK8P7rjyZE6Vm5seY7Fr704YCOoFGdTIMzl1W7R0ZFpXSMjGKLG2T05DfFSYTxvtQCEx7DDT69DGsDB2+ZXFHY8oAjiKz0gw8BhDFywgmfIpoXnGpj7fONNzIIfvbrDrE9WJsMu6Io/0bDLM5WfKs0zktiNjyOWpfYrmnfINYmjW8NLOZFoz74xTcgTptAld">
And this is the Cookie returned:
Set-Cookie:__RequestVerificationToken_L2VGbG93=skmTAVI8HCbfxDS+xhioIMIISL3UOBI7qJM1JbHjTtAqKl4W70pDUcTKMm0p3R3mrHDziE8vXw0C0OO4HArzWO1/e6py+v/cFdbe9maFgjl4jMiZ9Wc4YIhC6+IUXkk6yqJDJ8dCIr8qtGaYcD9IX+m7/SlVhu521KQSWJYRcaY=; path=/; HttpOnly
When I examine what the server is sending, the cookie is exactly the same, but the payload has different encoding I think:
__RequestVerificationToken:QK8P7rjyZE6Vm5seY7Fr704YCOoFGdTIMzl1W7R0ZFpXSMjGKLG2T05DfFSYTxvtQCEx7DDT69DGsDB2%2BZXFHY8oAjiKz0gw8BhDFywgmfIpoXnGpj7fONNzIIfvbrDrE9WJsMu6Io%2F0bDLM5WfKs0zktiNjyOWpfYrmnfINYmjW8NLOZFoz74xTcgTptAld
The differences are in two characters that appear encoded:
/ -> %2F
+ -> %2B
Those are the only differences I can find between the hidden input field, and the post payload.
What could be the problem that is causing that ValidateAntiForgeryToken fails in verify the token?
Regards.
I've had and resolved several issues with ValidateAntiForgeryToken lately, so I'll share my findings with you.
Salt: Since you mention this only happens on a single page, my best guess is that you are using different salt values in your calls to Html.AntiForgeryToken(salt) and ValidateAntiForgeryToken(salt) calls.
AJAX: as another answer has said, using AJAX may require extra work to ensure the token is included in the POST. Here is my favorite simple, automatic solution to add the token to all AJAX POST requests.
In your question though, you state that you have verified that the token is sending. Have you verified that you're only sending the token once? I found out that an AJAX call of mine was sending the token twice, which combined the values, and caused it to fail.
Machine Key and Cookies: this issue is ugly, easy to spot (causes exceptions), but not very intuitive. The validation cookies and tokens are encoded and decoded using a unique "machine key". This means that if you have a server farm, or change your server, your cookie will no longer be valid. Closing your browser fixes the issue (because the cookie is a session cookie). However, some people leave their browser windows open in the background for a long time!
The solution is to set a "machine key" in your config file. This will tell MVC to use the same key on all servers, ensuring that the cookie will be decryptable everywhere.
Encoding Bugs: using a testing utility called jMeter, we attempted to load-test our pages, only to find out that it had a bug that caused our token to have 2 extra " around the value.
The solution is to lower your trust in your tools! Test in a browser, and if that works, create a test that extracts the token and cookie values, and set a breakpoint to verify the results.
If none of these things work for you, then I'd recommend taking a look at the MVC source code for ValidateAntiForgeryTokenAttribute, specifically the OnAuthorization method. It will help you see the different steps where validation could fail. You might even inspect your error's Exception.StackTrace to determine which part is failing.
As a side note, I really dislike the implementation of ValidateAntiForgeryToken in MVC, because:
There are about 5 verification steps that can fail, but there is only one generic error message.
The class is sealed, so it cannot be extended with additional functionality.
The encryption method is weird - it initializes a Page and creates an artificial ViewState to encrypt the tokens and cookies. Seems overkill.
So, I grabbed the source code, and created my own specialized subclass, which also turned out to be very helpful in debugging its issues, because I could set breakpoints on the validation methods, and it was really easy to determine which validation step was failing.
If this is being sent as an Ajax request, then the current setup of the framework isn't build to do this naturally.
Luckly Phil Haak wrote a nice blog post on dealing with CSRF and Ajax -> Preventing CSRF With Ajax which goes into some good detail about how to use the existing framework and modify it to work for Ajax/Json.
From my recent findings ...
If you set content type as "application/x-www-form-urlencoded" in the ajax request then you must put the AFRT in the data
If you set the content type to "application/json" then the token goes in the ajax "headers" property as described by haack.
On the server if you are checking for the form type token then using the vanilla AntiForgeryRequestTokenAttribute is ok but if you want to validate tokens sent in the header then you need to call the AntiForgeryToken.OnAuthorize ... or whatever, passing the token from the cookie (http context).
It aint easy but if it was everybody would be doing it :)
I'm trying to login to a website (http://www.meo.pt/ver/Pages/login.aspx) from within my application so that I can access the program listing, etc, I searched in the page source code for the html for of the username textbox and password textbox input.
<input name="ctl00$SPWebPartManager1$g_cb264700_1517_426f_926d_3ca40934a6fd$ctl00$EditModePanel1$txtUserName"
type="text"
id="ctl00_SPWebPartManager1_g_cb264700_1517_426f_926d_3ca40934a6fd_ctl00_EditModePanel1_txtUserName"
class="forms_login" />
I used the value in name and set the content of that key with the username and the same form the password. Then made a POST request to http://www.meo.pt/ver/Pages/login.aspx from which I got a response containing the HTML source of the same page, so login wasn't successful. I don't think the server even considered it a login try.
My question is how should I set the POST request values to make this work?
I'm using ASIHTTPRequest for iPhone.
My guess is that it's cookie-related: the page sends a cookie when it appears and requires that cookie along with the username and password. Odds are good that every POST and GET returns a cookie along with the page content, a cookie you'll need to send back.
If you use ASIHTTPRequest to perform the requests and use the same instance of the object to make subsequent requests, it will take care of sending those revised cookies each time. I love this library and recommend it.
http://allseeing-i.com/ASIHTTPRequest/
If instead you're using an NSURLConnection and prefer to manage the cookies yourself, the NSHTTPCookie object will help.