72

This question is similar to Exploitable PHP Functions.

Tainted data comes from the user, or more specifically an attacker. When a tainted variable reaches a sink function, then you have a vulnerability. For instance a function that executes a sql query is a sink, and GET/POST variables are sources of taint.

What are all of the sink functions in C#? I am looking for functions that introduce a vulnerability or software weakness. I am particularly interested in Remote Code Execution vulnerabilities. Are there whole classes/libraries that contain nasty functionally that a hacker would like to influence? How do people accidentally make dangerous C# code?

Community
  • 1
  • 1
rook
  • 66,304
  • 38
  • 162
  • 239
  • 5
    It's a little bit vague. A lot of the danger comes from applications running under full trust instead of a lower trust level; the lower the trust, the harder it gets to do something malicious. – Lucero Oct 15 '10 at 08:28
  • @Lucero I liked the php question, I think this applies to C# quite well. – rook Oct 15 '10 at 16:08
  • 3
    wow, the software weakness link is a huuuuge page. – IWriteApps Oct 26 '10 at 18:13
  • @Gio yep took a while to put together ;) – rook Oct 26 '10 at 18:14
  • 3
    What exactly do you expect here? A huge list of functions? I'm not sure how that is useful... Also, to be pedant, you are talking about the .Net [Base Class Library](http://en.wikipedia.org/wiki/Base_Class_Library), or maybe Asp.Net, not C# functions (I'm not sure there *are* "C# functions"). – Kobi Dec 29 '13 at 10:31
  • @Kobi My post for PHP functions was pretty useful and more than just a dumb list. There are families of functions, and unintended functionality. – rook Dec 29 '13 at 10:43
  • To add to @Kobi's remarks, no answer below is in fact related to C# as a language. They apply to probably all .NET languages (VB, F#, etc.). You should widen the question to BCL or .NET IMHO. – Simon Mourier Dec 29 '13 at 11:07

12 Answers12

56

Anything that uses regular expressions (particularly the RegularExpressionValidator). To see this, run a RegularExpressionValidator with the regex ^(\d+)+$ and give it 30 digits and an alpha character to validate against.

Some posts:

This is called a Regular Expression Denial of Service attack and it can bring a website to its knees.

Abe Miessler
  • 82,532
  • 99
  • 305
  • 486
  • 3
    Oh, that's a good one. And applies to any language with regex support. – Jeff Mercado Oct 28 '10 at 23:52
  • 2
    Interesting oddity, but this is a far reach from the complete answer. – rook Oct 30 '10 at 19:29
  • 2
    All regular expressions won't cause such problems. This one is particularly crafted to have this kind of problem. – Lasse V. Karlsen Nov 06 '10 at 18:33
  • I'm aware of that. Did you look at either of the links I posted? – Abe Miessler Nov 06 '10 at 18:44
  • 3
    Yes, I did, and I fully agree. If you use regular expressions that you haven't vetted, and you know *a lot* about regular expressions, you're opening up all sorts of cans of worms. – Lasse V. Karlsen Nov 06 '10 at 19:52
  • 1
    By using a smart algorithm and removing support for some exotic features, regex can be done safely. Examples: TRE, Google's RE2. – jilles Nov 10 '10 at 22:23
  • Regex can be done safely with out that. You just need to write it in a safe way. – Abe Miessler Nov 11 '10 at 00:08
  • is that a specific problem with the MS regex implementation? it did not take that long with a simple grep on the command line: $ time echo "123456789012345678901234567890" | grep "\\([0-9]\+\\)\+" 123456789012345678901234567890 real 0m0.007s user 0m0.020s sys 0m0.010s – lothar Nov 11 '10 at 23:38
  • No its not specific to .NET regex. Try adding a "z" to the end of your string of numbers. Only languages that use an NFA regex engine are vulnerable. – Abe Miessler Nov 12 '10 at 01:34
  • As a side note: .NET 4.5 has the option of limiting the execution time of a regular expression. Use the constructor with the TimeSpan. http://msdn.microsoft.com/en-us/library/hh160196(v=vs.110).aspx – Pieter van Ginkel Jan 06 '14 at 11:17
  • Just a note about the cause of this. This is not a problem with NFA regex engines--it is a problem with [backtracking](http://swtch.com/~rsc/regexp/regexp1.html). An example of a non-backtracking NFA is the [Thompson NFA](http://en.wikipedia.org/wiki/Thompson's_construction_algorithm), commonly used in implementations of ed, grep, awk, and sed. – laindir Mar 12 '14 at 13:26
35

On the web based side of things, C# (and more generally, ASP.NET) is commonly vulnerable to the following (items listed by OWASP Top 10 2013). I realise you were mainly interested in sink functions, of which I cover some, however you did ask how people accidentally make dangerous C# code so hopefully I've provided some insight here.

A1-Injection

SQL Injection

Generating queries by string concatenation.

var sql = "SELECT * FROM UserAccount WHERE Username = '" + username "'";
SqlCommand command = new SqlCommand(sql , connection);
SqlDataReader reader = command.ExecuteReader();

This can often be solved by parameterised queries, but if you are using an IN condition it currently isn't possible without string concatenation.

LDAP Injection

Code such as

searcher.Filter = string.Format("(sAMAccountName={1})", loginName);

can make the application vulnerable. More information here.

OS Command Injection

This code is vulnerable to command injection because the second parameter to Process.Start can have extra commands passed to it using the & character to batch multiple commands

string strCmdText= @"/C dir c:\files\" + Request.QueryString["dir"];
ProcessStartInfo info = new ProcessStartInfo("CMD.exe", strCmdText);
Process.Start(info);

e.g. foldername && ipconfig

A2-Broken Authentication and Session Management

Sign Out

The default Forms Authentication SignOut method does not update anything server side, allowing a captured auth token to be continued to be used.

Calling the SignOut method only removes the forms authentication cookie. The Web server does not store valid and expired authentication tickets for later comparison. This makes your site vulnerable to a replay attack if a malicious user obtains a valid forms authentication cookie.

Using Session State for Authentication

A session fixation vulnerability could be present if a user has used session state for authentication.

A3-Cross-Site Scripting (XSS)

Response.Write (and the shortcut <%= =>) are vulnerable by default, unless the developer has remembered to HTML encode the output. The more recent shortcut <%: HTML encodes by default, although some developers may use this to insert values into JavaScript where they can still be escaped by an attacker. Even using the modern Razor engine it is difficult to get this right:

var name = '@Html.Raw(HttpUtility.JavaScriptStringEncode(Model.Name))';

ASP.NET by default enables Request Validation, which will block any input from cookies, the query string and from POST data that could potentially be malicious (e.g. HTML tags). This appears to cope well with input coming through the particular app, but if there is content in the database that is inserted from other sources like from an app written using other technologies, then it is possible that malicious script code could still be output. Another weakness is where data is inserted within an attribute value. e.g.

<%
alt = Request.QueryString["alt"];
%>
<img src="http://example.com/foo.jpg" alt="<%=alt %>" />

This can be exploited without triggering Request Validation:

If alt is

" onload="alert('xss')

then this renders

<img src="http://example.com/foo.jpg" alt="" onload="alert('xss')" />

In old versions of .NET it was a bit of a mine-field for a developer to ensure that their output was correctly encoded using some of the default web controls.

Unfortunately, the data-binding syntax doesn’t yet contain a built-in encoding syntax; it’s coming in the next version of ASP.NET

e.g. not vulnerable:

  <asp:Repeater ID="Repeater1" runat="server">
    <ItemTemplate>
      <asp:TextBox ID="txtYourField" Text='<%# Bind("YourField") %>'
        runat="server"></asp:TextBox>
    </ItemTemplate>
  </asp:Repeater>

vulnerable:

<asp:Repeater ID="Repeater2" runat="server">
  <ItemTemplate>
    <%# Eval("YourField") %>
  </ItemTemplate>
</asp:Repeater>

A4-Insecure Direct Object References

MVC model binding can allow parameters added to POST data to be mapped onto the a data model. This can happen unintentionally as the developer hasn't realised that a malicious user may amend parameters in this way. The Bind attribute can be used to prevent this.

A5-Security Misconfiguration

There are many configuration options that can weaken the security of an application. For example setting customErrors to On or enabling trace.

Scanners such as ASafaWeb can check for this common misconfigurations.

A6-Sensitive Data Exposure

Default Hashing

The default password hashing methods in ASP.NET are sometimes not the best.

A7-Missing Function Level Access Control

Failure to Restrict URL Access

In integrated pipeline mode .NET can see every request and handles can authorise each request, even to non .NET resources (e.g. .js and images). However, if the application i running in classic mode, .NET only sees requests to files such as .aspx so other files may be accidentally unsecured. See this answer for more detail on the differences.

e.g. www.example.com/images/private_photograph_user1.jpg is more likely to be vulnerable in an application that runs in classic mode, although there are workarounds.

A8-Cross-Site Request Forgery (CSRF)

Although the legacy web forms applications are usually more secure against CSRF due to requiring the attacker to forge the View State and Event Validation values, newer MVC applications could be vulnerable unless the developer has manually implemented anti forgery tokens. Note I am not saying that web forms is not vulnerable, just that it is more difficult that simply passing on a few basic parameters - there are fixes though, such as integrating the user key into the View State value.

When the EnableEventValidation property is set to true, ASP.NET validates that a control event originated from the user interface that was rendered by that control. A control registers its events during rendering and then validates the events during postback or callback handling. For example, if a list control includes options numbered 1, 2, or 3 when the page is rendered, and if a postback request is received specifying option number 4, ASP.NET raises an exception. All event-driven controls in ASP.NET use this feature by default.

[EnableEventValidation] feature reduces the risk of unauthorized or malicious postback requests and callbacks. It is strongly recommended that you do not disable event validation.

A10-Unvalidated - Redirects and Forwards

Adding code such as

Response.Redirect(Request.QueryString["Url"]);

will make your site vulnerable. The attack could be initiated by sending a phishing email to a user containing a link. If the user is vigilant they may have double checked the domain of the URL before clicking. However, as the domain will match your domain which the user trusts, they will click the link unaware that the page will redirect the user to the attacker's domain.

Validation should take place on Url to ensure that it is either a relative, allowed URL or an absolute URL to one of your own allowed domains and pages. You may want to check someone isn't redirecting your users to /Logout.aspx for example. Although there may be nothing stopping an attacker from directly linking to http://www.example.com/Logout.aspx, they could use the redirect to hide the URL so it is harder for a user to understand which page is being accessed (http://www.example.com/Redirect.aspx?Url=%2f%4c%6f%67%6f%75%74%2e%61%73%70%78).

Others

The other OWASP categories are:

  • A9-Using Components with Known Vulnerabilities

of which I can't think of any to mind that are specific to C#/ASP.NET. I'll update my answer if I think of any (if you think they are relevant to your question).

Community
  • 1
  • 1
SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
18

Process.Start is the first one to come to mind.

I am sure that WindowsIdentity and much of System.Security can also be used for evil.

Of course, there are SQL injection attacks, but I don't think that's what you mean (though remote execution can occur through SQL Server).

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 2
    Things like connection strings that have a username and password for SQL are a bit dodgy, when you use static strings they are typically found in decompilers, so its always best not to use them if they contain private information. – kyndigs Oct 15 '10 at 08:32
  • Please describe the problems with WindowsIdentity – jgauffin Oct 23 '10 at 18:20
  • Whereas I prefer connectionstring with usernames and password, but then tightly control the database permissions so that the username and password cant do anything I didnt explicitly give it permission to do on a case by case basis. – Peter Lange Oct 29 '10 at 21:50
17

Aside from the obvious Process.Start() already mentioned, I can see a couple of ways of potential indirect exploitation.

  • WinAPI calls via PInvoke to CreateProcess() and whatnot.
  • Any sort of dynamic assembly loading mechanism using Assembly.Load() and other such overloads. If a compromised assembly made it to the system and loaded.
  • If running in full trust in general.
  • With the right permissions, any registry operations could put you at risk.

That's all that comes to mind right now.

Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
12

IMO: The nr 1 exploitable functions, are innocent looking, but very dangerously when used without thought.

In ASP.Net Response.Write or the shortcut:

  <%= searchTermFromUser %>

In ADO.Net:

  • The string + operator:
    var sql = "SELECT * FROM table WHERE name = '" + searchTermFromUser + "'"
GvS
  • 52,015
  • 16
  • 101
  • 139
12

Any piece of data you get from the user (or any other external source) and pass to another system or another user is a potential exploit.

If you get a string from the user and display it to another user without using HtmlEncode it's a potential exploit.

If you get a string from the user and use it to construct SQL it's a potential SQL injection.

If you get a string from the user and use it to contract a file name for Process.Start or Assembly.Load it's a remote execution vulnerability

You get the point, the danger comes from using unsanitized data, if you never pass user input to external system without sanitizing it (example: HtmlEncode) or using injection-safe interfaces (example: SQL parameters) you are relatively safe - the minute you forget to sanitize something the most innocent-looking method can become a security vulnerability.

Note: cookies, html headers and anything else that passes over a network is also data from the user, in most cases even data in your database is data from the user.

Nir
  • 29,306
  • 10
  • 67
  • 103
  • Yes data from the user is called tainted data. When tainted data reaches a "sink" function, then you have a vulnerability. Look at the list of PHP sink functions i posted at the top. – rook Oct 26 '10 at 16:25
  • 1
    @Rook - You can't possibly list all the "sink" functions, any code that is not explicitly designed to deal with possibly malicious data is a sink function - also, any code that is designed to deal with malicious data in a diffract context that you use it is a sink function (example: XmlDocument.Load is designed to detect and reject malformed or malicious XML, but if you let the user control the file you load it can be used to load your configuration files and create a really bad information disclosure vulnerability) – Nir Oct 27 '10 at 10:01
  • did you see my PHP link at the top? Or have you come across static analysis tools like RATS (https://www.fortify.com/ssa-elements/threat-intelligence/rats.html) – rook Oct 27 '10 at 16:44
8

Plenty of things in the System.Net, System.XML, System.IO, (anything that takes a URI and/or file path and actually deals with the resource they identify) System.Reflection, System.Security, System.Web, System.Data and System.Threading namespaces can be dangerous, as in they can be used to do bad things that go further than just messing up the current execution. So much that it would be time consuming to try to identify each.

Of course, every method in all third party assemblies will have to assumed to be dangerous until shown otherwise. More time consuming again.

Nor do I think it's a particularly fruitful approach. Producing a checklist of functions only really works with a limited library, or with a large-language where a lot of what would be in a library with a language like C# is in the language itself.

There are some classically dangerous examples like Process.Start() or anything that executes another process directly, but they are balanced by being quite obviously dangerous. Even a relatively foolhardy and incompetent coder may take care when they use that, while leaving data that goes to other methods unsanitised.

That sanitation of data is a more fruitful thing to look at than any list of functions. Is data validated to remove obviously incorrect input (which may be due to an attack, or may simply be a mistake) and is it encoded and escaped in the appropriate way for a given layer (there is too much talk about "dangerous" character sequences, ' never hurt anyone, it's ' not correctly escaped for SQL, that can hurt when it is indeed at a SQL layer - the job required to make sure the data gets in there correctly is the same as that to avoid exploits). Are the layers at which communication with something outside of the code solid. Are URIs constructed using unexamined input, for example - if not you can turn some of the more commonly used System.Net and System.XML methods into holes.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
7

Using any type of unsafe code can cause problems such as pointers. Microsoft provided a good article about unsafe code here: http://msdn.microsoft.com/en-us/library/aa288474(VS.71).aspx

kyndigs
  • 3,074
  • 1
  • 18
  • 22
  • 2
    -1 for qualifying pointers as problems... what kind of problem they are? – jachguate Nov 10 '10 at 03:24
  • They are unsafe, pretty obvious if used incorrectly they can be exploited hence they can be a problem, doesnt take einstein to figure that one out does it? – kyndigs Nov 10 '10 at 09:38
  • _if used incorrectly_. Your car is unsafe _if used incorrectly_, a kitchen knife is unsafe _if used incorrectly_, but they are not inherently unsafe for someone who knows what are doing and how to properly use them. – jachguate Nov 10 '10 at 21:31
  • Which is exactly why I said "can cause" in my post... I didnt say "will cause". – kyndigs Nov 11 '10 at 10:15
7

Reflection.Emit and CodeDom

Edit:

Allowing plugins or third party libraries that uses threading can bring your whole application down unless you load those libraries/plugins in a separate appdomain.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
7

Probably half the framework contains very scary functions. I myself think that File.WriteAllText() is very scary since it can overwrite any file the current user has access to.

A different approach to this question would be how you can manage security. The article at http://ondotnet.com/pub/a/dotnet/2003/02/18/permissions.html contains a basic description concerning the .NET security system, with the System.Security.Permissions namespace containing all permissions .NET makes available. You can also take a look at http://msdn.microsoft.com/en-us/library/5ba4k1c5.aspx for more information.

In short, .NET allows you to limit the permissions a process can have, for example denying methods that change data on disk. You can then check these permissions and act on whether the process has them or not.

Pieter van Ginkel
  • 29,160
  • 8
  • 71
  • 111
7

even a simple string comparison can be an issue.

If an application makes a trust decision based on the results of this String.Compare operation, the result of that decision could be subverted by changing the CurrentCulture

Take a look at the example. Fairly easy to miss

jasper
  • 3,424
  • 1
  • 25
  • 46
3

I've seen code where the user could set the name and parameters for a function call in a database. The system would then execute the named function through Reflection without checking anything ...

BigBlackDog
  • 544
  • 1
  • 6
  • 19