At the time of this writing, the current version is 0.3.6 and it has been gaining traction in the Elixir/Phoenix communities.
Why Run Security Scans?
First, it should be a matter of personal responsibility to your product and your users that you try to protect your application and your user’s data.
Second, various certifications like PCI Compliance can require things like automated static-analysis security scans or security code reviews of all changes to the system.
Third, what coding habits do you have that might be a security risk? Sobelow can be that third-party reviewer to challenge your long-held assumptions.
I work at Divvy. We are a fast-paced startup with agile workflows. The best option is to have security scans automatically performed on PRs before they are merged. Some benefits to having them automated is you don’t forget to run the checks and it helps identify new code changes that could have security problems.
The project recommends installing it outside of the project to be scanned like this.
This works well when you want to scan other people’s projects without modifying their dependencies.
It also works to add it to your project’s
mix.exs if that makes more sense for
Running a Scan
Running your first scan is easy.
There are a number of command-line options and new options were recently added so it is worth checking for current documentation.
We Need Code to Scan!
I did a quick Github search for OpenSource Phoenix applications that I could use for this post and found one under active development. This will work perfectly!
Setup steps before we can test
sobelow on the project.
- Clone the project locally
- Make it able to compile
- Nothing more needed! It’s “static-analysis” remember?
sobelow on the project…
Note: Unfortunately, the color coding doesn’t translate to my copy of the text here. So just note that it is sorted with “High Confidence” items higher up then descending to “Medium” and “Low”. The colors change accordingly.
Interesting output! Now what does it mean? It is worth noting what the Sobelow project says about “False Positives”:
Sobelow favors over-reporting versus under-reporting. As such, you may find a number of false positives in a typical scan. These findings may be individually ignored by adding a @sobelow_skip mark, along with a list of modules, before the function definition.
So we need to check them personally and determine if it is a problem or not.
Let’s try out the command-line option
--with-code and see if that helps
give context to the warnings. I won’t include the full output for brevity’s sake.
I double-checked the router file and yes, it is missing the
:protect_from_forgery call you would otherwise expect.
Well that’s nice! A recent
sobelow feature is checking for known
vulnerabilities in the project’s dependencies. And yes, the project’s
file is pinned to an older phoenix version. Time to upgrade!
Here’s another one with a good code sample.
Again, the coloring doesn’t come across here. But the code being pointed out is this…
After checking the router, it is clear that this is indeed taking user submitted
data and interpolating that text into a command-line path. This means submitting
a “temp_file” value like “
../somewhere/else” poses a risk of accessing data
from anywhere on disk. I verified in the router that in order to even make this
call, you must be an authenticated user. This prompts the question, “How much do
you trust all of your users?”
I notified the project on Github of the issues and they have already addressed them.
It is also interesting how
sobelow displays the function as
def(view_uploaded_data(...)). Looking at the actual file, it was as
you’d expect with
def view_uploaded_data(...). I guess that’s exposing the
def is an Elixir macro. :)
Now you’ve seen some real-world examples of how
sobelow can help your project.
Sobelow is only designed for scanning Phoenix applications. So it doesn’t scan a
mix new project. I follow the pattern where my projects are umbrella
applications with the Phoenix project being generated without Ecto. This really
reduces the utility of sobelow.
Running it from the root of my project it returns this…
--root option lets me specify the path to the Phoenix app in my
It’s totally true. My personal project that lives only on my machine hasn’t been setup for HTTPS yet. But, it’s a nice reminder that this should be a priority before I deploy outside of my home.
But it found nothing else. Since all my Ecto queries are done in other apps where the business logic lives, how comfortable should I be that this didn’t find anything? I’m not sure. Sobelow has been advancing quickly recently. I’m hopeful that it will grow in sophistication over time.
Work Project Scan Results
I started using Sobelow on our backend system at Divvy. Now, I got the same “HTTPS Not Enabled”. However, in this case it isn’t a problem. Our production deployment has the web application behind load-balancers that are terminating the HTTPS connection. So our app doesn’t have that responsibility. How do we tell Sobelow this is okay?
Disable a Check
To disable the “HTTPS Not Enabled” check, I searched the sobelow project code for some error text and found it easily enough.
This one is not a specific line of code to disable, it is turning off the check.
-i is to “ignore” that check.
Sobelow found a valid “Unsafe
String.to_atom - High Confidence” issue. At
Divvy, many of the backend developers are new to Elixir. You can’t expect
everyone to be familiar with the details of a new language and its runtime. A
member of our team took client provided raw param data and performed
String.to_atom on it. Atoms in Elixir are like Symbols in Ruby. Elixir atoms
are not garbage collected. This allows a malicious user to arbitrarily create
them through an HTTP POST which can be abused to consume system resources until
the server crashes. Resulting in a “denial of service” attack.
This find lets us have an “education moment”. So it works!
--exit returns a non-zero return code when problems are found. This
makes it easy for an automated system to “fail” the process when a new
vulnerability is introduced.
From the docs:
The exit option accepts a confidence threshold (low, medium, or high), and will return a non-zero exit status at or above that threshold.
So our project at Divvy can run the tests on the multiple phoenix applications in the umbrella and automatically fail the code checks when new problems are introduced.
Sobelow is the first static-analysis security scanner for Phoenix that I’m aware of. I looked around a lot. At Divvy, we have PCI Compliance requirements in addition to our desire to have a completely secure system. Sobelow came along at the perfect time for us. It has become part of our automated processes for testing code quality.
Give it a try on your Phoenix projects and share your results!