Wednesday, January 14, 2015

Developing Secure applications using Microsoft C#.NET - A primer

Here are some of the most important Security concepts/best practices on developing secure code using Microsoft C#.NET framework.

Threat Modeling:
a. Threat modeling involves understanding the complexity of the system and identifying all possible threats to the system.
b. These threats are analyzed based on their criticality and likelihood.
c. Decision is made whether to mitigate the threat or accept the risk associated with it.
d. Look at the system from the perspective of an adversary to help designers anticipate attack goals and determine answers to questions about what the system is designed to protect,and from whom.

Threat Modeling -Steps:
The threat modeling process consists of the following three high-level steps:
• Characterizing the system
• Identifying assets and access points
• Identifying threats.

Characterization:
• Characterizing the system involves understanding the system components and their interconnections, and creating a system model emphasizing its main characteristics.
• Then assets and access points of the system are identified.
• Identifying threats creates a threat profile of a system, describing all the potential attacks that need to be mitigated against or accepted as low risk.

Data Flow Diagram:
A data flow diagram (DFD) is a graphical representation of the "flow" of data through an information system, modeling its process aspects.
• DFDs can also be used for the visualization of data processing (structured design).
• A DFD shows what kind of information will be input to and output from the system, where the data will come from and go to, and where the data will be stored.
• It does not show information about the timing of processes, or information about whether processes will operate in sequence or in parallel.

Threat:
• The goal of this step is to identify threats to the system using the information gathered so far. A threat is the adversary’s goal, or what an adversary might try to do to a system
• Sometimes a threat is also described as the capability of an adversary to attack a system.
• The best method for threat enumeration is to step through each of the system’s assets, reviewing a list of attack goals.
• Assets and threats are closely correlated. A threat cannot exist without a target asset.

STRIDE:
• The output of threat identification process is a threat profile for a system, describing all the potential attacks, each of which needs to be mitigated or accepted. In general, threats can be classified into six classes based on their effect:
• Spoofing-Using someone else’s credentials to gain access to otherwise inaccessible assets.
• Tampering-Changing data to mount an attack.
• Repudiation-Occurs when a user denies performing an action, but the target of the action has no way to prove otherwise.
• Information disclosure-The disclosure of information to a user who does not have permission to see it.
• Denial of service-Reducing the ability of valid users to access resources.
• Elevation of privilege-Occurs when an unprivileged user gains privileged status.

Attack Trees:
• Attacks are modeled through the use of a graphical, mathematical, decision tree structure called an attack tree.
• Attack trees are constructed from the point of view of the adversary. Creating good attack trees requires that we think like an attacker.
• In an attack tree vulnerability model, the topmost (root) node represents an objective that would be of benefit to one or more threat agents.

Attack Tree:
Attack trees provide a formal, methodical way of describing the security of systems, based on varying attacks. You represent attacks against a system in a tree structure, with the goal as the root node and different ways of achieving that goal as leaf nodes.



Mitigation:
• Once all potential threats have been analyzed and the threats that must be mitigated have been determined, the next task is to specify security requirements. A requirement is a statement of goals that must be satisfied. A security policy can be considered a set of security requirements.
• A good security system strikes a balance between what is possible and what is acceptable via the risk management process.
• The simplest way to prioritize threats is by using two factors: damage and likelihood.

Risk Management:
There are four possible ways to manage a risk:
• Accept the risk -The risk is so low and so costly to mitigate that it is worth accepting.
• Transfer the risk -Transfer the risk to somebody else via insurance, warnings etc.
• Remove the risk -Remove the system component or feature associated with the risk if the feature is not worth the risk.
• Mitigate the risk -Reduce the risk with countermeasures.

The Three Pillars of .NET Security:
• You use authentication to ensure that you have correctly established the identity of a user.
• Once you have authenticated and identified a user, you authorize (authorization) the user to access one or more restricted resources.
• In terms of software security, when we trust someone, we grant that person access to one or more restricted resources;

.NET Security Namespaces
System.SecuritySystem.Security.Cryptography
System.Security.Cryptography.X509Certificates
System.Security.Cryptography.Xml
System.Security.Permissions
System.Security.Policy
System.Security.Principal

Assembly
An assembly contains Microsoft Intermediate Language (MSIL), metadata; an assembly contains the code that the common language runtime executes and description of the assembly itself. The .NET Framework uses the assembly as the basic unit of deployment and versioning and, most importantly as the basic security boundary. As such, assemblies are considered to be security surfaces.

Strong name
Strong names are used to protect assemblies –particularly shared assemblies.
• Simple name
• Version number
• Culture
• Encoding from the public / private key token

sn-k MyKeyPair.snk

Obfuscation
Obfuscation is the technique of altering the MSIL statements so that the application executes in the same way, but the output of a decompileris unreadable. Primary techniques
• Encryption
• Randomize symbolic names
• Application logic more difficult to follow
• The other alternative is writing security modules in native code.

CLR and Security
• Isolation with Application Domains
• Type safe code
• Unsafe code
• Verification
• Isolated storage
• Runtime security policy

CLR and Runtime Security Policy
• The runtime establishes the identity and grant set of an assembly when the assembly is loaded. You cannot alter the identity of an already loaded assembly to change the permissions granted to it.
• It inspects various characteristics of the assembly (evidence) to determine an identity for the code.
• The runtime uses the assembly’s evidence as input to a process named policy resolution.
• The result of policy resolution is a set of protected operations and resources to which the code within the assembly has access (permissions).

Evidence
The evidence objects you will most commonly use to define the identity of your assemblies are the seven standard evidence classes from the System.Security.Policynamespace:
• ApplicationDirectory
• Hash
• Publisher
• Site
• StrongName
• Url
• Zone

Permission request operations
• Requesting minimal permissions
• Requesting optional permissions
• Refusing permissions
• Permissions
• DnsPermission
• PrintingPermission
• SocketPermission
• FileIOPermission
• ReflectionPermission
• RegistryPermission
• UIPermission
• And more

Code Access Security Explained
The .NET Framework includes an important new feature known as code-access security (CAS), which provides fine-grained control over the operations and resources to which managed code has access. With CAS, access is based on the identity of the code, not the user running it and enforcing permission sets.

CAS is effectively another layer of security that managed code must pass through before it can interact with protected system resources, such as the hard disk and the Windows registry.

Permission sets
• Creating, deleting, and modifying files and directories
• Reading from and writing to the Windows registry
• Using sockets to accept or initiate a network connection
• Creating new application domains.
• Printing
• Code Access Security is the enforcement of security policies at the code level.
• Imperative security statements appear in the body of your methods and functions, which means they end up forming part of the compiled intermediate language (IL) code contained in your assembly.
• Declarative security statements are expressed using attributes, which are statements compiled to form part of an assembly’s metadata.

Imperative
public void CreateFile( ) {
// Create a new FileIOpermission object
FileIOPermissionperm = new FileIOPermission(
FileIOPermissionAccess.Write, @" C:\SomeFile.txt");
try {
// Demand the FileIOPermission
perm.Demand( );
}
catch (SecurityExceptionse) {
// Callers do not have necessary permission
}
// Method implementation...

Declarative
[FileIOPermission( SecurityAction.Demand,
Write = @" C:\SomeFile.txt"]
public void CreateFile( ) {
// Method implementation...
}

CLR
The .NET Framework provides a generic role-based security mechanism to represent the identity and roles of the user on whose behalf code is running.

.NET’s role-based security interfaces provide a standard mechanism through which you can make runtime security decisions based on the identity and roles of a user.
Namespace: System.Security.Principal

Roles
The process of determining what actions and resources a user has authority to access. A person’s authority is expressed in terms of roles. A role is a logical categorization that grants members of the role specific permissions.

An identity represents the user on whose behalf code is running. Normally, this is the currently logged-on Windows user, but this is not always the case. If your application authenticates users against an authority other than the Windows account system, then the identity may be different to the currently logged-on Windows user. A principal encapsulates an identity and the roles to which the identity belongs. Represented by the IPrincipaland IIdentity.

// Create a GenericIdentityfor the user Peter
GenericIdentitygi= new GenericIdentity(" Peter");

// Create a GenericPrincipalfor Peter and specify membership of the
// Developers and Managers roles
String[] roles = new String[]{" Developers", "Managers"}; GenericPrincipalgp= new GenericPrincipal( gi, roles);
// Assign the new principal to the current thread Thread.CurrentPrincipal= gp;

Impersonation
Sometimes, you will want your code to act at the operating system level as though it is a different user than the one currently logged on. This is particularly common in server applications that process requests from different users and need to access resources, such as databases, on behalf of the user.

[assembly:SecurityPermission( SecurityAction.RequestMinimum, UnmanagedCode= true)]
public class WindowsImpersonationTest{
[DllImport(" advapi32. dll", SetLastError= true)]
static extern intLogonUser(
String UserName, String Domain, String Password,
intLogonType, intLogonProvider, ref IntPtrToken);
public static void Main( ) {
IntPtrtoken = IntPtr.Zero;
intret = LogonUser(@" Bob", ".", "treasure", 2, 0, ref token)
if (ret = = 0) {
Console.WriteLine(" Error {0} occuredin LogonUser", Marshal.GetLastWin32Error( ));
return;
}
WindowsIdentitywi= new WindowsIdentity( token);
WindowsImpersonationContextimpctx= wi.Impersonate( );
StreamWriterfile = new StreamWriter(" test.txt");
file.WriteLine(" Bob's test file.");
file.Close( );
impctx.Undo( );

Cryptography
• Using cryptography in any application that processes sensitive or valuable data.
• Encryption works on the basis that there is one piece of information that the attacker has not been able to acquire, known as the key. The key is used as part of the encryption process and is kept secret. Sender selects an encryption algorithm and uses the secret key to create the encrypted data. When Receive gets the encrypted text, the secret key is used to restore the confidential message so that he can read it.

Types of Encryption
• Some types of encryption require Sender and Receiver to know the key and are called symmetric encryption (because they share the same knowledge). The problem with symmetric encryption is that both parties need to agree on what the secret key will be before sending any messages.
• Another approach is to use asymmetric encryption, where only Receiver has to keep a secret. Receiver creates a special pair of keys, one of which is kept secret (known as the private key ) and one that is given out to anyone who wants to send a message (the public key ). Receiver can provide the Sender his public key openly, because he does not care if someone intercepts it.

Integrity
• Integrity becomes an issue when Sender wants to send a message to Receiver but is concerned that someone will tamper with the message and change the contents. In this case, Sender does not care if anyone can read the message —they only want to make sure that the Receiver can detect any changes.
• The solution to this problem is to use a “keyed” hash code, which uses the contents of the message and a secret key to create the hash code. The Attacker can still modify the message, but can no longer create a valid hash code, because they lack the key used to create the original code.
• Unless threat is able to discover the key, they will be unable to create hash codes that will fool Receiver.

Digital Signatures
The goal of authentication is to allow Receiver to establish that Sender is the author of a message. For our purposes, this means that the Sender should be able to create a "digital signature” for the message and that Receiver should be able to check the signature to ensure that it is valid.

• Digital signatures rely on asymmetric encryption techniques, although they are applied differently than we discussed earlier. Sender creates a pair of keys, one made public and one of which kept private. To sign the message, the Sender creates a cryptographic hash code of the message that is sent to Receiver, as discussed earlier. The sender then signs the hash code using the private key. This creates a digital signature that is unique to the combination of the document.
• When Receiver gets the message, they verify the signature using Senders public key. If the signature is valid, then Sender has “signed” the message, and the Receiver can assume that a threat has not forged the message.

Creating a hash
[assembly:SecurityPermission( SecurityAction.RequestMinimum, UnmanagedCode= true)]
public class WindowsImpersonationTest{
[DllImport(" advapi32. dll", SetLastError= true)]
static extern intLogonUser(
String UserName, String Domain, String Password,
intLogonType, intLogonProvider, ref IntPtrToken);
public static void Main( ) {
IntPtrtoken = IntPtr.Zero;
HashAlgorithmx_hash_alg= HashAlgorithm.Create(" MD5"); // byte[] x_hash_code= x_hash_alg.ComputeHash( x_message_data); foreach(byte x_bytein x_hash_code) {
Console.Write("{ 0:X2} ",
x_byte);


1 comment:

  1. • Accept the risk -The risk is so low and so costly to mitigate that it is worth accepting.
    • Transfer the risk -Transfer the risk to somebody else via insurance, warnings etc.
    • Remove the risk -Remove the system component or feature associated with the risk if the feature is not worth the risk.
    • Mitigate the risk -Reduce the risk with countermeasures.
    Great advice! I need to keep that in mind!

    ReplyDelete