Deprecation of SSL / TLS 1.0

Introduction

This article is based on the following article: https://blog.pcisecuritystandards.org/are-you-ready-for-30-june-2018-sayin-goodbye-to-ssl-early-tls

Is your organization still using the SSL/early TLS protocols? Do you work with online and e-commerce partners or customers who haven’t yet started the migration away from SSL/early TLS to a more secure encryption protocol? Read on for key questions and answers that can help with saying goodbye to SSL/early TLS and reducing the risk of being breached.

What’s happening on 30 June 2018?

30 June 2018 is the deadline for disabling SSL/early TLS and implementing a more secure encryption protocol – TLS 1.1 or higher (TLS v1.2 is strongly encouraged) in order to meet the PCI Data Security Standard (PCI DSS) for safeguarding payment data.

What is SSL/early TLS?

Transport Layer Security (TLS) is a cryptographic protocol used to establish a secure communications channel between two systems. It is used to authenticate one or both systems, and protect the confidentiality and integrity of information that passes between systems. It was originally developed as Secure Sockets Layer (SSL) by Netscape in the early 1990s. Standardized by the Internet Engineering Taskforce (IETF), TLS has undergone several revisions to improve security to block known attacks and add support for new cryptographic algorithms, with major revisions to SSL 3.0 in 1996, TLS 1.0 in 1990, TLS 1.1 in 2006, and TLS 1.2 in 2008.

What is the risk of using SSL/early TLS?

There are many serious vulnerabilities in SSL and early TLS that left unaddressed put organizations at risk of being breached. The widespread POODLE and BEAST exploits are just a couple examples of how attackers have taken advantage of weaknesses in SSL and early TLS to compromise organizations.

According to NIST, there are no fixes or patches that can adequately repair SSL or early TLS. Therefore, it is critically important that organizations upgrade to a secure alternative as soon as possible, and disable any fallback to both SSL and early TLS.

Your .NET Code Could Stop Working

What code is impacted?

  • Targets .NET Framework 4.0 or 4.5
  • Uses .NET’s built-in communication framework (HttpClient, HttpWebRequest, etc)
  • Uses default security protocols

What will happen?

If your client code has only SSL 3 and TLS 1.0 enabled when attempting to securely communicate with a server that has only TLS 1.1 and/or TLS 1.2 enabled… it simply won’t work (SocketException). Both server and client must have at least one matching protocol enabled in order to communicate.

What are some options to fix it?

  1. Update your code to explicitly enable the newer protocols.
    This is the option we’re going to explore.
  2. Update your project to target .NET Framework 4.6 or newer.
    This will enable TLS 1.0, TLS 1.1, and TLS 1.2 by default.
  3. Update the registry as described here to enable secure defaults across all .NET applications on the machine.
  4. Rewrite your code to implement a 3rd-party communication framework.

The option you choose depends entirely on your constraints (time, risk, target operating systems, etc). You may not be able to target .NET 4.6 or modify the registry due to a lack of control on your target platform. You might not want to risk rewriting your codebase and retesting.

Thankfully, the code fix is relatively straightforward if you’re targeting .NET 4.5
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

This will ensure that TLS 1.1 and TLS 1.2 are enabled in addition to the system defaults. You can set this once at the beginning of your application to affect all connections in the current AppDomain.

What if I’m targeting .NET 4.0?

Unfortunately, the Tls11 and Tls12values are not defined in .NET 4.0’s version of the SecurityProtocolType enum.

However, if .NET 4.5 or newer is installed on the system, the following code will work at runtime:

using System;
using System.Net;
using System.Reflection;
using System.Runtime.Versioning;

namespace ProtocolCheck {
    class Program {
        static void Main(string[] args) {
            var assembly = Assembly.GetExecutingAssembly();
            var attributes = assembly.GetCustomAttributes(typeof(TargetFrameworkAttribute), false);
            var version = (TargetFrameworkAttribute)attributes[0];

            Console.WriteLine($"Target Framework: {version.FrameworkDisplayName}");

            SecurityProtocolType flag;
            if (Enum.TryParse("Tls11", out flag))
                ServicePointManager.SecurityProtocol |= flag;
            if (Enum.TryParse("Tls12", out flag))
                ServicePointManager.SecurityProtocol |= flag;

            Console.WriteLine($"Enabled Protocols: {ServicePointManager.SecurityProtocol}");
        }
    }
}

By default, all versions of Windows starting with Windows 8 ship with .NET 4.5 or newer.

Unfortunately Windows 7 / Server 2008 only ships with .NET Framework 3.5.1. The solutions for applications targeting .NET 3.5.1 are slightly different than what I’ve covered here. You’ll definitely want to look at Microsoft’s patch for Windows 7 / Server 2008 that enables the new protocols for .NET 3.5.1.

How to pass in Uri complex objects without using custom ModelBinders or any serialization?

Do you wonder why I publish such an article?
Well, recently it happened to me to ask to a legacy information system in which I was to find information of users only with their name and their first name…
Yes yes using their name first name:).

I had to send to the WebApi a list of name/first name, the whole paginated, how did I make it?

At the beginning I had the idea to create my search model object in JSON which I would have to serialize while passing it in the URL, then, I had the idea to create an object with a string property containing the list of the names/firstnames the whole “decorated with separators” then split it in the WebAPI with a custom ModelBinder. Finally I decided I’d rather understand how to pass in the Uri more or less complex objects without using of ModelBinder or serialisation?.

Here what I did:

I tested 2 scenarios, the first with a list of “Person” and a second with a little more complex object “ListOfPersons”.
Before starting, as a reminder, I just want to remind you how we pass in a Uri a string collection.

namespace QueryStringDemo.Models
{
    public class Person
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }
    }
}
namespace QueryStringDemo.Models
{
    public class ListOfPersons
    {
        public int? PageNumber { get; set; } 
        public int? PageSize { get; set; }
        public List Persons { get; set; }
    }
}
using QueryStringDemo.Models;
using System.Collections.Generic;
using System.Web.Http;

namespace QueryStringDemo.Controllers
{
    [RoutePrefix("api/demo")]
    public class DemoController : ApiController
    {
        [Route("simplelist")]
        [HttpGet]
        public IHttpActionResult Get([FromUri]List strings)
        {
            return Ok();
        }

        [Route("simplelistOfpersons")]
        [HttpGet]
        public IHttpActionResult Get([FromUri]List listOfPersons)
        {
            return Ok();
        }

        [Route("complexlistOfpersons")]
        [HttpGet]
        public IHttpActionResult Get([FromUri]ListOfPersons listOfPersons)
        {
            return Ok();
        }
    }
}

1- Scenario 1, reminder, string collection :

Uri :

scenario1-url

Result in code :

scenario1-code

Note that you have to use the attribute [FromUri], it provides deserialization to the target object from a complex object that comes from the queryString.

2- Scenario 2, collection of person object :

Uri :

scenario2-url

Result in code :

scenario2-code-1

Note that the object is in fact an array, an array like this

?[index].PropertyName=Value

3- Scenario 3, a more complex collection of person object :

Uri :

scenario3-url

Result in code :

scenario3-code

Note that it works also with an array,
our object looks like this :

?PropertyName1=value&PropertyName2=value&PropertyName3[index].SubPropertyName1=value&PropertyName3[index].SubPropertyName2=value

Finally we have demystified how queryString native serialization/deserialization works, was it so complicated ? 🙂

Micro ORMs, alternatives to Entity Framework ? Part 9

 

<< Previous article (Part 8)

What conclusion(s) can we make ?

Let’s summarize first principals features we described for each Micro ORM before in a user friendly table here:

Legends :

 Disappointing

 Good

 Excellent

 Yes

 No

 Yes, but not verified

Note that they :

  • All support the execution of stored procedures, views, functions
  • Are all protected from SQL injection (queries parameterization)

What we liked ?

  • NPoco for simplicity of its syntax and performance
  • Dapper for its outstanding performance and its amazing community
  • OrmLite for its double LINQ-like and SQL syntax, and for its rich functionalities and performance

Finally….

Even if we love some Micro ORMs and they are more performant than Entity Framework, they don’t provide all Entity Framework’s functionalities, and they don’t support unit tests as Entity Framework does (by mocking its DbContext).

In fact it depends on what you are looking for 🙂

I hope this suite of articles helped you to make a choice 😉

If you need to check the source code, you can find it here : https://github.com/AnthonyGiretti/MicroOrmDemo.net