all Technical posts
Domain-Driven Security with F# FPrimitive and C# Interop
What if you could have a more secure code base just by following the requirements of your domain?
This post explores the idea of validation, access-control and trust-boundaries in the context of domain modeling.
The extension on Domain-Driven Design (DDD) is Domain-Driven Security which is actually “DDD with conventions”. Personally I would think that conventions, validation, … is already a part of domain-modeling and design (and it is), but we could go even further. This post explores ways to secure your domain model even more by reusable validations, ways to define trust boundaries, and increase control on the access of your domain model.
The Reality of the Naive
Did you know that input validation is one of the major vulnerabilities when it comes to security on application-level? How is it that we somehow ‘trust’ inputs from external sources?
One of the major topics of security in application development is defining trust-boundaries: from what level do we assume that we are dealing with input that we can trust? Something that is not
string that is not empty? … Probably. But is that correct?
Sometimes you see projects where there exists some validation with white-listing input via regular expressions; which is probably the best way to have a secure validation system. But after the validation, the same “untrusted” data type is used around the system. How can you be sure that that data is still valid? To be correct, you should duplicate your entire validation on every single place that untrusted data type is used. Or… you could create a dedicated type for it to centralize the validation. This is the one and only correct approach to address validation!
The FPrimitive library contains a validation system to address both validation and domain modeling because they should indeed be addressed at the same time.
Following example shows how validation and modeling can be combined (just for demonstration purposes).
Control is an Illusion
After you establish your domain types, your specifications and your trust boundaries, you can think about how your application should access certain parts. Is one path more critical than another? Is it really necessary to keep some private information in memory the whole time the application is running? Is it correct that some function can be called more than once?
Several of these questions can be handled within the infrastructure of your application. If you control from the outside when your app is available for example. But in my opinion, that should not be an excuse to not think about Access-Control on application level. Maybe there is another way to access your application to bypass the infrastructure. What happens then?
The FPrimitive contains, besides of specifications, also a way to make your part of the application more controlled. Here are some examples:
Trust is not an Option
As a bonus, I want to show how we can manipulate the default untrusted data (
byte, …) and make it explicit that this is indeed untrusted data.
The FPrimitive package contains a way to do this. The idea is to teach people how small the circle of trust really is.
Having these building blocks in your next project will help you creating a more correct Domain model and by doing so, a more secure application.
Thank you for reading!
Subscribe to our RSS feed