Forms Authentication 4.0 on Web Farm - asp.net

This is quite literally driving me bananas - I'm on holiday as from tomorrow but if I can't get this working today then it's under threat - so any help much appreciated!
Firstly, my website has a manually defined <machinekey /> element defined so that both web servers in the web farm are kept in sync. I have verified this with IIS manager (hence why I'm asking, despite the similarity with so many other questions). It looks like this (keys elided - but they are the correct length):
<machineKey validationKey="[512 bit hex]"
decryptionKey="[256-bit hex]"
validation="SHA1"
decryption="AES" />
The website is running Asp.Net MVC3 and I am using Forms authentication in 'normal' mode (i.e. not 2.0 compat mode). I'm using Forms Authentication to create an authentication ticket - using code like the following:
FormsAuthentication.SetAuthCookie(userName, false);
My Forms Auth config is very simple; there are no IIS or server-wide settings in place that override the documented defaults:
<authentication mode="Forms">
<forms defaultUrl="~/Unauthorised"
loginUrl="~/Unauthorised"
ticketCompatibilityMode="Framework40" />
</authentication>
And then I've hijacked the cookie-reading functionality as per this MSDN topic so that I can create the principal and identity that I want.
Problem is - only one half of the web farm is able to decrypt the authentication cookie, the other half (i.e. whichever one didn't authenticate the user) just gives:
System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
With this as the top-part of the stack trace:
[CryptographicException: Length of the data to decrypt is invalid.]
System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) +12521039
System.Security.Cryptography.CryptoStream.FlushFinalBlock() +53
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType) +331
System.Web.Security.FormsAuthentication.Decrypt(String encryptedTicket) +293
We are using a slightly ancient (but very reliable) Load balancer - which does not modify the HTTP traffic - and the traffic in this case is HTTPs; I'm able to verify that it's always one server and not both by having used Fiddler to decrypt and inspect the traffic.
This clearly points to out-of-sync machineKeys - but they are not - so any idea what's going on!!?
Thanks in advance!

When different servers have different patches, it has the potential to alter the behavior of encryption (/decryption), therefore possibly causing this runtime exception:
System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
More information regarding this issue can be found here: http://blog.evonet.com.au/post/SystemSecurityCryptographyCryptographicException-Length-of-the-data-to-decrypt-is-invalid.aspx

Related

ViewState Encryption doesn't work with mixed algorithms

I have a client who wants to turn on ViewState encryption in an ASP.NET Web Forms application. They are not able to use the default algorithms because of FIPS compliance. The initial request from the client was to use 3DES/AES as follows, which I added to the web.config file:
<machineKey validationKey="..." decryptionKey="..." validation="3DES" decryption="AES" />
Putting in this configuration caused the application to stop working with the following error:
[HttpException (0x80004005): Unable to validate data.]
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType, Boolean signData) +1090
System.Web.UI.Page.EncryptString(String s, Purpose purpose) +150
[...]
By switching both keys to 3DES, I was able to get the system working.
Why does the system fail when the two different algorithms are used?
Not quite sure why that's failing - perhaps some error with the length of the key provided? The inner exception should be able to tell you more if there's one present.
Regardless, you should be aware that 3DES is being phased out by NIST and that ASP.NET does not use 3DES in a FIPS-compliant fashion. (Reference: http://csrc.nist.gov/publications/nistpubs/800-67-Rev1/SP-800-67-Rev1.pdf. See in particular the foreword, which states that we're in a transitional period for customers to move off of 3DES and on to AES. Also see Section 3.5; ASP.NET does not limit the number of invocations of the block cipher algorithm, so our particular usage of this algorithm makes it non-FIPS-compliant.)
The best course of action would be to use AES for encryption / decryption and HMACSHA256 for validation. This combination is FIPS-compliant and provides better security than 3DES / SHA1 (which is what was being used earlier). To do this, set:
<machineKey validation="HMACSHA256" validationKey="256 bits worth of hex digits (64 hex chars)" decryption="AES" decryptionKey="256 bits worth of hex digits (64 hex chars)" />
Then also set <pages viewStateEncryptionMode="Always" /> in Web.config to tell ASP.NET to use view state encryption using the algorithms you just provided in the <machineKey> element.

Decrypting data that was encrypted with FormsAuthentication.Encrypt

I am encrypting data into a cookie via FormsAuthentication.Encrypt(data) in a .Net 4.0 ASP.Net web application deployed on a development web farm. I have specified a machineKey attribute to hard-code the ValidationKey, DecryptionKey, and Decryption (algorithm).
Now, I am trying to decrypt that cookie using an application i built on my development workstation. I am able to get the cookie via Request.Cookies["CookieName"] but when I attempt to decrypt the value via FormsAuthentication.Decrypt(encCookie), I get the following error:
Unable to validate data. at
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean
fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length,
Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType,
Boolean signData) at
System.Web.Security.FormsAuthentication.Decrypt(String
encryptedTicket) at TuoVanitySite.Default.Page_Load(Object sender,
EventArgs e) in
c:\src\ets_2008\main\ebtDev\Sandboxes\rrozinov\TuoVanitySite\TuoVanitySite\Default.aspx.cs:line
22
Here is blurp from my web config (keys were removed):
<machineKey
validationKey="keyA"
decryptionKey="keyB"
decryption="3DES"
compatibilityMode="Framework20SP1"/>
Anyone has dealt with this situation where machineKey was not enough?
Ok, I was able to find a solution for my problem however i am not sure why this works.
I had to add the validation attribute to the machineKey:
<machineKey
validationKey="keyA"
decryptionKey="keyB"
validation="SHA1"
decryption="3DES"
compatibilityMode="Framework20SP1"/>
What makes it a bit interesting is the fact that regardless whether i put SHA1 or 3DES, my code can decrypt just fine. I did confirm that server is using default SHA1. I am still open to find a root cause for educational purposes.
as is mentioned in the "How To: Configure MachineKey in ASP.NET 2.0" article :
HMACSHA1 is used even if validation is set to AES or 3DES
So it may be the case that if the compatibility mode is set to Framework20SP1 or Framework20SP2 then it uses SHA1 regardless of what is set in the validation attribute.
I'm struggling with similar task at the moment - setting up single sign on between ASP.Net 4.0 and 3.5SP1 web applications that are deployed on IIS8 on Windows Server 2012. It gets more complicated because Win2k12 has .Net 4.5.1 which is an "in-place" upgrade to 4.0...

Viewstate Validation fails in web-farm - Usual suspects eliminated

I think that I've tried all of the standard responses to this problem, and I know that I've read hundreds of questions and posts about this problem, but none of them seem to have resolved it or shed any light on what the cause is in my scenario. (I'm 5 hours down and no nearer :-( )
I have a web-farm of 2 servers.
I have set the machine key and validation key in machine.config on both machines
Encryption: SHA1, Decryption: AES - These are the defaults, could it help to change them?
I have verified that no other config files in the chain (web.cfg, apphost etc.) have a setting for these values.
I have added a page to the site (based on this SO) that spits the machine key values back out, and verified that they are the same across requests to both machines and match the values that are in machine .config
The server side session state is in a shared state-server, I have verified that sessionid remains constant between requests to the 2 servers.
I have verified that the page is completely loaded and the __EVENTVALIDATION hidden field has been rendered into the page before initiating the post. The viewstate size is not too bad at 7.64kb
When a page is rendered from a request to server 1 and then posted back to server 2, I get the dreaded...
Error Message:
Unable to validate data.
at System.Web.Configuration.MachineKeySection.GetDecodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) HttpApplication.RecordError => HttpApplication.RaiseOnError => global_asax.Application_Error
The post is triggered by a standard, unadulterated asp linkbutton, there is no ajax going on on the page.
Any and all help will be greatly appreciated.
Setting enableViewStateMAC = false is not a solution :-)
Having inherited the servers in the state that they were configured, I never questioned the validity of the keys!!! ...Just checked that they matched on both servers...
Leaving all the encryption / decryption and validation algorithm settings as they were, I generated new keys using this tool which has a few more options than the others.
Problem solved
Moral of the story: If in doubt, generate new keys
... but why and how? Some postbacks with viewstate were working just fine with the old keys, it was only when the postback was to a different server that the problem became evident. If the keys were invalid - missing a character or something - then every postback should have failed - I think
If you've established that the machine keys are the same on both boxes, could it be the encryption/decryption thereof ?
Have you tried using Triple DES and setting the decryptionKey in the machine.config on both servers?
Check here
Also a easy way of making sure the machineKeys are the same is to add a line like this in the web.config.
NB: Assuming you have the same web.config on both servers and making sure that the validationKey and decryptionKey is valid
You can use http://aspnetresources.com/tools/machineKey to generate it.
<system.web>
<machineKey validationKey="*D9B0EDEA69D81A89BF5FBA2B08BAF691013F86B89A1F6BA8068C6ECC9539074" decryptionKey="*AE2B1966AF65D08F03EDFB" validation="SHA1" decryption="AES" />

ViewState and Security Settings generating errors

I have an odd reoccurring error that I believe is related to View State and security settings. This error appears on one of my client’s site between 1 to 6 times a day:
Source: System.Web
Error in: /detail.aspx?CaseID=1852
Error Message: Unable to validate data.
Stack Trace: at System.Web.Configuration.MachineKeySection.**EncryptOrDecryptData(**Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
Researching online has lead to a deadend. I believe it has do with security and ViewState. Because this is an ecommerce site, I took the extra steps of protecting against a number of treats, includign XSS and CSFR. Here are the steps I took:
Turned on HTTPOnly Cookies (Protects against XSS Style Attacks)
Turned on Secure Cookie Flag (Protects against XSS Style Attacks)
Created a BasePage which all the pages inherit instead of Page, in the Basepage I overrides OnInit and set ViewStateUserKey to SessionID (Protects against certain CSFR Style Attacks)
Explicitly enabled validateRequest (On by default, but can be overwritten)
ViewState Encryption Enabled
The website is hosted on a Win2003 Virtual Server, using ASP.NET 3.5 SP1 and AJAX. The page is not using caching, which some articles I found suggested was a problem when you set the ViewStateUserKey key to a unique value, such as SessionID. I can duplicate this exact error if I turn off cookies in my browser and try to view one of the pages that creates the error.
Notes, The error message does NOT mention MAC has failed
My theory is that those that experience this error are on networks that have a Proxy/Caching Server. My solution was to only set the ViewStateUserKey when it was a secure connection. Most Proxy/Caching Servers are only set to cache HTTP connections, not secure connections.

Is this an attempt to break my ASP.Net site's security?

I am fairly new to ASP.NET. I recently set up automated email from my website to notify me of an unhandled exceptions. Just a few hours ago in 3 minutes there were 10 unhandled exceptions and all stack traces were similar. There is a lot in the error messages I do not understand, but I do not like the way this looks.
Here is one of the email messages:
An unhandled exception occurred:
Message: Padding is invalid and cannot be removed.
Stack Trace:
at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.UI.Page.DecryptStringWithIV(String s, IVType ivType)
at System.Web.Handlers.AssemblyResourceLoader.System.Web.IHttpHandler.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Is this an attempt to hack into my site or something else?
Many thanks go to those who provided Answers and Comments provided which pointed me in the right direction to get an answer to this exception. It's cause can be difficult to determine, especially when not occuring in a web farm.
IE 5.5 was not causing the problem as I had earlier thought.
It was not easily found, but a post on my web host forum by one of the staff mentioned reports of Viewstate errors. The cause was attributed to the asp worker process or the server recycling.
The asp worker process settings refers to the processModel Element in the machine.config file. See http://msdn.microsoft.com/en-us/library/7w2sway1(VS.80).aspx for more information.
The recommended fix was to set an encrypted machineKey in the web.config file. The Machine Key node is in the system.web element.
This was easily done and solved the problem thanks to the handy ASP.NETResources site which has a MachineKey Generator. See http://www.aspnetresources.com/tools/keycreator.aspx.
This exception is thrown when the assembly resource handler gets an invalid request. It is unlikely this is related to any malicious activity; it's usually caused by an incorrectly configured machine config on the server.
Some background:
ASP.NET has built-in mechanisms for exposing resources from the assembly (dll) via an HttpHandler. Resources such as JavaScripts and images can be stored as text in the assembly and requested by the browser via .axd handlers. But for security reasons, the handlers don't accept a plain-text location of the resource, which might expose clues about how your code works. Instead, it uses information in the machine.config on the server to encrypt a unique identifier to the resource. This exception gets thrown when a resource is requested, but when the server tries to decrypt the identifier provided, it fails.
The error is because your appdomain was recycled/restarted. When that happens the application and the machine key is set to auto, it changes. That affects the decryption of the info in the url of the resources urls (.axd). Setting up a fixed machine key will prevent it from ever happening again.
Please check this for more info on a similar case (the explanation is with an issue with viewstate validation, but the cause is the same one):
http://www.developmentnow.com/blog/InvalidViewstate+Or+Unable+To+Validate+Data+Error.aspx
Ps. this explains it on single server deployments :) - although the solution is the same for both multi-single server, the fix was usually only explained to make all servers use the same machine key.
Update 1: The padding is invalid message doesn't have relation to the css padding. If it is only happening on ie 5.5, it is likely the parameters for the webresource.axd are being messed up, just like in this question: Invalid Webresource.axd parameters being generated.

Resources