I have a form with certain elements, input boxes, check boxes etc. I need to encrypt the names of these input boxes and check boxes. I'm currently using a Rijndael encryption/decryption method through c# however this is making the encrypted names too long to be passed in a post. Is there a better way to get decent encrypted names? my purpose is to have the names encrypted before the post happens so if someone views the code behind the names are already encrypted.
Just what do you intend to accomplish by doing this?
It's not going to stop anyone from analyzing the form or submitting spoofed data. If they look at the page source and see <p>Email: <input type='text' name='skhge,f'></p>, then it's going to be quite clear to them that "skhge,f" is the name of the email field, so they can just submit spoofed data under that name instead of "email".
One of your responses to comments on the question seems to imply that you're concerned about the form being intercepted as it is sent to the user. If so, use SSL. It encrypts traffic in both directions, so you're covered against any interception that way, while just hiding the field names would provide no protection at all. (My first point applies equally to an eavesdropper as to the final intended recipient of the data.)
The only possible scenario I can think of where this might be of any benefit is if you're worried about someone building a bot to submit forms to you, but, even then, it's the wrong approach - if you're encrypting the field names, then they'll remain the same every time you send the form, so the bot will just be written to submit "skhge,f" every time instead of "email".
To foil a bot in this way, you'd need to submit random field names with every form, not encrypted names, and your responses to the suggestion of using a GUID indicate that you don't want to maintain a 'field name -> meaning' map for every form sent out. Maintaining such a map is the only thing that would slow down a bot writer and, well, even that wouldn't slow them down much. Unless you take exceptional measures to obfuscate your form layout and text content (such as those used by spammers in their attempts to slip HTML mail through spam filters), it would be easy for me, as a bot writer, to request a blank form prior to submission and correlate the textual labels presented to the user (e.g., the user-visible text "Email:") with the corresponding input field and obtain the correct field name ("skhge,f") that way.
So I'm not quite sure what your intended purpose is, but I am 99% certain that encrypting field names will not be the best way to do it - if it would even work at all.
You might be better of mapping the names to random values on them server-side.
[lkjgh] = 'username';
[hjsaf] = 'email';
If you remap on every request, looking at the code will not reveal anything of value.
Still makes me wonder, why this requirement? Usually, SSL prevents eavesdropping just fine.
If you worry about the possibility that someone relates the input name with what the value it carries is, why not just use guids instead of meaningful variable names?
Related
I just stumbled across the fact that the Password property of WPF PasswordBoxes is not bindable for security reasons, which makes using them quite cumbersome in a MVVM context.
Answers like https://stackoverflow.com/a/1493330/3198247 suggest that otherwise, the password might be stored in plain text in memory at runtime, which would be a bad idea since it could potentially be read by malware.
However, I still don't seem to understand the reason in general or that answer. There, it says Keeping your password in plain text on the client machine RAM is a security no-no.. However, the password is in memory as soon as it is typed as I'm able to access it from code.
So why would malware not be able to read it directly from the textbox? Am I missing another point here?
edit: To clarify, esp. w/ regards to Sheridan's answer: Assume a PasswordBox where a user types "pw" as his password. Then, clearly "pw" is in memory as I can retrieve it via PasswordBox.Password. Why is it then insecure to additionally be able to bind it to a string property of a ViewModel? Then, "pw" would at most be contained in two strings, but as far as I can see, this should not make it any more or less secure. Or is the point really to "remind" the programmer that the PW should not be stored for longer than needed?
Have a read of this answer
Why is char[] preferred over String for passwords?
I know it is java but I believe the same rule apply. But depending on the level of security required for your system it should be enough. Theres always ways that malware will obtain information e.g. keylogging but theres only so much you can do.
You are missing something.
Plain passwords should never be stored in a database. Instead, passwords are encrypted and then stored in the database. When a user tries to log in, they type their text which you should immediately encrypt and compare to the encrypted password from the database.
Therefore, we never see the unencrypted password, either in the database, or the code.
What else needs to be validated apart from what I have below? This is my question.
It is important that any input to a site is properly validated:
Textboxes, etc – use .NET validators (or custom code if the validators aren’t appropriate)
Querystring or Form values – use manual validation (casting to specific types, boundary checking, etc)
This ties into the problems which XSS can reveal.
Basically you have to validate any input that someone could potentially tamper with:
Form Postbacks (mainly .NET Controls – these can be validated with .NET validation controls. Also if you have Request Validation turned on on all pages, this reduces the risk )
QueryString Values
Cookie values
HTTP Headers
Viewstate (automatically done for you as long as you have ViewState MAC enabled)
Javascript (all JS can be viewed and changed, so need to ensure no crucial functionality is handled by JavaScript- i.e. always enable server side validation)
There is a lot that can go wrong with a web application. Your list is pretty comprehensive, although it is duplication. The http spec only states, GET, POST, Cookie and Header. There are many different types of POST, but its all in the same part of the request.
For your list I would also add everything having to do with file upload, which is a type of POST. For instance, file name, mime type and the contents of the file. I would fire up a network monitoring application like Wireshark and everything in the request should be considered potentially harmful.
There will never be a one size fits all validation function. If you are merging sql injection and xss sanitation functions then you maybe in trouble. I recommend testing your site using automation. A free service like Sitewatch or an open source tool like skipfish will detect methods of attack that you have missed.
Also, on a side note. Passing the view state around with a MAC and/or encrypted is a gross misuse of cryptography. Cryptography is tool used when there is no other solution. By using a MAC or encryption you are opening the door for an attacker to brute force this value or use something like oracle padding attack to take advantage of you. A view state should be kept track by the server, period end of story.
I would suggest a different way of looking at the problem that is orthogonal to what you have here (and hence not incompatible, there's no reason why you can't examine it both ways in case you catch with one what you miss with another).
The two things that are important in any validation are:
Things you pay attention to.
Things you pass to another layer untouched.
Now, most of the things you've mentioned so far fit into the first cateogry. Cookies that you ignore fit into the second, as would query & post information if you passed to another handler with Server.Execute or similar.
The second category is the most debatable.
On the one hand, if a given handler (.aspx page, IHttpHandler, etc.) ignores a cookie that may be used by another handler at some point in the future, it's mostly up to that other handler to validate it.
On the other hand, it's always good to have an approach that assumes other layers have security holes and you shouldn't trust them to be correct, even if you wrote them yourself (especially if you wrote them yourself!)
A middle-ground position, is that if there are perhaps 5 different states some persistant data could validly be in, but only 3 make sense when a particular piece of code is hit, it might verify that it is in one of those 3 states, even if that doesn't pose a risk to that particular code.
That done, we'll concentrate on the first category.
Querystrings, form-data, post-backs, headers and cookies all fall under the same category of stuff that came from the user (whether they know it or not). Indeed, they are sometimes different ways of looking at the same thing.
Of this, there is a subset that we will actually work upon in any way.
Of that there is a range of legal values for each such item.
Of that, there is a range of legal combinations of values for the items as a whole.
Validation therefore becomes a matter of:
Identify what input we will act upon.
Make sure that each component of that input is valid in its own right.
Make sure that the combinations are valid (e.g it may be valid to not send a credit card number, but invalid to not send one but set payment type to "credit card").
Now, when we come to this, it's generally best not to try to catch certain attacks. For example, it's not so good to avoid ' in values that will be passed to SQL. Rather, we have three possibilities:
It's invalid to have ' in the value because it doesn't belong there (e.g. a value that can only be "true" or "false", or from a set list of values in which none of them contain '). Here we catch the fact that it isn't in the set of legal values, and ignore the precise nature of the attack (thus being protected also from other attacks we don't even know about!).
It's valid as human input, but not as what we will use. An example here is a large number (in some cultures ' is used to separate thousands). Here we canonicalise both "123,456,789" and "123'456'789" to 123456789 and don't care what it was like before that, as long as we can meaningfully do so (the input wasn't "fish" or a number that is out of the range of legal values for the case in hand).
It's valid input. If your application blocks apostrophes in name fields in an attempt to block SQL-injection, then it's buggy because there are real names with apostrophes out there. In this case we consider "d'Eath" and "O'Grady" to be valid input and deal with the fact that ' is significant in SQL by escaping properly (ideally by using an API for data access that will do this for us.
A classic example of the third point with ASP.NET is code that blocks "suspicious" input with < and > - something that makes a great number of ASP.NET pages buggy. Granted, it's better to be buggy in blocking that inappropriately than buggy by accepting it inappropriately, but the defaults are for people who haven't thought about validation and trying to stop them from hurting themselves too badly. Since you are thinking about validation, you should consider whether it's appropriate to turn that automatic validation off and then treat < and > in a manner appropriate for your given use.
Note also that I haven't said anything about javascript. I don't validate javascript (unless perhaps I was actually receiving it), I ignore it. I pretend it doesn't exist and then I won't miss a case where its validation could be tampered with. Pretend yours doesn't exist at this layer too. Ultimately client-side validation is to save the good guys making honest mistakes time, not to twart the bad guys.
For similar reasons, this is best not tested through a browser. Use Fiddler to construct requests that hit the validation points you want to examine. This way all client-side validation is by-passed, and you're looking at the server the same way an attacker will.
Finally, remember that a page with 100% perfect validation is not necessarily secure. E.g. if your validation is perfect but your authentication poor then someone can send "valid" code to it that will be just - perhaps more - nasty as the more classic SQL-injection of XSS code. That hits onto other topics that are for other questions, except that validation as discussed here is only part of the puzzle.
I'm learning ASP.NET now and I am a bit confused by the __VIEWSTATE and __EVENTVALIDATION.
Would it be possible to read the value those two items to learn about the internals of the app and possibly manipulate it. For eg. people write that the __VIEWSTATE contains information about the properties of elements that are not sent back through the POSTBACK, like a label for example. Wouldn't it be possible then to manipulate the value of labels in an app to make it display wrong information?
Would it be possible to change the value of __VIEWSTATE with a much larger value so that when it is posted back to the server it adds serious overhead to decompressing and/or decripting the information and thus basically making a DDOS?
Yes it is possible to read the values of the viewstate. It is base64 encoded which does not mean it is encrypted so to read its values all you need to do is convert it from base64 to UTF-8 and you will be able to read its contents. Try it out here for yourself Each control is listed and several of their properties. In regards to manipulating the contents, this is possible but difficult as the contents are validated before being processed on the server end.
Yes its possible, if your site is targeted for an attack and a huge number of large requests were sent with large viewstates then it will have a corresponding effect on the server.
Take a look at the following:
Denial of service attacks
Viewstate info
Truly understanding viewstate
Yes, if you don't encrypt it using a machine key. Read this: Malicious use of view state
Encryption and ViewState MAC helps here. Read this: Protecting Your Site from DDoS Attacks
Yes, however it would only display incorrectly for that client. When it becomes dangerous is when you read this values to perform your business logic. Generally for web apps never trust information from the client. The value the viewstate is hashed to attempt to detect modification with the default settings of ASP.NET but can still be manipulated by someone with enough desire.
Yes, it is just a field on the form that you receive from the client. Thus it can be manipulated.
When passing variable from one page to another
To avoid the user messing around with the URL parameter Values
Is it best to ...
1) pass the variable via session
2) pass the variable in the URL along with a signature
As long as you're passing in a signature, it wouldn't matter where are you passing the values because you will always check for the signature integrity
What I would do is pass everything (including the signature) in the session. Just to keep the URL clean. But that's up to you and your particular use case.
If you use the session, the user cannot control the contents of the values.
Also, if you have view state encryption enabled, you could use the view state. The advantage of the view state is that it's localized to a single page. This means that when the user has two tabs open of your website, the variables are localized to the specific tabs.
See http://www.codeproject.com/KB/viewstate/AccessViewState.aspx for how to access view state from another page.
Depends on your use case. Session IS in most cases safer. If someone can compromise your server to get your session data, then you have different things to worry about. It would be bad though if you store session data in a place where other people can see it ;-).
URL signature could theoretically be brute-forced. Since the parameters are probably short and they may be sometimes predictable it may give someone who knows about encryption some point of attack. This is not trivial though. But if security is top option for you then I'd not allow this data to leave your server.
If you are really worried user going crazy and stripping down params, then you can go with Session states, however you may lose history, i.e Back Forward buttons.
The second option looks good but if user is stripping things you can't be sure that the param even existed.
So a mix of both looks good.
To prevent my application from crashing with the error "A potentially dangerous Request.Form value was detected...", I just turned page validation off. I want to revisit this and solve it correctly.
Is there a good strategy for this? If people are entering '<' and '>', I think the only way to save their data is to encode it via Javacript. I have tried catching it in the code-behind, but it becomes too late. I am thinking of inheriting the textbox and auto encode/decode the input with client scripts. I also have to think of all the angle brackets that are already saved in my database.
Any suggestions or experience with this?
I get from your answer that you don't want your client to send you "dangerous" content, so its desirable to leave the page validation turned on, as a last line of defense, instead of turning it off and using Server.HtmlEncode on each user input value (you might miss one and it is a lot of work).
I would go for a javascript solution, for example you could use a library such as jQuery, and hook into the submit events of the forms, and tidy the input before submitting. Much cleaner than creating your own derived textbox.
For the users without javascript, or that try to "hack" your little script, sc#!w them, they will reach your last line of defense, and get an error.
It's best to think of the built-in page validation as a safety device that isn't applicable to all cases. There are more than a few times when it is completely impossible to do something with it turned on. In these cases we turn it off, and deal with the validation ourselves.
The most obvious case is that sometimes we actually do want to send big chunks of HTML to the server. Of course, doing so still has to be made secure, but "oh, that looks like a big chunk of HTML! throw a security exception!" obviously isn't the correct way to do that.
So, in these cases it's perfectly sensible to turn off page-validation and add your own server-side. It does mean that you have to think about just how this input will be used with a bit more scrutiny than before. Follow through the path of every datum input (not just those where you expect to see characters like <, and ensure that either it will never be sent back to the client unescaped, or that it is thoroughly inspected to guarantee safety.
You can escape dangerous chars before posting the data. Like this:
string = escape(string);
and then on the server side:
var stringVal = Server.UrlDecode(Request["string"]);
Something like that.
Have you considered using ,
Server.HtmlEncode(input)
There is no real need to do it in the client end using javascript. You can easily do it in the server side using the above technique.
And possibly be a duplicate of this question
/BB