TL/DR: Youtube
So why are we fast-forwarding, Blink???
The goal for season 2 was to show the use of various devops tools in action... not to spend a bunch of time learning to write Python. While I'm enjoying the coding aspect of building Hangman, I have to remember my plan and stay on target!
With that in mind, I've been feeling like we've spent enough time on the code of the application and I'd rather introduce you to some cool toys for improving your software delivery process rather than going deep into Python and Tkinter... so if you pull down this week's branch on GitHub, you'll see the frontend code got some major changes! While it may not be completely polished yet, we do now have a working application... so feel free to play around with that to see how it works; it's not particularly complex but there were a couple of interesting problems to solve along the way!
Some interesting things that happened
There were a few "honorable mentions" in the coding that I wanted to highlight. Here's a quick summary for you:
When I first ran the game board, I found that I had a bug in the game class - all the punctuation and whitespace was ignored by the game logic, and phrases were all smashed together. This turned out to be a great opportunity to enhance a unit test, which helped me narrow down the cause of the bug and fix it quickly.
Having the game in its own class and just reporting its status back made it super easy to set up the UI. I designed the whole window for the game and got it running without the game code... and then once that was done I could go back in and inject the game into the existing interface.
I caught myself writing some sloppy code in an earlier episode: the game editor window had API calls throughout it! This isn't "bad", but it will become hard to maintain if there are API or database changes in the future. I took this opportunity to enhance the db_api.py file with the rest of the API calls, and then I removed all of the HTTP request code from the editor window and made the editor call to db_api. This means that any more interface maintenance I have to do will happen in exactly one place. In a small app, this might not be too important... but in Enterprise code? You'll need this kind of thinking.
Moving on to today's topic
So if we're not reviewing all the code, what are we going to do today?
Let's talk about SECURITY
We're using a LOT of code that we didn't write in this project.
MongoDB.
The Python runtime.
Flask.
Requests.
And in future episodes, we're likely to add even more. Now for a small-time app, this isn't really a big deal - it's a simple game. It isn't like it's going to have access to any super sensitive data or anything. But let's think about the Enterprise angle again... imagine we're building this not as a little game but as an Application component in some real Production-grade code. We need to ensure we aren't introducing vulnerable components into our applications. How can we stay ahead of this?
We can Snyk up on it
Yeah, I had to Dad-joke that one in there... today we're going to use a product called Snyk that scans our code for vulnerable includes - we can add this into our GitHub workflow to find out if code we're using is vulnerable to attackers and get assistance with updating it.
Snyk has a convenient free tier for low-traffic projects. I configured my free workspace to be connected to my GitHub profile, which was as simple as clicking "authorize". Then I just had to select my project and tell it to scan:
Let's take a look at what it found in the Hangman project:
What does this mean?
There was only a single Critical vulnerability found, in our API Dockerfile.
There are several medium vulnerabilities we should review (2 in our MongoDB Dockerfile and 2 in the requirements.txt file for our API code)
Our actual python code didn't show any problems at all! This is an interesting point to me: it means that I can write "perfect" code but still be vulnerable because of code I included but didn't write myself.
So what are we gonna do about it?
Let's take a look at the critical vulnerability and see what we can learn:
zlib1g is a library included in the Python runtime. According to this report, here are the details:
- No known exploit has been published for this problem.
- There's also no fix for it, even in the later version of Python that's available.
It looks like (at the time of this writing, at least) there's nothing we can do to mitigate our risk. And because this is our database's docker container, there's not a lot for us to be able to do about it anyway. But we know about the problem, and we can keep our eyes out for an updated MongoDB Docker image that resolves the problem in the future.
Let's move on to a different report: the one for our API's requirements.txt.
This shows that the problem was introduced by Pymongo 4.5.0 -> this is the library we use for Flask to communicate with the Mongo database.
But in this case, they've both been fixed! We can actually update our code to use the newer version of Pymongo, and we should be able to resolve our problems. In fact, Snyk will allow us to do this directly from the scan by clicking the button to "Fix this vulnerability".
This takes us to a screen where Snyk offers to open a Pull Request directly in our repository with the updated versions of the libraries. Pretty slick, huh?
Wrapping up
Security isn't usually a developer's favorite topic - it represents a lot of work that doesn't have the "wow" factor you get when you code up a whiz-bang new feature. But hopefully today you've seen how a product like Snyk can be a valuable part of your delivery pipeline... you can manage your whole software supply chain with ease!
Top comments (0)