Following my previous case study on Windows application security testing, I returned to my area of expertise: web applications. Familiarity doesn’t guarantee ease, particularly when facing deadlines and a client who’s had their web application penetration tested twice in the past four years.
This case study explores a five-day web application pentest that challenged everything I thought I knew about time management, prioritization, and finding value in previously hard-tested systems.
Racing Against Time
For five days. If you’re new to pentesting, five days seems like plenty of time, but that’s before you consider the documentation, report writing, and the need to provide meaningful findings for the client. Perhaps only the latter causes stress, as the remaining administrative duties can proceed smooth once there’s something to write about.
The client stated their expectations clearly: “We’ve been tested before.” We need to focus on what’s changed, what’s new, and the CMS integration.”
The planned schedule was: reconnaissance and initial testing on Day 1, vulnerability deep dive on Days 2-3, CMS integration testing and validation on Day 4, and report compilation and verification on Day 5.
However, in the end I performed reconnaissance daily in case I missed valuable network traffic data. A lot of time went into uncovering vulnerabilities, with automated and manual tasks performed at the same time. The only part of the original plan I followed was dedicating day 4 to CMS testing. I worked in an agile manner: scanning for issues, discovering them, attempting to exploit them, and then documenting the process. Incrementally.
The Challenge of Previous Testing
Something security courses often miss is that following up on a past penetration test is usually more challenging than testing a completely new application. You need to prove your worth by finding something new, something that actually matters. The vulnerabilities that were easy to catch had already been reported.
However, just because prior reports showed significant injection flaws, and the site is now patched doesn’t mean you shouldn’t test for injection vulnerabilities. Or that you may not discover easily exploitable vulnerabilities. But it is definitely a greater challenge.
The previous report was vast but dated. Although my role focused on evaluating new and modified features, I still had to consult the past report. Therefore, several minutes or hours of time left on the clock were lost because they weren’t estimated in advance.
Gray-Box Testing: Walking in the Dark
The client opted for a gray-box approach, which meant I had some application knowledge and limited access, but not the full picture. In the end, it’s still a good security testing approach, but on the downside, I wasn’t always sure if my exploits were actually reaching the database or just getting caught by some middleware layer.
Usually, I prefer white-box pentest. It’s the most attractive and efficient security testing concept. You can start with black-box testing, assessing the app blindly, and move to gray-box, like using credentials if you couldn’t bypass auth, ending with white-box, assessing all technical aspects including code. Throughout my years of programming, I’ve always loved reading code, and now, being able to identify security issues makes it even more rewarding.
The CMS Integration: Where Things Got Interesting
Integrated with a well-known CMS, the application managed content delivery and user-generated data. I found this integration very helpful for many reasons:
- First, it greatly increased the attack surface. Each API call between the main application and CMS represented a possible vulnerability. Also, the potential for supply chain vulnerabilities emerged: if the CMS was insecure, those issues could affect the main application.
- Above all, it gave me an end-to-end testing route that helped confirm whether my exploits were truly effective or not.
I discovered that user input processed by the main application was being passed to the CMS with minimal sanitization. While the main application had decent input validation, the CMS integration bypassed several of these controls. This resulted in stored XSS vulnerabilities that persisted across user sessions.
By the fourth day, I had identified enough issues that I wanted to prioritize and document them in detail. It’s always satisfying to find more than 10 serious vulnerabilities (medium, high, or critical), along with some less severe ones. As always, prioritization is more of an estimation, and the product team and stakeholders usually have the final say. Because of different project knowledge, certain low-priority tasks were escalated to highest priority, and certain high-priority tasks were deliberately de-prioritized.
Component reuse is always a smart architecture approach
One advantage of this application was its architecture: it reused components extensively. From a development perspective, this was smart. From a pentesting perspective, it meant that finding one vulnerability often led to finding several instances of the same issue. But again, fixing it once will propagate to the other pages as well.
I found a file upload vulnerability in one module that also existed in three other parts of the application. Although the developers created a reusable component, they failed to implement consistent and proper security controls. Because the component is new and security was an afterthought, these incidents are, unfortunately, frequent.
Lessons Learned
- Due to time constraints, prioritization is necessary. With unlimited time, it’s easy to get lost, finding more low-impact vulnerabilities. Five days forced me to focus on findings that actually mattered. However, the limited time doesn’t fully represent the threat landscape.
- Gray box testing needs a strategic approach. Prioritize the areas where you’re able to validate the effect, instead of just spotting potential issues.
- Previous tests are guides, but don’t treat them as solved. They might turn into blind spots. The fact that it was tested before doesn’t mean it is secure in the present.