Personally, I try and write secure ASP.NET code. However, I have become quite paranoid about the code I write, as I used to work for a Registrar (high fraud targets). Are there any ASP.NET functions I should look at with extreme scrutiny (other than SQL access - I know enough not to do dynamic SQL).
This is an excellent MSDN article: Security Practices: ASP.NET 2.0 Security Practices at a Glance.
Excerpt:
How to prevent cross site scripting
Validate input and encode output.
Constrain input by validating it for
type, length, format, and range. Use
the HttpUtility.HtmlEncode method to
encode output if it contains input
from the user, such as input from form
fields, query strings, and cookies or
from other sources, such as databases.
Never just echo input back to the user
without validating and/or encoding the
data. The following example shows how
to encode a form field.
Response.Write(HttpUtility.HtmlEncode(Request.Form["name"]));
If you return URL strings that contain
input to the client, use the
HttpUtility.UrlEncode method to encode
these URL strings, as shown here.
Response.Write(HttpUtility.UrlEncode(urlString));
If you have pages that need to accept
a range of HTML elements, such as
through some kind of rich text input
field, you must disable ASP.NET
request validation for the page.
Turn On Custom Errors To Keep Errors Private
<customErrors mode="On" defaultRedirect="YourErrorPage.htm" />
Never trust user input. Never assume client-side validation will prevent bad input data. Always ensure that ValidateRequest="true" and EnableEventValidation="true" in your web.config :
See Request Validation and ASP.NET Security Tutorials.
Related
I am working on a legacy Application which has some cross site scripting - reflected issues when we take the input from query string. The issues are being reported by Fortify code scan (WebInspect) tool.
For example:
I have a page called ProgressDisplay.aspx which takes reportPath as a query string parameter.
/ReportViewer/ProgressDisplay.aspx?reportPath=%27%3b%61%6c%65%72%74%28%35%36%36%34%35%29%2f%2f
In the above code reportPath is a query string parameter where the malicious payload is being passed which shows an alert in the response.
Above payload becomes alert(56645) after rendering.
Like this, there are several similar issues are being reported. Is there any centralized approach to fix all the issues at one shot by using any ASP .Net library Or making some changes in the config instead of fixing each issue Or I'll have to fix all the issue one by one?
After the fix, the page shouldn't return the response as 200 when a malicious script is inserted. We have to return a Bad Request in response.
Use below recommendation to avoid Cross site scripting attack in Microsoft.NET Language :
URL Encoding : It prevent malicious script from being injected into a URL.
Not: You can use Microsoft Web Protection Library (WPL) to avoid all xss-Reflected issues.
eg: <a href=<%# Microsoft.Security.Application.Encoder.UrlEncode(TEST.Url) %>>View Details</a>
Enabling a Content Security Policy (CSP)
Validated Input data:Input data should be validated Before execute.
XSS- Microsoft.NET
Encode data on output
My <textarea> forms will often, intentionally, include fragments of HTML, which my server code is correctly coded to handle. However, ASP.NET rejects any requests with HTML by causing an error:
"A potentially dangerous Request.Form value was detected from the client."
Accordingly, I've added two lines to my web.config in the system.web section:
<pages validateRequest="false" />
<httpRuntime requestValidationMode="2.0" />
This allows the HTML through unhindered, but what else have I done? What other validations, if any, am I switching off that I should be aware of?
I wouldn't switch it off, I would suggest that you should encode/decode the html in your textarea on form submission instead .
A quick Google shows that Microsoft recommend exactly the same thing:
Microsoft Docs: Request Validation
Request validation, a feature of ASP.NET since version 1.1, prevents the server from accepting content containing un-encoded HTML. This feature is designed to help prevent some script-injection attacks whereby client script code or HTML can be unknowingly submitted to a server, stored, and then presented to other users. We still strongly recommend that you validate all input data and HTML encode it when appropriate.
Is there any in-framework way to prevent Cross Site Request Forgery (CSRF) within ASP .NET 4.0 Web forms based websites (not MVC)? I do see the framework generate __EVENTVALIDATION and __VIEWSTATE hidden form fields and I've encrypted them via machineKey and viewStateEncryptionMode="Always" in my web.config. However, it's not clear if they can actually prevent CSRF attacks. I tested a cross posting (via PostBackUrl in the form's asp:Button) form where I modified the __VIEWSTATE, __EVENTVALIDATION and __PREVIOUSPAGE (extra for cross posts) hidden, encrypted form fields and the other sensitive form fields still reached my code-behind processing block. I was expecting the framework to detect the modified encrypted fields and throw up an error. FYI, I saved the aspx as an .html, changed those hidden form fields and re-used the form (now in .html) to simulate an attacker. So I could still post to my sensitive form/fields because (start speculation) .html files don't go through the ASP.NET processing engine? (/end speculation)
If no such in-framework mechanism exists, are there any code snippets for quick prototyping/usage? I can easily create a per-user unique identifier by hashing the user ID and even set a form hidden variable for that c# variable. But the ASP.NET 4.0 mechanics of
Also setting that c# variable as a cookie
and
Checking if the cookie value == form value on subsequent requests (for validity)
is unclear to me.
I don't know how to do it in the framework, but you can do it yourself easier than your post suggests.
You don't need to set the cookie value. Its just how the mvc framework does it as an optimization\ to allow the server to be stateless. All you need to do to pick some random ( to an attacker) value and add it as a hidden field in your form. When you get the data back, verify that that value is in the form. Don't just hash the userid, hash the userid and some secrete random value. That way the attacker can't compute the hidden value if she knows a user id.
Because the same origin policy prevents attacker.com from reading the markup for your site, they can't read the hidden value. Thus the CSRF post they make, while having your cookie ( and hence the view state), won't have that value.
I have a situation where we're aggregating what amounts to marketing data from N number of clients, where a client can host a HTML form using any backend of their choice, each with the action of the form pointing to a path that we're hosting. Each client has a different URL, there's no auth (but there is some simple validation of the data) and it's all generally working just fine.
However, there's one small wrinkle that I can't seem to get my head around.
The aspx that is processing the submitted data resides at a path, let's call it ~/submit/default.aspx. The idea is that we should be able to hand to our partner a URL along the lines of "http://sample.com/submit/?foo=bar" as the action of their form. Doing this however results in a HTTP 405 error, "Resource not allowed".
Having the action of the form set as "http://sample.com/submit/default.aspx" works just fine and dandy however.
Default.aspx is set as one of the default document names in IIS 6.
The .aspx file extension is properly mapped to the correct .Net dll and has the verbs GET, HEAd, POST, and DEBUG activated for the mapping.
Those were the only two things I could think of to double check first--anyone else have any ideas? I'd have preferred to use URL rewriting / routing with IIS7, but that's unfortunately not an option--and I have a number of additional requirements where "clean" URLs will highly be preferable, so solving this problem is going to be a pretty core problem to get through.
IIRC, IIS will only use the default docs if the requested resource is a directory. Since the requested resource in the first case is not, it'll never make it through the default doc handlers - instead failing on a POST to an unregistered script extension (405).
it may depend on the document type of "http://sample.com/submit/?foo=bar"... if you IIS doesn't know how to handle the document type being returned to it (which then returns it to you, the client), then you may get an http 405 error - which means that it doesn't know how to handle that document type, server-wise. Maybe try putting something like
in your web.config file that drives the app. HTTP Handlers are modular pieces of code, written and compiled in a .net language, and act as kind of a 'servlet' if you're familiar with Java terms. It's a piece of code that writes out something to the client -- in your case maybe a rendering of a .doc file, found programmatically in your handler class.
for some reason, it didn't render my code sample!! you guys need to decode and encode less than and greater than signs for your "Your Answer" text box.... anyways,
<httpHandlers>
<add verb="your.class.to.handle.doc.files"/>
</httpHandlers>
is what should be in your web.config file.
What options do I have to work around disabled cookies for session management?
In the page in hidden field
In the query string
In the HTTP header
You can append an SID variable to every link you output to the user. PHP has some built in support for this.
Well, all a cookie does is holds on to the big ugly string your system generated as that user's session identifier (SID) for you. If you don't have cookies, the goal is to get that SID sent in with every request from that specific user.
Creating a hidden form field with the SID in it is necessary when you are accepting input from the user. You should probably read up a bit on Cross-Site Scripting vulnerabilities - might as well head these off while you're monkeying with your forms anyway.
Adding data to links (via the query string) is typically called "URL Rewriting", so just look that up for details. The upshot is that every time you output a link it must have the SID as one of the parameters in the query string.
For example: "http://mysite.com/action?SID=da83fdec49ebfafe4"
Some frameworks can handle this URL rewriting semi-transparently.