We were pretty coni dent about our application, so we all grabbed some popcorn
and watched the test phases. After a huge set of successful tests, one i nally failed.
The security guys had managed to capture the Hypertext Transfer Protocol (HTTP)
request and change some parameters to get a response from the application. The
issue was not huge because the middle tier had its own authorization system.
Nevertheless, the tweaked request could access an authorized response.
To summarize, the client should call several services to access a resource. Let's say
service A returns some IDs and Service B could be called with the IDs returned
from Service A. Similarly, Service C could be called with one of the IDs returned
from Service B. This means that an intruder could capture and insert a random B
ID, which the user was authorized to query but didn't. In such a case, the client
would bypass the standard call l ow and access a resource.
Because the accessed information was a resource that the user authorized, the issue
was not huge. Still, it was reported as a security l aw that bypassed regular l ow;
this got attention.
The application was already completed and tested, and we didn't really want to
refactor the application. Instead, we came up with a brilliant idea: Because in each
request the client needs to use an ID from the previous response, we could capture
all returned IDs. If the requested ID was from the list of queried IDs, we could
easily let it go or invalidate the session and force the user to log in again.
The idea was simple but effective, yet we didn't know how to implement it with
minimal change. Because everything we wanted to do related to web requests,
intercepting and validating them seemed like a good idea. Luckily, Java already
offered a built‐in solution, and we didn't need to use a fancy third‐party
The solution was to implement a servlet i lter. This would cache the requested
IDs in the response and check whether the next request had a valid ID from the
list. We only needed to add a class i le that acted as the servlet i lter and an XML
dei nition to put the servlet i lter into action. The solution was pluggable and
could be integrated with no problem. Also, it came with an option to turn it off in
The system not only passed all security tests, but it went beyond expectations. We
could easily log and extract statistical data from request/response pairs. Best of all,
the solution did not have an impact on the overall architecture and complexity of
AOP can be a great tool to encapsulate common nonbusiness concerns. However, AOP can also
be confusing if it adds behavior to business logic. Such implementations cause decentralized,
distributed, and hard‐to‐test‐and‐debug business logic. The resulting code would be hard to