Socket Security


There are many aspects to adding security to sockets, ranging from preventing malicious local processes from stealing ports to authenticating client connections to detecting a denial of service attack. In this chapter, we focus mainly on the socket sharing issue, but we ll also discuss the SocketPermission class, which can be used to override the default socket security policy enforced by the Microsoft Windows .NET Framework. Chapter 14 will discuss how to detect malicious clients by managing server resources and limiting how long a client can be idle.

Sharing Ports

Under certain circumstances, it s possible to have several sockets bound to the same address and port. However, depending on the protocol, the effects can be undesirable. For TCP and UDP, it s undetermined which socket will receive traffic. The only case where it s truly useful to have several sockets bound to the same address and port is for IP multicasting, where each socket bound to the same local interface and port and joined to the same multicast group will each receive a copy of the data. Normally, if an attempt is made to bind a socket to an interface and port already in use, a SocketException occurs.

For all versions of Windows prior to Windows Server 2003, sockets were shareable by default. On a pre “Windows Server 2003 machine, if a second socket is created and SocketOptionName.ReuseAddress is set via SetSocketOption , the socket can be bound to an interface and a port already being used by another socket. To prevent another socket from doing this, a new socket option, SocketOptionName.ExclusiveAddressUse , was introduced on Windows NT 4 Service Pack 4 and later (but not on Windows 9 x ). If a socket sets this option before binding, then after the socket is bound, no other sockets can reuse the same address and port regardless of whether the ReuseAddress option is set.

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 changed somewhat. Now if a socket wants to allow others to bind to the same address and port, the first socket must set the ReuseAddress option, which is in effect setting the permission to allow others to steal the address and port. Then the second socket must also set the ReuseAddress option to bind to the same address and port.

There is one catch, however, when binding a socket to the wildcard address under the new security scheme. Even though the socket is not shareable, it s not exclusive when it comes to the wildcard address. Therefore, the first socket can bind to the wildcard address and specific port, but a second socket can come along and bind to an explicit address on the same port. For example, on a computer with two interfaces, 10.10.10.1 and 10.10.10.2, the first socket can bind to 0.0.0.0:5150, and a second socket can bind to 10.10.10.1:5150. In this case, all traffic received on 10.10.10.1:5150 will be handled by the second socket, and all traffic received on port 5150 for interfaces other than 10.10.10.1 will be handled by the first socket.

As you can see, in the case where the socket is bound to the wildcard address on Windows Server 2003 and later, another socket can t bind to the wildcard address and same port (or a SocketException will be thrown), but it can bind to an explicit interface and port. However, if the server socket sets ExclusiveAddressUse , even binding to the explicit interface will fail. In general, a server should always set the ExclusiveAddressUse option regardless of which operating system it s running on. The only exception is for multicast UDP sockets.

Socket Permissions

As we saw in Chapter 8, different levels of code access security are available for socket applications depending on the zone in which the application is run. Under certain circumstances, an application can invoke untrusted assemblies or another application that resides in a more restrictive zone. In this case, the executed code is subjected to the code access permissions, which can result in socket operations failing. However, the SocketPermission class can be used to grant access to socket resources for subsequently invoked socket code.

The SocketPermission class enables applications to specify the resources to which subsequent socket calls have access to. For example, the permissions set could limit code to creating TCP sockets that connect to a single destination. Any attempt to connect to a different destination will fail. The permission properties that are used to grant or deny access are listed in Table 9-1.

Table 9-1: Socket Permission Properties

Property

Description

Transport type

Defines the transport on which to control. The transport value can be all, connection-oriented, connectionless, or the specific transports (TCP or UDP).

Host name / address

Indicates the host name or string address being granted access to.

Port number

Indicates the port number being granted access to, which can either be a specific port or all ports.

Set socket permissions

  1. Create an instance of the SocketPermission class. There are two constructors: one which sets the initial permission state (to either unrestricted or none) and one that allows a specific transport, host name, and port to allow access to. The following code shows how to create a SocketPermission instance with no permissions:

    C#

     SocketPermissionsockPerm1; sockPerm1=newSocketPermission(System.Security.Permissions.PermissionState.None); 

    Visual Basic .NET

     DimsockPerm1AsSocketPermission sockPerm1=NewSocketPermission(_ System.Security.Permissions.PermissionState.None) 
  2. Once the initial SocketPermission object is created, individual permissions can be added to the object. The following code allows sockets to connect to any port on the host AllowedHost using the TCP transport:

    C#

     sockPerm1.AddPermission(NetworkAccess.Connect, TransportType.Tcp,  AllowedHost", SocketPermission.AllPorts); 

    Visual Basic .NET

     sockPerm1.AddPermission(_ NetworkAccess.Connect,_ TransportType.Tcp,_  AllowedHost",_ SocketPermission.AllPorts_) 

    Note that the SocketPermission constructor can be used to specify a single allowed host from step 2.

    C#

     sockPerm1=newSocketPermission(NetworkAccess.Connect, TransportType.Tcp,  AllowedHost", SocketPermission.AllPorts); 

    Visual Basic .NET

     sockPerm1=NewSocketPermission(_ NetworkAccess.Connect,_ TransportType.Tcp,_  AllowedHost",_ SocketPermission.AllPorts_) 
  3. Enforce the socket permission for all subsequent socket calls by calling the Demand method.

    C#

     sockPerm1.Demand(); 

    Visual Basic .NET

     sockPerm1.Demand() 
  4. The Deny method will prevent any function higher in the call stack from modifying the socket permissions granted. Once the desired permissions are established and demanded, the Deny method should be invoked before calling the untrusted code.

    C#

     sockPerm1.Deny(); InvokeUntrustedSocketCode(); 

    Visual Basic .NET

     sockPerm1.Deny() InvokeUntrustedSocketCode() 

If multiple SocketPermission classes are created, the Union and Intersect methods can be used to perform logical operations on sets of permissions. These methods return a new SocketPermission instance containing the results of the operation.

Finally, note that the permissions granted by the SocketPermission class are applied only when the executed code does not have socket permissions. For example, creating and demanding a SocketPermission that allows a connection to a single host will not be enforced when run in the local computer zone because socket operations are unrestricted in that zone. In other words, the SocketPermission class can t deny access to socket resources if the executed code has permission to access them.




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