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:

  • Using socket options

  • Identifying connections and sessions

  • Handling idle connections

  • 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 9 x . 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#

 SocketMySocket; MySocket=newSocket(AddressFamily.InterNetwork,0,0); try { intone=1; MySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse,one); } catch(SocketExceptionex) { Console.WriteLine(Setsocketoptionfailed:{0}", ex.Message); } IPEndPointbindEndPoint=newIPEndPoint(IPAddress.Any, 5150); MySocket.Bind(bindEndPoint); 

Visual Basic .NET

 DimMySocketAsSocket MySocket=NewSocket(AddressFamily.InterNetwork,0,0) Try DimoneAsInteger=1 MySocket.SetSocketOption(SocketOptionLevel.Socket,_ SocketOptionName.ExclusiveAddressUse,one) CatchexAsSocketException Console.WriteLine(Setsocketoptionfailed:{0}",_ ex.Message) EndTry DimbindEndPointAsIPEndPoint=NewIPEndPoint(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#

 SocketmySock=newSocket(AddressFamily.InterNetwork, SocketType.Dgram,ProtocolType.Udp); IPEndPointlocalEndpoint=newIPEndPoint(IPAddress.Any,5150); mySock.Bind(localEndpoint); constintReceiveBroadcast=22; mySock.SetSocketOption(SocketOptionLevel.IP, (SocketOptionName)ReceiveBroadcast,0); 

Visual Basic .NET

 DimmySockAsSocket=NewSocket(AddressFamily.InterNetwork,_ SocketType.Dgram,ProtocolType.Udp) DimlocalEndpointAsIPEndPoint=NewIPEndPoint(IPAddress.Any,5150) mySock.Bind(localEndpoint) ConstReceiveBroadcast=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#

 SocketMySocket=newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); IPEndPointLocalEndPoint=newIPEndPoint(IPAddress.Any,5150); MySocket.Bind(LocalEndPoint); MySocket.Listen(5); SocketAcceptedSocket=MySocket.Accept(); IPEndPointRetIP=(IPEndPoint)AcceptedSocket.RemoteEndPoint; if(RetIP.Address.Equals(IPAddress.Parse(200.200.1.200))) { Console.WriteLine(WegotaconnectionfromIPaddress200.200.1.200); } 

Visual Basic .NET

 DimMySocketAsSocket MySocket=NewSocket(_ AddressFamily.InterNetwork,_ SocketType.Stream,_ ProtocolType.IP) DimLocalEndPointAsIPEndPoint=NewIPEndPoint(IPAddress.Any,5150) MySocket.Bind(LocalEndPoint) MySocket.Listen(5) DimAcceptedSocketAsSocket=MySocket.Accept() DimRetIPAsIPEndPoint=CType(AcceptedSocket.RemoteEndPoint,_ IPEndPoint) If(RetIP.Address.Equals(IPAddress.Parse("200.200.1.200")))Then Console.WriteLine(_  "WegotaconnectionfromIPaddress200.200.1.200") EndIf 
start sidebar
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.

end sidebar
 

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#

 SocketReceivingSocket=newSocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPointLocalEP=newIPEndPoint(IPAddress.Any,5150); ReceivingSocket.Bind(LocalEP); IPEndPointRemoteEP=newIPEndPoint(IPAddress.Any,0); SocketAddressRemoteAddress=newSocketAddress(AddressFamily.InterNetwork); EndPointRefRemoteEP=RemoteEP.Create(RemoteAddress); byte[]buffer=newbyte[2048]; intBytesReceived=ReceivingSocket.ReceiveFrom(buffer, refRemoteEP); IPEndPointRetIP=(IPEndPoint)RemoteEP; if(RetIP.Address.Equals(IPAddress.Parse(200.200.1.50))) { Console.WriteLine(Wegotapacketfrom200.200.1.50); } 

Visual Basic .NET

 DimReceivingSocketAsSocket=NewSocket(_ AddressFamily.InterNetwork,_ SocketType.Dgram,_ ProtocolType.Udp) DimLocalEPAsIPEndPoint=NewIPEndPoint(IPAddress.Any,5150) ReceivingSocket.Bind(LocalEP) DimRemoteEPAsIPEndPoint=NewIPEndPoint(IPAddress.Any,0) DimRemoteAddressAsSocketAddress=NewSocketAddress(_ AddressFamily.InterNetwork) DimRefRemoteEPAsEndPoint=RemoteEP.Create(RemoteAddress) Dimbuffer(2048)AsByte DimBytesReceivedAsInteger=ReceivingSocket.ReceiveFrom(buffer,_ RemoteEP) DimRetIPAsIPEndPoint=CType(RemoteEP,IPEndPoint) If(RetIP.Address.Equals(IPAddress.Parse("200.200.1.50")))Then Console.WriteLine("Wegotapacketfrom200.200.1.50") EndIf 

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.




Network Programming for the Microsoft. NET Framework
Network Programming for the MicrosoftВ® .NET Framework (Pro-Developer)
ISBN: 073561959X
EAN: 2147483647
Year: 2003
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net