Why Security?

Written by Pete Corey on Mar 13, 2017.

I’m a software developer, but I spend a lot of time thinking and worrying about software security. In fact, I’ve even recently started working on a software security service called Inject Detect!

Sometimes my friends and coworkers ask why I, as a software developer, spend so much time writing about security. Why don’t I give up on development and focus on security full-time?

Security is fundamental to everything we do as software creators. It is an underlying assumption that makes everything we do possible. We spend countless hours building an effective team, developing amazing software and nurturing trust with our users, but all of that falls to the floor without security.


Imagine your company is doing well. Your application is a pleasure to use, and your user base is rapidly growing. You’ve attracted investors and you’ve built yourself an amazing team.

But suddenly, everything changes. A malicious user has managed to find and exploit a severe vulnerability within your application. Their attack has negatively impacted hundreds users.

The hard earned trust between those affected users and your company vanishes instantly. Other users, when they learn of the attack, quickly begin to lose trust as well. Now, one of the first results when people google your product is a scathing TechCrunch article outlining the gory details of the attack. Soon, investors lose interest. With their lack of support and a rapidly dwindling user base, you realize that you won’t be able to make payroll this month.


The question of “why security?” is answered simply: Because everything we do depends on it.

Security isn’t something that can be tacked on at the end of the software development process. Building vulnerability-free software is a holistic process, and security should be considered along every step of the way.

Inject Detect - Coming Soon!

Written by Pete Corey on Mar 6, 2017.

To make a long story short, I’ve decided to start working on a new project called Inject Detect.

Inject Detect is a SaaS application designed to detect NoSQL Injection attacks against your MongoDB-backed application as they happen.

Check out the Inject Detect landing page for more details, and sign up for the Inject Detect newsletter to stay in the loop. I’ll also send you an introduction to NoSQL Injection for signing up!

Why NoSQL Injection?

It turns out that my most popular post from last year was about the NoSQL Injection talk I gave at the 2016 Crater Remote Conference.

This couldn’t make me happier! NoSQL Injection has been, and continues to be one of the most serious security issues I see pop up time and time again in Meteor applications (and any application using MongoDB).

In fact, of all the serious security issues I’ve found while conducting Meteor security assessments, nearly half are directly caused by NoSQL Injection vulnerabilities!

An Idea is Born

Wanting to piggyback off of the success of last year’s NoSQL Injection talk, I began considering writing an ebook or an online course diving into the topic of NoSQL Injection.

During my brainstorming, I asked myself many questions. What is NoSQL Injection? What causes it? How do I prevent it? What does it look like in different stacks and technologies? All of these questions had fairly well-accepted answered within the software development community.

Finally, I landed on the question of “How do I detect NoSQL Injection?” This question struck a chord with me.

When we write applications, we do our best to make them secure. In terms to preventing NoSQL Injection, we try to make sure that every possible piece of user-provided data is thoroughly checked and validated.

But what if we miss something? How do we know we don’t have vulnerable code sitting in production right now? How would we know if we were being hit with NoSQL Injection attacks as we speak? Server-side errors wouldn’t be raised, and the malicious user certainly wouldn’t file a bug report.

It seems like we’re operating blindly here, and that seems like a very dangerous gamble.

Enter Inject Detect

Inject Detect is my answer to this problem.

By analyzing the structure of the queries made against your MongoDB database and comparing them to a set of expected queries, Inject Detect will be able to identify and quickly notify you about suspicious queries that may be the result of a NoSQL injection attack.

Put simply, Inject Detect is a fully automated and easily configurable check as a service.

Inject Detect is still in very early development. My goal is to be transparent about its development. If you want to follow along, sign up for the Inject Detect newsletter and check back here for development updates as they happen!

Does Inject Detect sound like a useful service for you or your team? What features would you expect from it? Let me know - I’d love to hear your feedback!

My Favorite Pattern Revisited

Written by Pete Corey on Feb 27, 2017.

A few weeks ago, I posted an article about my favorite pattern without a name. Surprisingly, this article got quite a bit of feedback, both good and bad.

People were quick to point out that this pattern did indeed have a name. It’s a fluent interface! It’s an interceptor, a la Clojure! It’s a lense! No wait, it’s just plain-old functional composition!

Some people pointed out that, regardless of what its called, it’s an awful pattern.

While all most of these comments were relevant and useful, I found one of the discussions around this article especially interesting from a practical point of view; my friend Charles Watson introduced me to the beauty of Elixir’s with macro!

Criticisms

The original example we started with in my previous article looked something like this:


user = get_user(sms.from)
response = get_response(sms.message)
send_response(user, response)

After constructing an all-encompassing state object and chaining it through our three methods, we were left with this:


%{sms: sms, user: nil, response: nil}
|> get_user
|> get_response
|> send_response

The main criticism of this approach largely boils down to the fact that we’re allowing our functions to know too much about the architecture of our final solution.

By passing our entire state “God object” into each function, we’re obfuscating the actual dependencies of the function. This makes it difficult to determine what the function actually does, and what it needs to operate.


From a practical standpoint, this chaining also presents problems with error handling.

Our original solution assumed that all of our functions succeeded. However, what happens if any of the functions in our chain fail? Can we even tell how they would fail in our example? Would they return an :error tuple? Would they throw an exception?

It’s hard to tell from reading the code, and even worse, both failure modes would lead to a less-than-ideal debugging situations.

Thankfully, we can refactor this solution to use the with macro and address both of these criticisms.

Using the With Macro

With Elixir’s with macro, we could have refactored our original example to look like this:


with
  user     <- get_user(sms.from)
  response <- get_response(sms.message)
do
  send_response(user, response)
end

So what’s the big deal? Arguably, this is much less clean that both our previous refactor and our original implementation!

While using the with macro does cost a few extra characters, it doesn’t come without its benefits.

In our original example, I happily glossed over any errors that might have occurred during our SMS sending process.

Imagine if get_response encountered an error. What does it return? Judging by the fact that a happy path call returns a response object, it’s easy to assume that an error would result in an exception. What if we wanted to gracefully handle that error, rather than having our process blow up?

Let’s pretend that we’ve refactored get_user, get_response, and send_response to return either an {:ok, result} tuple if everything went well, or an {:error, error} tuple in the case of an error.

We could then refactor our with-powered function pipeline to gracefully handle these errors:


with
  {:ok, user}     <- get_user(sms.from)
  {:ok, response} <- get_response(sms.message)
  {:ok, sent}     <- send_response(user, response)
do
  {:ok, sent}
else
  {:error, :no_response} -> send_response(user, "I'm not sure what to say...")
  error -> error
end

Our with assignments happen in order. First, we call get_user and try to pattern match it against {:ok, user}. If that fails, we fall into the else block where we try to pattern match against our known error patterns.

If get_user fails with an {:error, :user_not_found} error, for example, that error will match the error -> error case in our else block and will be returned by our with expression.

Even more interestingly, if get_response fails with a {:error, :no_response} error, we’ll match against that error tuple in our else block and send an error response back to the user.

Using with, we’re able to short circuit our function pipeline as soon as anything unexpected happens, while still being able to gracefully handle errors.

Another added benefit of using with over the pattern I described in my previous post is that it doesn’t artificially inflate the surface area of the functions we’re calling.

Each function is passed only the exact arguments it needs. This reduction of arguments creates a much more understandable, testable, and maintainable solution.

On top of that, by specifying arguments more explicitly, a natural ordering falls out of our function chain.

Final Thoughts

While this is a fairly contrived example, with can be used to gracefully express complicated functional pipelines. I’ll definitely be using the with macro in my future adventures with Elixir.

I’d like to thank my friend Charles Watson for pointing out the with macro to me and showing me just how awesome it can be.

If you’re interested in this type of thing and want to dive deeper into the world of functional composition, I highly recommend you check out this response to my previous article, left by Drew Tipson. He outlines many interesting topics which are all fantastic diving boards into worlds of amazing topics.

Happy composing!