February 2005 - Posts
Now Oracle is supporting .NET Developer Community in a full swing!
Oracle is now offering developer Tools for Visual Studio .NET, it released its beta and plans to release product version very soon.
The main highlight of this Dev Tools is Oracle Explorer, this is similar to existing Server Explorer, that enables to connect to oracle servers, create, edit and debug stored procedures etc.
Read here the full story http://www.ftponline.com/reports/vslivesf/2005/mendelsohn/
I remember now that in one of our projects that has got oracle as a back-end, we struggled a lot to debug the stored procedures from C# code behind. The Oracle Explorer feature add-in was needed that time :(
To know more about Oracle support to .NET visit Oracle's .NET Developer Center
The following are different types of directives in .NET
@Page: Defines page-specific attributes used by the ASP.NET page parser and compiler. Can be included only in .aspx files <%@ Page AspCompat="TRUE" language="C#" %>
@Control:Defines control-specific attributes used by the ASP.NET page parser and compiler. Can be included only in .ascx files. <%@ Control Language="VB" EnableViewState="false" %>
@Import: Explicitly imports a namespace into a page or user control. The Import directive cannot have more than one namespace attribute. To import multiple namespaces, use multiple @Import directives. <% @ Import Namespace="System.web" %>
@Implements: Indicates that the current page or user control implements the specified .NET framework interface.<%@ Implements Interface="System.Web.UI.IPostBackEventHandler" %>
@Register: Associates aliases with namespaces and class names for concise notation in custom server control syntax.<%@ Register Tagprefix="Acme" Tagname="AdRotator" Src="AdRotator.ascx" %>
@Assembly: Links an assembly to the current page during compilation, making all the assembly's classes and interfaces available for use on the page. <%@ Assembly Name="MyAssembly" %><%@ Assembly Src="MySource.vb" %>
@OutputCache: Declaratively controls the output caching policies of an ASP.NET page or a user control contained in a page<%@ OutputCache Duration="#ofseconds" Location="Any | Client | Downstream | Server | None" Shared="True | False" VaryByControl="controlname" VaryByCustom="browser | customstring" VaryByHeader="headers" VaryByParam="parametername" %>
@Reference: Declaratively indicates that another user control or page source file should be dynamically compiled and linked against the page in which this directive is declared.
Data Validation:
. Leverage client side scripting capabilities to perform validations
. Perform validations on both client and server side to avoid validation bypass
. Make appropriate use of the RequiredFieldValidator
. Use RegularExpression validator for validating complex fields like credit card, SSN, Zip code etc.
Data Binding:
. Always use SQL Data Provider for Microsoft SQL Server data access
. Use DataReaders for ASP.NET data access and use DataSets only when data caching or with web services
Apart from trusting user inputs, there are lot other security threats exist. One such thing is, giving more privileges to the applications. In other words, providing administrative rights when it is not required to the application, leads to security flaw. Say for example, if an application running a service that has a feature which is not utilized by most of the clients (browser or any other clients) then running the service in administrative privileges is not required. Obviously you pay less attention to the service and that leads to security threats.
So when installing that service in IIS it should not operate on default privileges provided by IIS.
The processes/services (and subsequently the components that are loaded up in the process address space) should always be modeled to run lower than an administrative privilege.
Actually one has to try to lower the privilege as low as one can and this will have to be a conscious decision one takes during the design. Having said that, one has to realize that a program code, when executed on lower privilege levels obviously cannot perform certain actions such as managing or even accessing the local system resources.
But on the positive side a careful think thru during design will ensure that security is elevated without affecting the functionality of the system. There are certain techniques by which one can achieve this – one of them being creating Sand Boxed Environments
Remember the moment we configure to run a process that has a Local Administrator Privilege, than it becomes part of TCB (a trusted computing base) – for example many of us do not care to configure an NT service to be configured to be set as “Run as a specific principal” as opposed to running it as a system account (which assumes local admin privilege and there by becomes or acts as a part of TCB). Imagine that you are running a process on local admin privilege and in your process you are loading a third party assembly that is fully trusted (for some silly reason) – now you can never trust the execution of the component’s code, for all you know you have Trojan that could access your system resources and create havoc on it !!. This happened because of the way we are running the parent process, if it had been on a lower privilege we would have got away without damaging our system resources
The moral of the story – there is absolutely little (read as NO need) need to have processes that would assume the privilege of a Local Administrator
Many developers write code that takes input and uses that input to build SQL queries to communicate with a back-end data store, such as Microsoft® SQL Server? Or Oracle.
Take a look at the following code snippet:
void DoQuery(string Id) {
SqlConnection sql=new SqlConnection("Your Connection String goes here");
sql.Open();
sqlstring= "SELECT hasshipped" + " FROM shipping WHERE id='" + Id + "'";
SqlCommand cmd = new SqlCommand(sqlstring,sql);
}
Here the real cause for concern is the string concatenation that builds the SQL statement.
If a user enters an ID of 1001, then you get the following SQL statement, which is perfectly valid and well formed.
SELECT hasshipped FROM shipping WHERE id = '1001'
However, attackers are more creative than this. They would enter an ID of
"'1001' DROP table shipping --",
which would execute the following query:
SELECT hasshipped FROM shipping WHERE id = '1001' DROP table shipping -- ';
This changes the way the query works. Not only does the code attempt to determine if something has shipped or not, it goes on to drop (delete) the shipping table!
Dangerous!!! Isn't it??
There are ways to avoid this:
Well, at this point we are probably wondering how any user could delete a table in the SQL Server database. Surely only admins can does a task like that? You're right and this is going to be the first step to solve SQL Injection.
You should never connect as "sa” or with any other login which has admin rights from any application to SQL Server; rather, you should either use Windows Integrated authentication, if appropriate, or connect as a predefined account with appropriately restricted rights.
Fixing the SQL injection issue is easy. Using SQL stored procedures and parameters, the following code shows how to build a query like this and how to use a regular expression to make sure that the input is valid because our business dictates that a shipping ID can only be numeric and between four and ten digits in length:
Regex r = new Regex(@"^\d{4,10}$");
if (!r.Match(Id).Success)
throw new Exception("Invalid ID");
SqlConnection sqlConn= new SqlConnection(strConn);
string str="sp_HasShipped";
SqlCommand cmd = new SqlCommand(str,sqlConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ID",Id);
Buffer overruns, cross-site scripting, and SQL injection attacks are all examples of trusting input. All these attacks can be mitigated by believing that all input is evil, until proven otherwise.
The important approaches to follow while dealing with database for SQL Injection are:
Use of xp_cmdshell
Microsoft's SQL Server supports a stored procedure "xp_cmdshell" that permits the amounts to arbitrary command execution, and if this is permitted to a web user, complete compromise of the webserver is inevitable.
So far it was limited to the web application and the underlying database, but if we can run commands, the webserver itself cannot help but be compromised. Access to xp_cmdshell is usually limited to administrative accounts, but it's possible to grant it to lesser users.
Read more about xp_cmdshell at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_xp_aa-sz_4jxo.asp
Escape/Quotesafe the input and Use bound parameters (the PREPARE statement)
Getting quotes right in to database is notably difficult, which is why many database interface languages provide a function that does it. When the same internal code is used for "string quoting" and "string parsing", it's much more likely that the process will be done properly and safely.
Though quotesafing is a good mechanism, many a times user inputs are still considered as SQL, and there is a much better approach for this: bound parameters, which are supported by essentially all database programming interfaces. In this technique, an SQL statement string is created with placeholders - a question mark for each parameter - and it's compiled ("prepared", in SQL parlance) into an internal form.
This prepared query is later "executed" with a list of parameters.
There may be some performance benefits if this prepared query is reused multiple times but it has to be parsed once, but this is very much minor when compared to the enormous security benefits. This is probably the single most important step one can take to secure a web application.
For additional reading on SQL Injection refer the following:
http://www.nextgenss.com/papers/more_advanced_sql_injection.pdf
http://www.securiteam.com/securityreviews/5DP0N1P76E.html
This new article at MSDN explains about the .NET Framework Code Access Security (CAS) for centralized trust decisions.
An Introduction to Code Access Security
Cross-site scripting vulnerabilities are Web-specific issues and can compromise a client's data through a flaw in a single Web page. Imagine the following ASP.NET code fragment:
<script language=c#>
Response.Write("Hello, " + Request.QueryString("name"));
</script>
How many of us have written or seen code like this? You may be surprised to learn that its buggy!
Normally, a user would access this code using a URL that looks like this:
http://MyWeb.com/welcome.aspx?name=Varad
The C# code assumes that the data is always well formed and contains nothing more than a name. Attackers, however, abuse this code and provide script and HTML as the name. If you typed the following URL
alert('hi!');http://MyWeb.com/welcome.aspx?name=<script>alert('hi!');</script>
You’d get a Web page that displays a dialog box, saying "hi!"
"So what?" you say. Well, imagine that the attacker convinces a user to click on a link like this, but the querystring contains some really nasty script and HTML to get your cookie and post it to a site that the attacker owns; the attacker now has your private cookie information or worse.
There are two ways to avoid Cross-site scripting.
The first is not to trust the input and be strict about what comprises a user's name. For example, you could use regular expressions to check that the name contains only a common subset of characters and is not too big. The following C# code snippet shows the way that you can accomplish this
//please include this namespace to run this code snippet
//using System.Text.RegularExpressions;
Regex rg = new Regex(@"^[\w]{1,40}$");
if (rg.Match(vpuCode).Success)
{
// Cool! The string is ok
}
else
{
// Not cool! Invalid string
}
This code uses a regular expression to verify that a string contains between 1 and 40 alphanumeric characters and nothing else. This is the only safe way to determine whether a value is correct.
Don’t use a regular expression to look for invalid characters and reject the request if such characters are found because there is always a case that will slip by you.
The second defense is to HTML-encode all input when it is used as output. This will reduce dangerous HTML tags to more secure escape characters. You can escape any strings that might be a problem in ASP.NET with HttpServerUtility.HtmlEncode, or in ASP with Server.HTMLEncode.
Ant was created and used most extensively by the Java community. While Ant can be used to build .NET applications, the .NET community decided to create its own build tool called NAnt. NAnt started life as a port of the Ant codebase, but as development progressed its code shed its Java roots to exploit.NET-specific features such as custom attributes.
NAnt, is an open source tool which is used for effectively managing distributed development, testing and deployment of the .NET application and provides powerful new tools for project management.
NAnt is easy to learn, stable, efficient, and best of all, its free. It is a build tool that uses XML for its file structure, which is more easily readable by humans and manipulated by code. Additionally, there is a robust mechanism for testing the success of each individual build step and halting the process upon failure.
You can extend NAnt by writing custom classes using the .NET programming language of your choice. There is a vibrant community of developers that have built customNAnt tasks. These tasks provide:
· Integration with a number of different source control repositories.
· Integration with different .NET programming languages. C#, VB.NET, and Managed C++ are
supported out of the box.
· Integration with unit testing harnesses such as NUnit.
· Limited integration with Visual Studio .NET solutions.
Consider the following scenario:
You have configured a web port within your orchestration and set the URL dynamically. Now you are trying to consume a web service useing windows integrated authentication based on current credentials (the default credentials).
How to achieve this in BizTalk?
In .NET you can do this like,
service1.Credentials = System.Net.CredentialCache.DefaultCredentials;
To do this within BizTalk orchestration
set the Send Port Adapter (transport) settings to use Integrated Authentication.
There are many ways to get into trouble when it comes to security. Obviously, I am not going to list all of them as the list continues to grow.
Well. But what we can discuss here is there are some of the really important issues, the biggest mistakes that we really need to watch out and we don't compromise on this for any reason.
First and foremost point.
Don't trust users input.
If you always assume that data is well formed and good, then your troubles are about to begin. Trusting that input is well formed can lead to buffer overruns, cross-site scripting attacks, SQL injection attacks, and more. Let's look at each of these potential attacks in more detail.
Protect Against Buffer Overruns
A buffer overrun occurs when the data provided by the attacker is bigger than what the application expects, and overflows into internal memory space.
Buffer overruns are primarily a C/C++ issue. They're a threat, but generally easy to fix.
So what will happen if the developer did not anticipate externally provided data that was larger than the internal buffer.
It is obvious. The overflow causes corruption of other data structures in memory, and this corruption can often lead to the attacker running malicious code.
There are also buffer underflows and buffer overruns caused by array indexing mistakes, but they are less common.
.NET role checking relies upon an IPrincipal object (representing the authenticated user) being associated with the current request.
For ASP.NET Web applications, the IPrincipal object must be attached to HttpContext.User.
For Windows Forms applications, the IPrincipal object must be attached to Thread.CurrentPrincipal.
To check the Roles manually, call the IPrincipal.IsInRole method to authorize access to specific code blocks based on the role membership of the caller.
Both AND and OR logic can be used when checking role membership.
More Posts
Next page »