HttpOnly is a flag that can be used when setting a cookie to block access to the cookie from client side scripts. Javascript for example cannot read a cookie that has HttpOnly set. This helps mitigate a large part of XSS attacks as many of these attempt to read cookies and send them back to the attacker, possibly leaking sensitive information or worst case scenario, allowing the attacker to impersonate the user with login cookies.

If you are interested in reading more on the background of HttpOnly cookies, OWASP has a great article here explaining them in more detail : https://www.owasp.org/index.php/HttpOnly

Now, onto how these can used in .net core.

Defaults Are Gone

An important thing to note in .net core compared to the .net framework, is that while previously you were able to set global defaults, you can no longer do this. For example in .net framework you were able to add the following to your web.config :

<system.web>
	<httpCookies httpOnlyCookies="true"/>
</system.web>

This would make sure that any cookies set by your application were HttpOnly. Obviously web.config is more or less out the window with .net core (Although if you are hosting on IIS you can still use it), and Microsoft hasn’t added in a global default able to be set yet. This may change in the future however because it was definitely a handy setting.

Setting A Cookie Manually

When setting a cookie manually (e.g. against an HTTPContext), there is an easy CookieOptions object that you can use to set HttpOnly to true. It ends up looking a bit like this :

HttpContext.Response.Cookies.Append(
	"CookieKey",
	"CookieValue",
	new CookieOptions
	{
		HttpOnly = true
	});

When Using Cookie Authentication

Microsoft have a middleware that uses cookies for Authentication. If you were to use it in your app, you add it in the Configure method of your startup.cs.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
	app.UseMvc();
	app.UseCookieAuthentication();
}

If you are using CookieAuthentication in this way, HttpOnly cookies will be used by default. (You can check the source code here on Github). If you actually need this functionality off (Dangerous, but it’s a possibility), then you can override the functionality like so :

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
	CookieHttpOnly = false
});

When Using XYZ Middleware

Because there is no global option for HttpOnly cookies, when using a third party middleware you are at their mercy as to how they set their cookies and whether they are HttpOnly or not. In some cases they may not be HttpOnly when you want them to be, and even vice versa when you actually need the cookie to be accessible. If you are building your own middleware that you intend to share as a library, the best option is leaving the default as HttpOnly set to true, and allowing the user to override it if they really feel the need.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

It’s hard to read an intro to .NET Core without someone also introducing .NET Standard and then quickly moving on, leaving you to wonder just what is the .NET Standard. I’ve seen the same questions come up over and over again.  Is it another framework I have to learn? Is it the old .NET? Is .NET Standard and .NET Core the same? Hopefully we can answer all those questions today!

.NET Standard Is Exactly That. A Standard.

.NET Standard is for lack of a better word, a standard. It’s a description of the core interfaces that every .NET platform should implement if they wish to say “I support .NET Standard 2.0” for example.

An easy way to see what exactly the standard defines is actually the nuget package here : https://www.nuget.org/packages/NETStandard.Library . If you scroll down you will see descriptions of what each standard defines. So for example, .NET Standard 1.1 introduces System.Linq. If you would like to use System.Linq, you will need to use a platform that implements .NET Standard 1.1.

That brings us to the next point….

What Is A Platform?

It’s may be also good to take a step back and look at what exactly is a platform. At the moment the Microsoft .NET platform list looks like.NET Framework (Old .NET), .NET Core, Xamarin, Universal Windows Platform (UWP), Windows Phone and now also Mono.

Each platform version will implement a specific .NET Standard version. So for example, .NET Framework Version 4.6 implements the .NET Standard 1.3, whereas .NET Core Version 1.0 implements .NET Standard 1.6. If I were to write a library that I wanted a developer to use in both .NET Framework Version 4.6 and .NET Core Version 1.0, then I would have to target the lowest .NET Standard that these platforms implement. That being .NET Standard 1.3 in this case.

Microsoft have released an easy to view “chart” that tells you which version of each platform implements each version of the standard. You can see it here.

It’s important to note that each platform can implement it’s own features. Windows Phone for example may implement phone specific classes and interfaces, but it will also expose a classes and interfaces of it’s corresponding .NET Standard.

When Do You Have To Worry About It?

If you are writing for a particular platform, you usually don’t have to worry about .NET Standard at all. You may at times wish to look up the standard to see what would be coming to your platform next release, but that’s about it.

If you are developing your own library that you wish to be used across multiple platforms, that’s when the .NET Standard comes in handy. If you write a library that you want working on .NET Core, UWP, Windows Phone and .NET Framework, you will need to only use classes that are available on all of those platforms. How do you know what classes are available on all platforms? The .NET Standard!

What we will likely see in the future from library developers is the requirements changing from “You need .NET Framework version 4.6” to, “This is built on top of .NET Standard 1.6”. And from there you can go and look up what platforms use that standard.

A Web Analogy

Let’s try and think about this in a web sense. It’s not a direct analogy, but we’ll try. Let’s take ECMAScript or Javascript as an example. ECMAScript is a standard. It’s defined in a way that browsers then have to implement. Each browser implements ECMAScript, but they can also do their own things on top (In terms of favourites, addons, plugins etc). This is similar to how a .NET platform would work, they implement the standard, but then they can add their own platform specific items on top.

Now if you are writing a website and you wish to use a certain feature of javascript, you have to look at what browsers have implemented that feature. Then you make the decision, either you support “old” browsers, or you only outlay your support for certain modern browsers. This is similar to how it would work if you were writing a .NET library. You look at what platforms you wish to support, but if they are old, crusty and are only implementing an old version of the .NET Standard, then you can forgo supporting that platform and target a higher standard.

There is one big difference however. Unlike ECMAScript (And other web technologies like CSS), it’s hoped that platforms implement an all or nothing approach when it comes to moving up the .NET standard ladder. Either you implement .NET Standard 1.5 or 1.6, but you don’t release a platform version that implements 1.5 and a few features from 1.6. Remember, .NET Standard is supposed to make it “easy” to determine what classes and interfaces you have available.

Questions?

I’ll admit, I’m still wrapping my head around how .NET Standard works. But it’s early days yet. You can go to the Microsoft Github and see people still discussing how things should work long term, so it’s not just your everyday developer trying to work it out. If you have any questions feel free to comment below and I’ll do my best to answer.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Note : This post is for .NET Core version 1.1 or .NET Standard 1.6. At that time, the SmtpClient class had not been ported across. It is now recommended that you use a popular 3rd party library called “MailKit”. You can read our guide on getting up and running with it right here!

You’ve upgraded your latest project to the very latest version of .net core, but you can’t seem to find the correct SMTPClient namespace? It used to live in System.Net.Mail, but it’s just gone *poof*. What gives?

System.Net.Mail Is Not Ported (yet)

If you are on a .net core version 1.1 or less (Or you are working on a .net platform that implements the .net standard 1.6 or less), you will not have access to System.Net.Mail, which by extension means you will not have access to the SmtpClient class, or anything to read POP3/IMAP messages etc. They were not ported across (yet). Bummer!

However, on the Microsoft Github there is a pullrequest here for the port of System.Net.Mail that looks like it made it into .net Standard 2.0. That would point to the next version of .net core having SmtpClient back in. The release date is looking like early 2017.

So In The Meantime?

In the meantime many people are using the MailKit. It’s a very powerful library with a very similar interface/api to the original .net System.Net.Mail. In most cases you should be able to plug it in without too much hassle.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

X-XSS-Protection is a header that can be set on a webpage to activate “limited” XSS protection in certain browsers. At the time of writing, the header is available in all modern browsers except Firefox.

If you aren’t up to speed on what XSS is, have a quick read of this wikipedia article first then come back.

Great, now let’s first take a look at what browsers do out of the box. All browsers use static analysis to detect XSS attacks. They are rather vague about how they offer this protection, but usually it’s protecting against the most basic attacks. A good writeup on how Chrome’s protection has evolved over time (And still getting bypassed) can be found here : https://blog.securitee.org/?p=37. Hopefully that should give you an idea of the sort of things the browser will natively protect against.

Now usually the browser has the XSS filter turned on by default, but using the header should enforce it. There are also a couple of other values to use to extend the functionality of the header.

X-XSS-Protection Settings

X-XSS-Protection: 0
Disables XSS protection (Handy when you may want to test out XSS on your own)

X-XSS-Protection: 1
Enables XSS protection. If XSS is detected, the browser attempts to filter or sanitize the output, but still renders it for the most part.

X-XSS-Protection: 1; mode=block
Enables XSS protection and if XSS is detected, the browser stops rendering altogether.

X-XSS-Protection: 1; report=<reporting-uri>
Report works only in Chromium browsers (But can be used to enforce protection in other browsers). You can have a callback that lets you know about XSS attempts.

Setting X-XSS-Protection at the Code Level

Similar to adding any other default header to your app, you can add a Use statement to the Configure method in your startup.cs like so :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
	app.Use(async (context, next) =>
	{
		context.Response.Headers.Add("X-Xss-Protection", "1");
		await next();
	});

	app.UseMvc();
}

And you’re done!

Setting X-Xss-Protection at Server level

If you are using IIS or any other web server infront of kestrel, you can also set headers there. There are different requirements for each server.

Setting X-XSS-Protection in IIS

The best way to do this if you are just using IIS to forward requests to Kestrel (Or even if this is actually being hosted in IIS), is to do this in IIS Manager.

  1. Open IIS Manager and on the left hand tree, left click the site you would like to manage.
  2. Doubleclick the “HTTP Response Headers” icon.
  3. Right click the header list and select “Add”
  4. For the “name” write “X-Xss-Protection” and for the value write in your desired option e.g. “1”.

Setting X-XSS-Protection in Apache

In your httpd.conf file you need to append the following line :

Header always append X-Xss-Protection 1

Setting X-XSS-Protection in htaccess

Header append X-Xss-Protection "1"

Setting X-XSS-Protection in NGINX

In nginix.conf add the following line. Remember to restart the service after!

add_header X-Xss-Protection "1";
ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

X-FRAME-OPTIONS is a web header that can be used to allow or deny a page to be iframed. This is very important when protecting against clickjacking attempts. Using this header you can ensure that your content is not rendered when placed inside an IFrame, or only rendered under certain conditions (Like when you are framing yourself).

A common alternative to protect against clickjacking is to use javascript code to “break” iframes when your website is placed in them. This works for the most part but will obviously fail if the user does not have JS enabled, or (more common than you think), you forget to load the JS file on a particular page.

X-Frame-Options Settings

Your options when setting the header as as follows.

X-FRAME-OPTIONS : DENY
The page cannot be put in a frame no matter who it is (Including the site framing itself). If you don’t use frames on your own site then this is a good catch all.

X-FRAME-OPTIONS : SAMEORIGIN
The page can be framed as long as the domain framing it is the same. This is good if you are using frames yourself.

X-FRAME-OPTIONS : ALLOW-FROM https://myotherdomain.com
The page can be framed by the specified domains. Good if you have two sites with one framing the other.

Note that Allow-From is only supported in Firefox and IE. Chrome and Safari have both said that they will not support it and instead implement “Content-Security-Policy”, an alternative way to prevent clickjacking (And the subject of a future post!). Because of that it is not recommended you use this setting, stick with DENY or SAMEORIGIN.

Setting X-Frame-Options At The Code Level

Adding X-FRAME-OPTIONS to your .NET Core app is very simple. In your Configure method in your startup.cs, you need to add a custom middleware like so :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
	app.Use(async (context, next) =>
	{
		context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
		await next();
	});

	app.UseMvc();
}

And that’s all! Now every request that runs through your ASP.NET Core app will be protected.

Setting X-Frame-Options At The Server Level

You (or your dev ops team) may prefer to configure headers at the server level. In that case below are the various ways to add X-FRAME-OPTIONS to your web server so every request gains the header.

Setting X-FRAME-OPTIONS in IIS

The best way to do this if you are just using IIS to forward requests to Kestrel (Or even if this is actually being hosted in IIS), is to do this in IIS Manager.

  1. Open IIS Manager and on the left hand tree, left click the site you would like to manage.
  2. Doubleclick the “HTTP Response Headers” icon.
  3. Right click the header list and select “Add”
  4. For the “name” write “X-FRAME-OPTIONS” and for the value write in your desired option e.g. “SAME-ORIGIN”.

Setting X-FRAME-OPTIONS in Apache

In your httpd.conf file you need to append the following line :

Header always append X-Frame-Options SAMEORIGIN

Setting X-FRAME-OPTIONS in htaccess

If you are using shared hosting you may only have access to an HTAccess file. Or you may prefer to use HTAccess to manage redirects, headers etc anyway. If that’s the case you need to add the following to your .htaccess file.

Header append X-FRAME-OPTIONS "SAMEORIGIN"

Setting X-FRAME-OPTIONS in NGINX

In nginix.conf add the following line (And restart the nginx service afterwards).

add_header X-Frame-Options "SAMEORIGIN";
ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Attempting to install a nuget package the other day I got the following error :

Package ‘xyz’ uses features that are not supported by the current version of NuGet. To upgrade NuGet, see http://docs.nuget.org/consume/installing-nuget.

Following the link takes you to this page. Because I am using the inbuild package manager console from Visual Studio, I followed the steps inside VS that say to go Tools > Extensions and Updates and then click the Updates tab to see if I had an update waiting.

I didn’t. Still stuck. Damn.

After a bit of searching I came across this page that has the Visual Studio extensions to be downloaded manually and installed. After downloading the package and installing manually, with a quick restart of visual studio we are up and running on the latest version of Nuget!

If you are unsure if you are on the latest version of Nuget, you can type “nuget help” in your package manager console and it will tell you the version.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Redis is a high performance distributed cache. It’s great for storing data that you are going to need again and again in a short period of time when you don’t want to use processing power to “create” that data again. Think number crunching or heavy SQL queries for data that doesn’t change often.

Roll Your Own

First off. You can absolutely roll your own Redis Cache services abstracted by your own interfaces etc. You may find it a little difficult to find libraries that target .NET Core, but this will change over time.

In saying that, there is a “.NET core” way of doing things that is a little different. It does tie you into the framework a little, but it abstracts away the caching completely and let’s Microsoft handle it and that’s what we are going to go over today.

The ASP.NET Core Way

The first thing you need to do is add the Redis caching package provided by Microsoft. You can do this in your package manager console by running :

Install-Package Microsoft.Extensions.Caching.Redis

In your startup.cs, you now need to add the following to your ConfigureServices method. It should look something like :

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc();

	services.AddDistributedRedisCache(option =>
	{
		option.Configuration = "127.0.0.1";
		option.InstanceName = "master";
	});
}

For your Configuration, while I’ve hardcoded this to 127.0.0.1, you can obviously change this to pull from your configuration as required. Either from AppSettings/ConnectionStrings etc.

And as you can probably guess with the method signature of “AddDistributedRedisCache”, you can also use things like SQL or InMemory caches using a similar sort of method. We will go over this in future posts!

AddDistributedRedisCache actually adds an interface automagically to your service collection called “IDistributedCache” that you can then use to set and retrieve values. You can then use controller dependency injection to get this anywhere in your app. So say we have a controller called HomeController and it wants to use the RedisCache. It would go :

[Route("api/[controller]")]
public class HomeController : Controller
{
	private readonly IDistributedCache _distributedCache;

	public HomeController(IDistributedCache distributedCache)
	{
		_distributedCache = distributedCache;
	}

	[HttpGet]
	public async Task<string> Get()
	{
		var cacheKey = "TheTime";
		var existingTime = _distributedCache.GetString(cacheKey);
		if (!string.IsNullOrEmpty(existingTime))
		{
			return "Fetched from cache : " + existingTime;
		}
		else
		{
			existingTime = DateTime.UtcNow.ToString();
			_distributedCache.SetString(cacheKey, existingTime);
			return "Added to cache : " + existingTime;
		}
	}
}

The first time we view this page, there is nothing in the cache so we are given a new time. And it’s added to the cache. If we refresh the page, we then end up with the time that was cached. So for example :

Added to cache : 5/01/2017 1:27:24 AM
*refresh page a few seconds later*
Fetched from cache : 5/01/2017 1:27:24 AM

A couple more notes.

  • IDistributedCache has async methods. You should use these in all scenarios that are possible.
  • IDistributedCache allows for storing either string values or byte values. If you want to serialize an object and store the entire thing, you can either serialize it to bytes and save it as bytes, or serialize it to JSON and save it as a string if you prefer.
  • As discussed earlier, while this is a Redis distributed cache, there are other implementations available that follow the exact pattern for InMemory, SQL Server etc.

If you need to use an InMemory Cache rather than Redis, see our tutorial on In Memory Caching here

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

HttpContext has had a bit of a shifting around in ASP.NET Core. While everyone has their own ideas on best practices, it’s a bit of a consensus that the usage of calling “HttpContext.Current” outside the scope of a controller (For example in a service class) was getting out of hand. It also made testing just that little bit harder.

So how to do it now? There are two ways.

Inside Controllers

Inside a controller, you can still access HttpContext by doing the following :

[HttpGet]
public async Task<bool> LoggedIn()
{
	var myUser = HttpContext.User;
	return myUser.Identities.Any(x => x.IsAuthenticated);
}

No, there is nothing special that I have done to access the Property “HttpContext”, it’s just available when inheriting from the base “Controller” class. Simple!

Inside Services

Inside services is a little tricker, but still possible. Note that you may want further abstraction away from directly accessing an HTTPContext, for example if you are using it for “Sessions” you may want to abstract it away incase you scale your servers horizontally and you will no longer be able to use the HTTP Session object within C#. But if you don’t think you’ll need that, read on!

First in your startup.cs, you need to register IHttpContextAccessor as a service like so :

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc();
	services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

In earlier versions of .NET Core, IHttpContextAccessor was automatically registered. This was removed and announced here. So you need to register it manually if you intend to use this inside services.

When you create a helper/service class, you can then inject in the IHttpContextAccessor and use it. It would look like something not too dissimilar to this :

public class UserService : IUserService
{
	private readonly IHttpContextAccessor _httpContextAccessor;

	public UserService(IHttpContextAccessor httpContextAccessor)
	{
		_httpContextAccessor = httpContextAccessor;
	}

	public bool IsUserLoggedIn()
	{
		var context = _httpContextAccessor.HttpContext;
		return context.User.Identities.Any(x => x.IsAuthenticated);
	}
}

Unfortunately if you have accessed HttpContext throughout your old .net 4.5 code and are looking to upgrade to .net Core, you will have to do a bit of work to get it working again. But it’s worth it for the nice clean approach to DI and better testability.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

By default, browsers abide by the Same-Origin policy, which is that documents (Or in most cases scripts) cannot interact with a resource from another domain. It isolates, for example, a malicious script being able to do “too much”. A script loaded from a third party should not be able to call your own API. However in some cases this actually may be warranted.

Enter CORS

CORS or Cross-Origin Resource Sharing is a way to by-pass this limitation/security measure for legitimate reasons. The most common in the context of ASP.NET core is that you are building a Single Page Application, and you wish to host your API on another domain. For example your website is www.mywebsite.com and your API is api.mywebsite.com. Any scripts be they from jQuery, Angular, React, Backbone, whatever cannot make HTTP calls from www.mywebsite.com to api.mywebsite.com.

Configuring CORS In ASP.NET Core

Let’s get going and see how this works in ASP.NET Core

First you need to add the Microsoft Cors package from Nuget.

Install-Package Microsoft.AspNetCore.Cors

You then need to add the CORS services. In your startup.cs in your ConfigureServices method you should have something similar to the following :

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors();
}

Next you need to add the CORS middleware to your app. In your startup.cs you should have a Configure method. You need to have it similar to this :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
	app.UseCors( options => options.WithOrigins("http://www.mydomain.com").AllowAnyMethod() );

	app.UseMvc();
}

The options lambda is a fluent API so you can add/remove any extras you need. You can actually use the option “AllowAnyOrigin” to accept any domain, but I highly recommend you do not do this as it opens up cross origin calls from anyone. You can also limit cross origin calls to their HTTP Method (GET/PUT/POST etc) so you can only expose GET calls cross domain etc.

Important!

Two very important points.

  • Incase it wasn’t obvious, the above is to be done on your API not your web project!
  • Your protocol is important. http://www.mydomain.com is not the same as https://www.mydomain.com
ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

It’s not like the war of Pascalcase vs Camelcase hasn’t been going on for a very long time, but in ASP.net core it flared up again with a breaking change in ASP.net core 1.0. You can read the actual change request here on Github, and then the subsequent announcement with some unhappy campers here.

To be clear.

MyVariable <- PascalCase
myVariable <- camelCase

In earlier versions of Web API and indeed early versions of ASP.net core, the default serialization of an object to JSON results in Pascalcase names. When a C# app is talking to another C# app, the casing actually doesn’t matter. You can send JSON data with mYVaRiAbLE and it will still be deserialized into MyVariable in C#.

The issue usually reared it’s head when you were using javascript to consume your Web API. Afterall, when Mozilla, Google, jQuery, WordPress and countless others cite camelCase as the standard for Javascript naming, it’s probably what most people expect to see. If you are binding a model using Angular or similar from a Web API, you probably want to keep with the same naming format. Not have properties that came from your API suddenly be in Pascal Case.

It mostly comes down to the 80/20 rule. I would say a large majority of people using ASP.net core are also using some sort of javascript framework to bind models. And for that, camelCase is best.

So, what are your options if you are still #TeamPascalCase?

Change To PascalCase In ASP.net Core 1.0+

Probably the most annoying thing about this change is that you need to change the ContractResolver for the Json Serializer. The thing that gets people’s goat is that the resolver that makes things PascalCase is actually called the “DefaultContractResolver”…. Even though in version 1.0 and onwards it isn’t the default at all…..

In anycase, in your startup.cs file, find your ConfigureServices method. You should already have an AddMVC call, and tack onto it like so :

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc()
		.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
}

Change To camelCase In ASP.net Core <1.0

Just incase you are behind with the times in ASP.net Core versions and you want to move to camelCase by default (Possibly in preparation for upgrading), you can do so by doing similar to the above, but instead making the contract resolver camel case like so :

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc()
		.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());
}
ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.