Ghostwriter: Looking Back at 2021

It has been a while since we last published details about the Ghostwriter project, but the project has been steadily moving forward. As we approach the end of the year it is the perfect time to look back at what we did to set up Ghostwriter for some great updates in 2022.

Reliability & Stability

You may be familiar with Ghostwriter as a project that we debuted in August 2019, but we wrote some of the core code 2016 and 2017. Code rot is real and it frequently caused us small issues that were hard to track down. As the project’s complexity increased and integrated with more external systems, it became clear we had severe technical debt in the form of missing unit tests.

We spent much of the summer writing unit tests to thoroughly test Ghostwriter before every release. To date, we have written 514 individual tests. These tests cover roughly 71% of the codebase, so we have some work left to do. Still, these tests helped us find and squash a myriad of issues and the project is far more stable as a result.

Running Unit Tests

All tests run inside the same Docker containers but use an ephemeral test database. They can be run at any time to quickly and easily test code changes. Running all 514 tests takes less than a minute.

Continuous Integration & Monitoring

If you look at the GitHub repository, you may notice all merges and pull requests are now subject to a few GitHub Actions (look at the bottom of any pull request). To make sure no one ever forgets to run unit tests against new code, any contribution to the main code branch must pass the following workflow:

Before running all unit tests, the workflow steps through the entire new installation setup process as documented in the wiki. This ensures the installation instructions are correct and nothing has changed with Docker, machine images, or the code that will prevent someone from installing Ghostwriter.

New code will only be merged into the main branch if that workflow passes with zero errors. It’s not bulletproof, but this will greatly increase the likelihood that we catch issues before code is merged.

As an additional layer of monitoring, we also set up CodeCov and CodeFactor monitoring. CodeCov monitors for the unit testing coverage so we can see if changes to the code resulted in a decrease in coverage. A decrease would indicate someone forgot to update a unit test or create new tests for their change.

If someone commits broken code that isn't covered by a unit test it could slip through the workflow and merge. This monitoring will show us if coverage has decreased and what new code isn’t being tested.

CodeFactor monitors code quality. It performs an opinionated review of the Python codebase and flags a section of code if it looks to be in danger of deprecation, too complex, inefficient, or might be difficult to maintain.

CodeFactor’s Grade

We thoroughly reviewed CodeFactor’s reports and scrubbed the codebase as much as possible to improve maintainability and efficiency. CodeFactor gives repositories a rough letter grade based on the results. We raised Ghostwriter from C- to an A- in 2021.

The changes that got us to an A- will really only ever be seen by someone working with the code, but that’s OK; we really want it to be easy for any developer to modify or maintain Ghostwriter. That’s why we place such a high value on code quality, style, and documentation.

Proactive Security Improvements

Unit testing and code quality aren’t the only things we started actively monitoring. Ghostwriter also leverages GitHub’s security dashboard and actions to perform static code analysis of all Python and JavaScript.

Example Dependabot Alert for a JavaScript Library

The Dependabot sends us alerts if third-party libraries (e.g., TinyMCE) should be updated to address any vulnerabilities. GitHub’s CodeQL integration performs static analysis with every commit and on a weekly schedule.

Certifying Ghostwriter

We looked to the Core Infrastructure Initiative (CII) as a guide for much of these efforts. CII states:

Projects that follow the best practices below can voluntarily self-certify and show that they’ve achieved a Core Infrastructure Initiative (CII) badge.

We registered Ghostwriter with CII and completed their survey to receive a Passing grade. We set a goal of meeting all requirements unless the requirement was truly not applicable to Ghostwriter. We met that goal in 2021 and documented all of it on the CII page for Ghostwriter, project 5139:


There are Silver and Gold badges beyond the Passing badge. In 2022, we will continue updating CII to progress Ghostwriter towards Silver. Through this effort, we hope to offer a publicly accessible source of information that explains how Ghostwriter meets various best practices.


We’re very excited about Ghostwriter’s next steps. At SO-CON 2020, we mentioned some features we hoped to release in 2021 (e.g., an API). Some of those features — like the API — didn’t happen because we felt so strongly that addressing the technical debt was the top priority and best way forward.

Now that we have a strong, stable foundation, we have made solid progress towards Ghostwriter v2.3 — aka the API release. We’re pleased to say the API is functional and just needs some polish and testing before it’s ready for a release candidate.

Also, you can’t have an API without good role-based access controls (RBAC) for tokens! We’re working on finalizing the roles and permissions for RBAC to release them alongside the API. Combined, RBAC and the API will allow easy expansion of Ghostwriter via middleware scripts. You’ll be able to do things like easily write scripts to import domains from any registrar or automate command-line logging. Expect to hear more about this in the coming months!

For now, thank you for your interest and support of Ghostwriter, and have a happy holiday season!

Ghostwriter: Looking Back at 2021 was originally published in Posts By SpecterOps Team Members on Medium, where people are continuing the conversation by highlighting and responding to this story.

Article Link: