< Code Access Security & Misc. | Main | Network Performance & Scalability In .NET >

 


 

 

Chapter 13 Part 2:

.NET Framework Network Security

 

 

What do we have in this chapter 13 Part 2?

  1. Securing Socket Data Communications

  2. Using Socket Options

  3. Identifying Connections and Sessions

  4. Conditional Accept in Winsock

  5. Handling Idle Connections

  6. Handling Data Encryption

  7. Encrypting Application Data

  8. IPSec

  9. HTTP Security

  10. Authentication Schemes in IIS

  11. Anonymous

  12. Basic

  13. Digest

  14. Integrated

  15. Certificates

  16. Forms

  17. Passport

  18. Choosing an Authentication Scheme

  19. Preauthentication

  20. Web Services

  21. Authorization

  22. URL Authorization

  23. File Authorization

  24. .NET Remoting

  25. Secure Sockets Layer

  26. XML Digital Signatures

  27. WS Security

 

Securing Socket Data Communications

 

As we’ve seen so far, CAS provides good run-time security for controlling managed code running on your computer. But what about securing the data communications when network applications communicate with other applications over a network such as the Internet using a socket? Writing network applications using the Socket class can provide an application the greatest flexibility to communicate over a network. With flexibility, however, comes the potential for a socket application to be exposed to unintended network communications and a denial of communications. Fortunately, a socket application can defend itself with the following techniques:

 

  1. Using socket options
  2. Identifying connections and sessions
  3. Handling idle connections
  4. Handling data encryption

 

Using Socket Options

 

Beyond CAS mechanisms for socket communication, security in a socket application also can be improved using socket options. Listening server sockets should always use the ExclusiveAddressUse option to ensure no other socket can bind the same interface. Under certain circumstances, it is possible for socket applications to have several sockets bound to the same address and port on a machine. However, depending on the protocol, the effects of this can be undesirable. For TCP and UDP, if multiple sockets are bound to the same address, it is undetermined which socket will receive traffic. Normally, a SocketException occurs whenever an attempt is made to bind a socket to an interface and port already in use.

For all Windows operating systems prior to Windows Server 2003, sockets were shareable by default. This meant that if a second socket was created and the SocketOptionName.ReuseAddress was set via SetSocketOption, the socket could then be bound to an interface and port already in use by another socket. To prevent another socket from doing this, a new socket option -SocketOptionName.ExclusiveAddressUse, was introduced on Windows NT 4 SP4. It is also available on later versions, but not on Windows 9x. If a socket first sets this option before binding, no other sockets can reuse the same address and port after the socket is bound, regardless of whether the ReuseAddress option is set. The following code fragment demonstrates how to set the ExclusiveAddressUse option:

 

C#

Socket MySocket;

MySocket = new Socket(AddressFamily.InterNetwork, 0, 0);

try

{

    int one = 1;

    MySocket.SetSocketOption(SocketOptionLevel.Socket,

        SocketOptionName.ExclusiveAddressUse, one);

}

catch(SocketException ex)

{

    Console.WriteLine("Set socket option failed: {0}", ex.Message);

}

 

IPEndPoint  bindEndPoint = new IPEndPoint(IPAddress.Any, 5150);

MySocket.Bind(bindEndPoint);

Visual Basic .NET

Dim MySocket As Socket

MySocket = New Socket(AddressFamily.InterNetwork, 0, 0)

Try

Dim one As Integer = 1

    MySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, one)

Catch ex As SocketException

    Console.WriteLine("Set socket option failed: {0}", ex.Message)

End Try

Dim bindEndPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 5150)

MySocket.Bind(bindEndPoint)

On Windows Server 2003 and later, the default security model for sockets was changed so that sockets are not shareable. As a result of this change, the uses of the two socket options ReuseAddress and ExclusiveAddressUse have also changed somewhat. Now, when a socket wants to allow another socket to bind to the same address and port, the first socket must set the ReuseAddress option, which in effect sets the permission to allow others to steal the address and port. The second socket also must set the ReuseAddress option to bind to the same address and port.

The Winsock IP_RECEIVE_BROADCAST option is another useful socket option worth mentioning for securing UDP communications. This option is new to the Windows 2003 platform and can help reduce inbound traffic to your UDP socket by preventing UDP broadcast traffic from being received. This option is not defined in the .NET Framework SocketOptionName enumeration for the SetSocketOption method. To use this option, it is necessary to pass the actual Winsock value of 22 to the SetSocketOption method. This can be done by casting the value 22 to the SocketOptionName enumeration type. It is also necessary to pass the value 0 to the OptionValue parameter of SetSocketOption, which indicates the value is false and you do not want to receive broadcast UDP datagrams. The following code fragment demonstrates how to use the Winsock IP_RECEIVE_BRODCAST option:

 

C#

Socket mySock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

IPEndPoint  localEndpoint = new IPEndPoint(IPAddress.Any, 5150);

 

mySock.Bind(localEndpoint);

 

const int ReceiveBroadcast = 22;

mySock.SetSocketOption(SocketOptionLevel.IP, (SocketOptionName) ReceiveBroadcast, 0);

Visual Basic .NET

Dim mySock As Socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)

Dim localEndpoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 5150)

 

mySock.Bind(localEndpoint)

 

Const ReceiveBroadcast = 22

mySock.SetSocketOption(SocketOptionLevel.IP, CType(ReceiveBroadcast, SocketOptionName), 0)

Identifying Connections and Sessions

 

When you use a socket connection over TCP, you can determine the connection peer by IP address and port. The Socket class maintains remote endpoint information that becomes populated with peer connection information after a socket has been successfully connected over TCP. The following code fragment demonstrates how you can determine that the connecting peer socket is connecting using the peer IPv4 address of 200.200.1.200:

 

C#

Socket MySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

IPEndPoint LocalEndPoint = new IPEndPoint(IPAddress.Any, 5150);

 

MySocket.Bind(LocalEndPoint);

MySocket.Listen(5);

 

Socket AcceptedSocket = MySocket.Accept();

 

IPEndPoint RetIP = (IPEndPoint) AcceptedSocket.RemoteEndPoint;

if (RetIP.Address.Equals(IPAddress.Parse("200.200.1.200")))

{

    Console.WriteLine("We got a connection from IP address 200.200.1.200");

}

Visual Basic .NET

Dim MySocket As Socket

MySocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)

Dim LocalEndPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 5150)

 

MySocket.Bind(LocalEndPoint)

MySocket.Listen(5)

 

Dim AcceptedSocket As Socket = MySocket.Accept()

 

Dim RetIP As IPEndPoint = CType(AcceptedSocket.RemoteEndPoint, IPEndPoint)

If (RetIP.Address.Equals(IPAddress.Parse("200.200.1.200"))) Then

    Console.WriteLine("We got a connection from IP address 200.200.1.200")

End If

Conditional Accept in Winsock

 

In Winsock, a server application can conditionally accept connections on a listening socket. Conditional acceptance is enabled by using the Winsock SO_CONDITIONAL_ACCEPT option on the listening socket. The .NET Framework Socket class, however, does not expose this conditional acceptance of client connections. Typically, the TCP/IP stack automatically acknowledges an incoming TCP request before the application even makes a call to accept it. This behavior lets an attacker know that the destination machine is valid and is running a server to accept connections. By enabling conditional acceptance, an application can decide whether or not to acknowledge each incoming connection request. In Winsock, this is done by calling the WSAAccept function with a conditional callback.

There are several major drawbacks to using conditional acceptance. First, if an application is poorly architected and cannot keep up with the incoming connection requests, the client’s connect request will time out (which is bad for other well-behaved clients). Secondly, enabling conditional acceptance disables the TCP/IP stack’s SYN attack detection logic. By default, the TCP/IP stack looks for patterns indicating a denial of service attack and ignores connections from malicious source IPs. When an application enables conditional acceptance, the application has the burden of detecting attacks since it is in control of what connections are accepted or rejected.

Another useful technique for improving security on connected sockets is to place limits on how many connections are allowed to connect to a listening socket. When a socket connection arrives, your application can determine the connection peer by its IP address and simply close the socket if the peer is servicing too many connections. It is up to your application to decide how many connections are allowed. On unconnected sockets such as UDP, your application cannot identify the communication peer until after it sends a datagram packet. Once a datagram is received, your application can decide whether to process the incoming datagram based on the communication peer IP endpoint information returned from a ReceiveFrom call. The following code fragment shows how to determine if a datagram has arrived from a communication peer with IPv4 address 200.200.1.50:

 

C#

Socket ReceivingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

 

IPEndPoint LocalEP = new IPEndPoint(IPAddress.Any, 5150);

ReceivingSocket.Bind(LocalEP);

 

IPEndPoint RemoteEP = new IPEndPoint(IPAddress.Any, 0);

SocketAddress RemoteAddress = new SocketAddress(AddressFamily.InterNetwork);

EndPoint RefRemoteEP = RemoteEP.Create(RemoteAddress);

 

byte [ ] buffer = new byte[2048];

int BytesReceived = ReceivingSocket.ReceiveFrom(buffer, ref RemoteEP);

 

IPEndPoint RetIP = (IPEndPoint) RemoteEP;

 

if (RetIP.Address.Equals(IPAddress.Parse("200.200.1.50")))

{

    Console.WriteLine("We got a packet from 200.200.1.50");

}

Visual Basic .NET

Dim ReceivingSocket As Socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)

Dim LocalEP As IPEndPoint = New IPEndPoint(IPAddress.Any, 5150)

ReceivingSocket.Bind(LocalEP)

 

Dim RemoteEP As IPEndPoint = New IPEndPoint(IPAddress.Any, 0)

Dim RemoteAddress As SocketAddress = New SocketAddress(AddressFamily.InterNetwork)

Dim RefRemoteEP As EndPoint = RemoteEP.Create(RemoteAddress)

 

Dim buffer(2048) As Byte

Dim BytesReceived As Integer = ReceivingSocket.ReceiveFrom(buffer, RemoteEP)

 

Dim RetIP As IPEndPoint = CType(RemoteEP, IPEndPoint)

 

If (RetIP.Address.Equals(IPAddress.Parse("200.200.1.50"))) Then

    Console.WriteLine("We got a packet from 200.200.1.50")

End If

There is one caution to be aware of when identifying a communication peer by IP address in UDP. Because UDP is not connected, the communication peer application can spoof the source IP address and make it look like its communication is from another computer. Of course, if the communication peer application expects your application to send something back, it will have to supply a proper source IP address.

 

Handling Idle Connections

 

A server should guard against idle connections, which are often forms of attacks. Consider a request-response–based server that accepts client connections, waits for a request, and issues a response. If the client connects, but never sends the request, the server typically posts an asynchronous receive that will never complete. If enough malicious clients do this, valid clients can be prevented from connecting when the server runs out of resources. A defensive server should track how long each client is idle and close the connection if it exceeds a predefined limit.

 

Handling Data Encryption

 

So far, we have examined three ways to make running socket applications more secure on your computer. Another way to improve socket data communication security even more effectively is to encrypt the data that is transmitted over a socket at the application level.

 

Encrypting Application Data

 

Chapter 2 described the composable .NET Framework CryptoStream, used to encrypt and decrypt data over a stream and read or write encrypted data to a file. The CryptoStream can be used to send and receive data over a network using a NetworkStream that in turn requires TCP sockets to communicate over a network. Several data encryption schemes are available in the CryptoStream, such as Data Encryption Standard (DES) and RSA Security. See Table 2-3 in Chapter 2 for more details. Using the CryptoStream to secure communications only works over a TCP socket. There is no data encryption technique available at the application level for UDP. Instead, you can encrypt the data at the network layer using IPSec.

 

IPSec

 

Internet Protocol Security (IPSec) can be used to securely transmit data between two IP hosts by using data encryption at the network transport layer. IPSec can be transparently applied to any IP network communication without having to change your application. While IPSec can provide secure communication between two hosts, you should not consider it a complete replacement for application-level security. It is better to design your application securely and only encrypt the sensitive data at the application level.

 

HTTP Security

 

In .NET, network application communication happens not only with sockets over TCP and UDP, but also when communicating with HTTP. Chapter 10 showed that Web classes can be built around communicating over HTTP without worrying about the underlying network socket communication. And Chapter 11 demonstrated that Web services use HTTP to communicate with ASP.NET on a Web server. HTTP is a simple protocol that is request-response oriented. The client makes a request to the server to perform some action. The server receives the request and generates a response that is returned to the client. Following the response, the entity or content being requested is transmitted.

When clients attempt to request resources on an HTTP server, the server can optionally require a client to identify itself by using authentication mechanisms. The HTTP 1.1 specification defines optional challenge-response authentication mechanisms named Basic and Digest by which means a server can challenge a client request to provide authentication information when accessing resources. An HTTP server that supports the HTTP 1.1 specification must at least provide Basic and Digest authentication support. However, the server is free to implement additional authentication mechanisms such as Forms-based authentication. Microsoft Internet Information Server (IIS) is a Web server that offers secure communication through HTTP by providing authentication and authorization to Web resources.

 

Authentication Schemes in IIS

 

IIS version 6 features several forms of authentication to secure Web resources: Anonymous, Basic, Digest, Integrated, and Certificate. Working in conjunction with ASP.NET, IIS also provides Forms- and Passport-based authentication.

 

.NET Framework Network Security: Authentication schemes for IIS accessed from Default Web Site property page

 

.NET Framework Network Security: the IIS authentication methods - Anonymous, Digest, Basic Authentication and Integrated Windows authentication

 

Anonymous

 

Anonymous authentication is not very secure because the client that is accessing a resource is not positively identified. Although Anonymous is not secure, it is needed for Web resources that are meant to be freely shared with clients, such as the launch page of a retail catalog Web site.

 

Basic

 

Basic authentication is a simple password-based authentication scheme supported by most Web browsers. When a Web resource is protected using basic authentication, IIS prompts users for a valid user account and password. The password information travels unencrypted over a network, however, which means that Basic authentication is not very secure even though it can identify a user. One way to make Basic more secure is to only use it over a Secure Sockets Layer (SSL) connection, which will be described later in this chapter.

 

Digest

 

Digest is another password-based authentication scheme similar to Basic authentication. User credentials are hashed and encrypted, however, typically using the MD5 message digest algorithm (see RFC 1321), when they are passed over the network during authentication, which makes the scheme more secure. The big advantage of Digest is that it can be easily deployed over the Internet to protect resources.

 

Integrated

 

Integrated authentication, also known as Windows authentication, is an authentication scheme that uses NTLM or Kerberos to authenticate users that are a part of a Windows domain. The nice thing about Integrated Windows authentication is that the authentication step is transparent to a client, such as a Web browser, because the user’s domain logon credentials are used to perform authentication. Windows authentication operates well in an intranet scenario. It does not work well on the Internet, however, because Windows domains are normally managed at the business organizational level rather than across the Internet.

 

Certificates

 

Certificate authentication uses public and private key security technologies to identify clients. The .NET Framework supports the use of X.509 version 3 certificates, which are a mechanism for validating that the private and public keys used to access a resource are correct. Chapter 10 described certificates used with the HttpWebRequest class.

 

Forms

 

Forms authentication is a mechanism that causes a user logging on to a secure Web site to receive an encrypted cookie that is used to access secure resources at the Web site. When the user first attempts to access a secured resource, HTTP client-side redirection sends the user to a form for providing authentication credentials. If the credentials satisfy the secure Web site, the client receives a cookie that contains an authentication ticket. Typically, the redirected connection to the form runs over SSL to handle the authentication step. Once authenticated, the cookie is used to identify the client every time a request is made to a secure resource. Forms-based authentication is only available in IIS from ASP.NET. Forms authentication allows you to develop a custom data store to manage credentials and authentication, which is usually handled by a Microsoft SQL Server database.

 

Passport

 

Passport authentication is similar to forms-based authentication where a client is redirected to an authentication server to receive a cookie containing an authentication ticket. The main difference is that the passport authentication service is centrally managed by Microsoft to authenticate HTTP clients. Passport is designed to standardize the authentication step by using one user account and password for all Web sites that support Passport authentication. The idea is to reduce a customer need to access Web sites with different logon credentials.

The .NET Framework Web class HttpWebRequest does not support forms- based authentication or Passport authentication, because the class does not handle the client-side redirection step needed to authenticate a client. For example, a request to a resource that is protected by forms-based authentication would be challenged by the server sending a redirect to a login page. This model works well for graphical clients such as a browser, but does not work well for clients that run as a service or contain no user interface. HttpWebRequest supports password-based authentication schemes, which are Basic, Digest, Integrated, and custom.

 

Choosing an Authentication Scheme

 

With so many authentication schemes available in IIS for HTTP communication, how do you decide which one to choose when designing an application? There are several factors to consider, such as browser type and accessibility of the authentication scheme. Table 13-3 provides a comparison overview for each scheme.

 

Table 13-3: Comparison of Authentication Schemes

 

Authentication Scheme

Advantages

Disadvantages

Basic

Used by most Web browsers.

Far reach over the Internet.

Not a secure authentication scheme because passwords travel over a connection without encryption.

Must use SSL to make authentication secure.

Must maintain a user account database.

Digest

Used by Web browsers supporting HTTP 1.1.

Passwords are encrypted over the wire.

Far reach over the Internet.

Must maintain a user account database.

Integrated

User account management is handled by a Windows Domain.

Does not have far reach over the Internet and is useful only in intranet scenarios.

Certificate

Far reach over the Internet.

Works with all Web browsers.

Clients must have X.509 certificates.

Forms

Far reach over the Internet.

Works with all Web browsers.

Easy to develop using ASP.NET.

Does not work with HTTP Web classes because it requires interaction with the user.

Must use SSL to make authentication method secure.

Must maintain a user account database.

Passport

Far reach over the Internet.

Centralized single-user account to access Web sites supporting Passport.

Works with all Web browsers.

Does not work with HTTP Web classes because Passport requires user interaction.

 

Choosing the correct authentication scheme really depends on the deployment scenario of your .NET application. For example, do you expect all your clients to use the same Web browser? Do you plan on deploying your application only in an intranet scenario where all your clients have a Windows account? Does you application work over the Internet? Knowing the answers to these questions will help you decide what authentication scheme is appropriate.

 

Preauthentication

 

Preauthentication is a method that allows an HTTP client to supply user credentials via an Authorization header so a Web server will not have to perform an authentication challenge using a WWW-authenticate header when a client application accesses a secure Web resource. The reason for it is to reduce the communications needed to set up and authenticate a client. Preauthentication is only supported by Basic and Digest authentication schemes. The HttpWebRequest class supports pre-authentication by allowing a client application to supply authentication credentials.

 

Web Services

 

The ASP.NET Web service uses HTTP and HTTPS to communicate over a network. Once a client has been authenticated by IIS or by ASP.NET, the authenticated identity of the client is used by ASP.NET to authorize access to specific Web resources.

 

.NET Framework Network Security: the ASP .NET Global Configuration and normal Configuration page access

 

.NET Framework Network Security: the ASP .NET Configuration Settings for Authorization

 

.NET Framework Network Security: the ASP .NET Configuration Settings for Authentication - Windows, Forms, Passport or None

 

Authorization

 

In ASP.NET, authorization determines whether an authenticated client has been granted access to a given resource. ASP.NET handles authorization in two ways, which are URL authorization and File authorization.

 

URL Authorization

 

URL authorization determines which users have access to specific URL resources by defining access in the Web.config control file for ASP.NET. In the Web.config XML file, the <authorization> section allows you to allow or deny specific users or groups to a specific URL.

 

File Authorization

 

File authorization requires the use of Windows authentication to apply an access control list (ACL) on Web resources. ACLs on Web resources are supported only if the file system is formatted using NTFS. ASP.NET applications can use impersonation to control the security of Web file resources. In an ASP.NET application, the application can execute using client-authentication identification. For example, you can lock specific file resources for specific users or groups that have been authenticated by Windows authentication. Web services offer good security control of Web resources using IIS when communicating over HTTP. .NET remoting also benefits from the authentication and authorization security mechanisms of IIS.

 

.NET Remoting

 

.NET remoting allows you to build highly distributed applications that can communicate securely over a network by using HTTP and IIS to host remoting. Using IIS to host remoting allows you to authenticate the user attempting to access a remoted class. It also allows you to securely transmit data over HTTPS (SSL). The HTTP channel offers most of the authentication schemes in IIS except for Forms or Passport authentication. The TCP channel for remoting currently does not offer the security mechanisms available in the HTTP channel. See Chapter 12 for more information on .NET remoting.

 

Secure Sockets Layer

 

SSL is a protocol that allows Web servers and Web clients to communicate securely by using data encryption for the HTTP communication. One of the great advantages of using SSL in the .NET Framework Web classes is that SSL support is nearly transparent. The only difference between a normal request and an SSL-encrypted request is that the URI scheme is HTTPS instead of HTTP. The SSL negotiation that occurs to establish the underlying connection, send the request, and retrieve the response is transparent and requires no intervention by the application.

 

XML Digital Signatures

 

XML digital signatures allow you to secure Web data by validating who sent the data and that the data is authentic. The System.Security.Cryptography.Xml namespace contains classes that support creation and validation of XML digital signatures. The SignedXML class enables you to create a signed XML document. Once an XML document is signed, it can be transmitted over a network and the receiver can validate that the XML is authentic by using security keys.

 

WS Security

 

Web Services Security (WS-Security) is an effort by Microsoft and IBM to help Web service developers’ secure SOAP messages by associating security tokens with the messages. Associating security tokens with SOAP messages provides message integrity, confidentiality, and authentication functionality in their transmission. The WS-Security architecture is designed with flexibility in mind enabling the application developer to associate any kind of security token with messages. A Web Services Enhancements (WSE) download is available to help Web service developers take advantage of the latest WS-Security and other enhancements to Web services. The WSE download can be found at Microsoft WSE download page.

 

 

 


< Code Access Security & Misc. | Main | Network Performance & Scalability In .NET >