Advanced
At this point, we have a probable SQL injection vulnerability, and we've begun the task of tracing a logical path to exploit this problem through malicious user input. However, marking every possible branch and function call manually can quickly be overwhelming, especially if the search is dozens of layers deep across multiple files and folders of the codebase. We can use some of the features in Loci Notes to help us manage this, and to quickly find and mark what we need.
- First, lets think ahead a bit to possible Sources for our vulnerable Sink. Given a Java Spring Boot web application like Project Diligence, the most likely way that user input enters the application is through HTTP requests. In Spring, these are (usually) defined via
RequestMapping
decorators. So, if we want to know the moment that we find a possible input source while searching for calls to our vulnerable Sink, we should drop a note at each defined Spring endpoint. We can do this manually, but Loci Notes lets us do this as a batch. - Bring up the Search pane (Ctrl-Shift-F) and break out the small pane on the left into a full editor page (via the Open New Search Editor button in the Search pane). This gives us more room to work with for building our search, and is required in order to bulk export comments in Loci Notes. Enable Regular Expressions in the search window, and enter the following regex:
@(Request|Get|Post|Patch|Put|Delete)Mapping
- Quickly glance through the results provided in the search pane. Given that
@RequestMapping
is used only by controllers, not by the endpoints, we can remove that remove the "Request" field from the regex in order to have only endpoints in the search results. Remove it, and ensurethe results inside the search window are what is expected.
- Next we want to mark every search result we found with a note declaring them as a possible Source for user input, so that if we come across one later, we will be able to see the full Source to Sink path easily. To do this, issue the "Comment All Search Results" command to VS Code (hot key is Ctrl-Shift-P for issuing commands). Fill out the Status and Priority accordingly, and put a note like "User input Source". Once completed, you can refresh the full list of Artifacts in the Loci Notes side pane and see that all previous search results have been marked accordingly.
Knowing all possible HTTP request endpoints is itself a useful exercise, even outside the scope of the current possible SQL injection problem. Use this search and export capability to ensure coverage across the entire appication's input surface, not just what you might see during a live test.
- Now that we have marked possible Sources, lets start at the vulnerable Sink/Artifact at
diligence-main/src/main/java/com/thetwitchy/diligence/repositories/impl/DynUserRepositoryImpl.java:30
. We're going to place a bookmark at this spot in order to easily see it, and find it later. Use the hotkey Ctrl-N, and you should see a small bookmark inserted into the gutted next to the line number, and a popup indicating the new bookmark. Additionally, if you have the Loci Notes Navigation pane open, you should see that your bookmark has been inserted there as well.
- The bookmarks in Loci Notes are organized as a stack, as this has several useful properties and funtions when navigating through code. The most important idea is that when in a stack, only the "top" bookmark can be operated on. That operation can include a push (add a new bookmark to the top), peek (go to or look at the top), and pop (remove the top). In each case, no matter how many bookmarks are under the top, we can always backtrack until we get to the root of the stack, or in our case, the root cause of our search (the SQL injection vulnerability).
- We've already marked the root of our search, so lets trace possible paths again, but this time use the bookmarks to help you "link" each callee to it's caller, instead of doing that manually like before. If you get lost, use the Peek (Ctrl-Alt-N) to find your way back to your last bookmark. If you find your self in a dea end of code, use Pop (Ctrl-Alt-Shift-N) to remove the last bookmark and Peek the new top, and if you find logical branch, or you just want to mark your spot, use Push (Ctrl-N) to place a new bookmark. Recursively do this until you find a previous note indicating a user input point.
In general, use as many bookmarks as is needed to be helpful, but a good guideline is a bookmark for each branch, and a bookmark for the start of each function (which is also usually a branch).
It may be helpful to learn about the Depth First Search algorithm, which is a technique to use a stack to navigate a graph, likethe one present in code. This is the primary technique by which paths are methodically searched during code reviews. Loci Notes just tracks the nodes and data.
Once you find the full Source to Sink path, and assuming no security controls along the way, you've found an exploit path to the SQL injection vulnerability. You should confirm this with real testing for real projects, but we also want to ensure that we capture the path quickly in case we need to come back to it, or find another path later (just because there is one path doesn't mean there isn't more to the same vulnerability). We can quickly do this by issuing the "Comment All Navigation Stack Locations" command to VS Code (Ctrl-Shift-P), and filling out the comments like we did with the search results.
In addition to the comments and status update, Loci Notes also automatically inserts links to the previous and next elements of the bookmark stack so that we can quickly view the entire set of bookmarks, in order, as needed.
- And we're done! Use the techniques from this tutorial along with the features provided by VS Code and Loci Notes to improve your code reviews and ensure that even small vulnerabilities can be found and used effectively, no matter how large and complex the codebase. If you run into problems or have questions, open an issue in GitLab or ask in Discord.