Learning Static Analysis by Playing Capture the Flag

The GitHub Security Lab has run multiple Capture the Flag contests built around CodeQL, the semantic code analysis engine. The most recent, CodeQL and chill – The Java edition, asked participants to find a remote code execution (RCE) vulnerability in a container management platform. Instead of hunting for a static flag string, competitors wrote CodeQL queries that identified the vulnerable data flow itself — tracking user-controlled input from a Java bean through the application to a location where arbitrary Java code could be executed.

The format is a deliberate departure from conventional CTFs. The goal is to expose participants to real-world vulnerability discovery patterns, using taint tracking libraries to locate a class of bug, not just a single instance. The exercise is designed to be reusable: once a query is written, it can be run against other codebases to find the same flaw pattern elsewhere.

The Winners and Their Approaches

Kanav Gupta took first place. His submissions were noted for accurate and well-organized query code, plus clear explanations for the more difficult bonus questions. Gupta was using CodeQL for the first time and described the experience as an intuitive introduction to static analysis.

“The Java CTF was an awesome way to learn about static analysis and CodeQL. I was using it for the first time and the intuitive structure of CodeQL made writing queries that find vulnerabilities a piece of cake! Such an awesome tool. The challenges in the CTF were very clear and explained the motives clearly.”

Nguyen Jang and Manas Chaudhary tied for second place. Jang demonstrated solid command of the CodeQL libraries, particularly in removing false positives. Chaudhary brought creative solutions to the harder questions and documented them well.

“While this was not a CTF in the traditional jeopardy/attack-defense sense, it's the first where I got to see how vulns in huuuge codebases are like and how the methodology to find them is totally different from sandboxed CTF challenges. Loved this change of pace!” — Manas Chaudhary

Oleksandr Synetskyi and Tony Torralba took fourth and fifth place, respectively. Torralba's writeup included a detailed proof-of-concept and explanations of why certain injection attempts failed. Synetskyi solved a bonus question with an alternative taint tracking configuration, similar to the reference solution.

Synetskyi, who works in digital forensics and incident response, drew a parallel between CodeQL's approach and his own field:

“My main area is Digital Forensics/Incident Response. With that, the most eye-opening experience was the general idea behind CodeQL: being able to reason about code as data and run queries against it to find not just unsafe methods like strcpy, but entire unsafe coding patterns? It looks amazing!

Interestingly, for me this idea resonated with the Incident Response approach of ‘making an adversary's job hard'... CodeQL enables you to do something similar but with vulnerability discovery – its queries can be run not just against codebases they were originally developed for but against others as well, allowing to detect and remediate a whole class of vulnerabilities.”

Reference Solutions and What’s Next

The reference solutions for all challenge steps are published on the Security Lab website. The next CTF challenge has not yet been announced, but sign-up and participation details are available through the Security Lab's involvement page, and additional security resources and team-oriented event listings are maintained on GitHub's security learning hub.