• Post Reply Bookmark Topic Watch Topic
  • New Topic

Iron-Clad Java: Building Secure Web Applications  RSS feed

 
Book Review Team
Bartender
Posts: 962
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Author/s    : Jim Manico, August Detlefsen
Publisher   : McGraw-Hill Osborne Media
Category   : Miscellaneous Java
Review by : Jeanne Boyarsky
Rating        : 10 horseshoes

It's taken me a while to write a review of "Iron-Clad Java: Building Secure Web Applications" because it motivated me to fix two security vulnerabilities in CodeRanch - clickjacking and brute force login. (and I didn't want to post this review until they were deployed)

The concepts were explained clearly in addition to tactics and patterns/anti-patterns. I particularly liked the emphasis on security vs usability. The explanation for the different types of XSS attacks and using encoding appropriate to the context was excellent. I like that there was a whole chapter on logging.

I learned a lot reading this book; even about topics I thought I knew a lot about. I hadn't known oWASP had an HTML validator. I hadn't heard of null byte attacks.

For many of the vulnerabilities, the book suggests libraries you can use to help. I hadn't heard of Apache Shiro. I was surprised OWASP's CSRF filter wasn't mentioned though.

The book targets Java developers, project managers, web security penetration testers and technical managers. I was skeptical that a book with so much code could be useful to managers. After reading the book, I'm convinced. Skipping over the coding sections gives managers an appreciation and the vocabulary for discussion security with their staff.

If you have a web app, you should definitely get this book.


---
Disclosure: I received a copy of this book from the publisher in exchange for writing this review on behalf of CodeRanch.

More info at Amazon.com
 
George Mournos
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I really liked this book, I learnt from it like you did, and I got a lot of value for my money...

But I would like to share two negative points, in this otherwise excellent book.

*I think there are problems in how the authors approached the CSRF subject that go further than not mentioning the OWASP CSRF Filter.
They haven't mentioned the "Same Origin Policy" at all which is central to the problem and to its solutions.
The "Synchronizer token" solution only works because the malicious script cannot do an HTTP-GET to retrieve the token before HTTP-POSTing, because of the "Same Origin Policy".
Ok, this sounds like there is not enough clarity in the explanation and it is not a mistake.
But their treatment of the "double submit cookies" solution is a mistake.
The malicious script cannot read the second cookie used to hold the csrf token because of the "Same Origin Policy".
The authors somehow miss this, and they input this to the cookie being HttpOnly.
However, what happens is exactly the opposite, the cookie SHOULD NOT BE HttpOnly, for javascript frameworks like AngularJs and DWR to be able to manipulate it.
I think this chapter should be re-written, with a clear reference to the "Same Origin Policy" and its impact.

* The authors present the "Insecure Direct Object Reference" Attack as a special case of SQL injection.
Specifically, a case of SQL injection where the injected part is in the "order by clause".
However, the "Insecure Direct Object Reference" Attack is something different and is not necessarily restricted to SQL databases.
Failing to describe the problem properly they also fail to present proper solutions, like the ESAPI RandomAccessReferenceMap class.

Ok, I regret if this post sounds too strict cos I found the book otherwise perfect and I learnt a lot from it.
 
Campbell Ritchie
Marshal
Posts: 56197
171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Have you any ideas what one could do about such omissions? If anything.
 
George Mournos
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, Chapter 5 really misses a reference to the same origin policy.
So after reading section Synchronizer Token Pattern in Chapter 5, one can come up with the question:
Suppose we have site vulnerable.com that renders a form after a GET request and submits the form with a POST request, and that we should CSRF protect the POST.
If the malicious site evil.com can send requests to vulnerable.com with session riding, why does it not issue beforehand a GET to render the form, harvest the CSRF token, and then submit the POST.
The answer to this is that the Same Origin policy forbids evil.com to access content from vulnerable.com.
But one cannot just comeup with this answer, if the same origin policy has not been introduced in the book.
Also, I think it is too late to introduce the Same Origin Policy so late in the chapter, when we already discuss solutions.
In the CSRF attack you ride the user session to issue requests from evil.com to vulnerable.com but you cannot see the results of these requests, due to the Same Origin Policy.
The same origin policy is kindof part of the definition of CSRF, so I think that the authors should first mention the Same Origin Policy when they introduce CSRF .
Then. in the discussion of Synchronizer Token Pattern later in the same chapter, they should analyze the above scenario and make another reference to the Same Origin Policy.
And they should make a reference to the OWASP CSRF Guard Project, it is THE flagship project afterall!!!
Finally to close Chapter 5, the authors should review the Stateless CSRF Defense section.
In their coverage of the double submit cookie solution, they write that the csrf cookie should be HttpOnly.
However, I am quoting wikipedia's CSRF entry, "The CSRF token cookie must not have httpOnly flag, as it is intended to be read by the JavaScript by design"
and from the CSRF Prevention_Cheat_Sheet, "An attacker cannot read any data sent from the server or modify cookie values, per the same-origin policy".
It is the Same Origin policy that does it and not having the cookie HttpOnly. In fact the cookie should not be httpOnly(view DWR, AngularJS...)
The authors should rewrite this section, correct the cookie, and again make a Reference to the Same Origin Policy and also to popular Javascript frameworks.
Btw, when they discuss who uses this method, they speak about stateless webservices and applications that want to keep nothing in their httpSession,
and they dont speak about popular Javascript frameworks, which make heavy use of the technique. This is kind of weird...

Finally in chapter 7, section Defence in Depth, the authors present the "Insecure Direct Object Reference" Attack as a special case of SQL injection.
Specifically, a case of SQL injection where the injected part is in the "order by clause".
However, the "Insecure Direct Object Reference" Attack is something different and is not necessarily restricted to SQL databases.
Failing to describe the problem properly they also fail to present proper solutions, like the ESAPI RandomAccessReferenceMap class.
The authors should just rewrite this from scratch, it is totally wrong.

I have made a much larget post, and I am afraid I just said the same things again.
Also, I probably sound too strict but the book was great it was by far my best read for 2014
 
Jim Manico
Author
Ranch Hand
Posts: 53
7
Java MySQL Database Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
George,

Great feedback. I appreciate you taking the time to provide such rich detail.

> If the malicious site evil.com can send requests to vulnerable.com with session riding, why does it not issue beforehand a GET to render the form, harvest the CSRF token, and then submit the POST.

This is not possible. Harvesting the token is only possible via cross site scripting on the vulnerable site itself. Evil.net does NOT send the request to vulnerable.com, it HOSTS that request. The evil request to vulnerable.com lands in the users browser and submits the request. Evil.com has no way to see that result. Make sense?

> The answer to this is that the Same Origin policy forbids evil.com to access content from vulnerable.com.

Exactly. I will make this clarification in the second edition. I agree, we need to clean this up!

> But one cannot just comeup with this answer, if the same origin policy has not been introduced in the book.

Agreed. We need a good section on CORS early on and will add that to the second edition. I'll be sure to give you attribution.

> And they should make a reference to the OWASP CSRF Guard Project, it is THE flagship project afterall!!!

I am not a fan of the architecture of that project, I did not include it *on purpose*. I would rather folks use the built-in defense seen in most frameworks or do it manually. This was a conscious choice to not include it. I find it to be a rather weak and problematic project, especially the fragile JavaScript based injection method. But I do not want to get into why I do NOT like things, I'd rather focus on the good - hence the book, I hope.

> Finally to close Chapter 5, the authors should review the Stateless CSRF Defense section.
> In their coverage of the double submit cookie solution, they write that the csrf cookie should be HttpOnly.

This is a mistake. We fixed this already and you will see that fix in the next edition.

> they speak about stateless webservices and applications that want to keep nothing in their httpSession,
and they dont speak about popular Javascript frameworks, which make heavy use of the technique. This is kind of weird...

ok, we will mention those frameworks next edition, easy to add.

> Finally in chapter 7, section Defence in Depth, the authors present the "Insecure Direct Object Reference" Attack as a special case of SQL injection.
> Specifically, a case of SQL injection where the injected part is in the "order by clause".
> However, the "Insecure Direct Object Reference" Attack is something different and is not necessarily restricted to SQL databases.

George, I did not state that Direct Object Reference was a special case of SQL Injection. I think you misread this section. I explained myself in detail in the next post.

> Failing to describe the problem properly they also fail to present proper solutions, like the ESAPI RandomAccessReferenceMap class.

As a side note, ESAPI is so far from production quality and is no longer maintained so I do not suggest using it in production for most folks.

> Also, I probably sound too strict but the book was great it was by far my best read for 2014

This was not strict at all, it's great help! Thanks kindly for your deep feedback. You are mostly "spot-on". I will be sure to make these changes in the second edition and give you full attribution for these suggestions.
 
Jim Manico
Author
Ranch Hand
Posts: 53
7
Java MySQL Database Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
George,

I think you misread the Direct Object Reference section in the SQL injection chapter. Here is the exact paragraph that I submitted to McGraw-Hill.

"There are situations where Query Parameterization is not possible in code. These exceptions are rare but do come up in legacy code. For example, table names and column names are not parameterizable for some database vendors. Although this situation leads one to ask, "Why is untrusted data driving a column name or table name?" they are often used by developers to created reports which only include certain columns or allow end users to specify custom sort options. This pattern can be considered to be the OWASP Top Ten 2014 risk, Insecure Direct Object Reference. When it is necessary to rapidly fix vulnerabilities in legacy code, and Query Parameterization is not possible, sometimes another defense such as input validation can be used to get around this limitation."

So, there are times that using the PreparedStatement class to bind certain variables during Query Parameterization is not possible. For example, if your query contains table names or column names that are driven by user input, then you simply cannot bind those varables in some databases. In fact, when you let a user drive a column name, it's a case of Direct Object Reference and is a vulnerability in and of itself independent of the injection.

So George, I stand by this section and the intention behind it. I will try to clarify it a bit more in the second edition.
 
Jim Manico
Author
Ranch Hand
Posts: 53
7
Java MySQL Database Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
George,

So in summary - I think your concerns about chapter 5 is spot on. That's a big mistake and I'm making the change today in my second edition transcript.

Here is the mistake in the book:

"The client is now responsible for saving and sending this random value value in both the request (as a hidden form field or other request parameter) and in a cookie. The cookie should be at least HTTPOnly since JavaScript code should never need to access this value."

I am changing this section to:

"The client is now responsible for saving and sending this random value value in both the request (as a hidden form field or other request parameter) and in a cookie. The cookie must not be HTTPOnly so JavaScript code can read the cookie and place the same value in another part of the request. Due to same-origin policy, only code delivered from the same domain will be allowed to access cookie data."

In addition to this change, I'm adding a section on CORS in chapter 1 or similar.

Did I address all of your concerns?

George, you rock. I love this level of detail from you. Is that all you got? Bring in on. What other nits do you see?

I'm jim@manico.net and if you want a free copy of the book to give to one of your friends, let me know. I'll ink in the changes by hand before I send it.

Aloha,
Jim
 
George Mournos
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim, thanks for your good words.
But maybe your enouragement will get you into trouble, cos I will be back with more comments...

So, I think I understand now your intention but I still disagree with keeping the reference to Insecure direct object reference (IDOR).
Of course this is just my personal opinion, it is your book after all...

But IDOR is when the object reference comes from the url or user input, and you can use it to access other Objects for which you have no permission.
So, in your example of the "order by" columns, if one does an IDOR attack and substitutes one "order by column" with another, he could order results in ways for which his has no access. This is not an attack (no impact)!!! On the other hand, if one does an SQL injection attack, he can inject a "drop database" statement.
OK, in the case of table names, one can substitute a different table to make unauthorised reads. In this contrived case, which is kinda unrealistic, cos it violates every software engineering principle, indeed we do have an IDOR attack.

So, after a second read of the section, I think I understand your motivation of talking about cases where one cannot use query parameterization and I am not suggesting that you scrap the whole section. But do you really have to refer to IDOR? You could change the example to have table names instead of column names to support the IDOR cause, but to be honest, I would scrap the reference to IDOR. I think it just promotes confusion, well at least you got me confused Also, the solution you propose is not one in the OWASP IDOR Cheatsheet, it is better that the readers have consistent sources.

I have a suggestion also, for the case when one cannot use query parameterization, that might be more common than having table names in user input.
I am not sure if you can use it in your book, but I ll shoot and it is up to you...

A common case when one has dynamic queries is when one has a "Query by Example" form.
In this case, if one cares about performance (otherwise one can outer join all tables) it is common to have logic like this:
* if the search field has a value then do an inner join with the table that contains it.
* if the search field does not have a value but we want to show the field in results, then do an outer join with the table that contains it.
* else, ignore the table that contains the search field.
Now, if one is using JDBC one has to do this for every search field and has to dynamically build the query.
But if one is using JPA, he can use the Criteria API and leave e.g. Hibernate do it for him.
It is more about ORMs than SQL injection, but I think it is the most common case of having to write a dynamic query.

Eliminating the need to have a dynamic query and use the Criteria API which will handle SQL injection...
It might sound a bit far fetched, but passing the table names to the user to edit is even more

I will write you now to get a free copy of the book, before I make you change your mind with me commenting it all the time


 
George Mournos
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim,

I also feel that you should say something more in the book about IDOR (but not in the SQL injection context

It is a recurring problem, in fact next week I will have to patch a page of downloading files in a legacy application with this vulnerability.
And because it is very difficult to retrofit proper server side security for this page, to check if the current user really has access to the file referenced, I will use the solution called "object reference" in the IDOR Prevention Cheatsheet.
For this, I put in the user's HttpSession the ESAPI RandomAccessReferenceMap class, which:
*is threadsafe, in case of many parallel requests for the same user, from multiple tabs or ajax.
*handles the random string generation by delegating to java's SecureRandom.

This solution has worked for me well in the past.
Now, I see your comment above that "ESAPI is so far from production quality and is no longer maintained so I do not suggest using it in production for most folks".
I am not so concerned by it, cos the part I use for IDOR is just two classes, one that delegates to SecureRandom and one that handles a couple of ConcurrentHashMaps to keep the correspondence of Key-Object and vice versa.
I see nothing bad about these classes, and in the worst case I could extract them and maintain them myself.

But if there is something better out there, I would like to know it.
So, I would like to see IDOR discussed in the second edition of your book.

 
George Mournos
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim,

About your comment on the OWASP CSRF Guard Project: "I am not a fan of the architecture of that project, I did not include it *on purpose*. I would rather folks use the built-in defense seen in most frameworks or do it manually. This was a conscious choice to not include it. I find it to be a rather weak and problematic project, especially the fragile JavaScript based injection method. But I do not want to get into why I do NOT like things, I'd rather focus on the good - hence the book, I hope"

I agree that one should better use the built-in defense if there is one.
I am not sure that I agree that one should do it manually.
I don't understand what you mean by "the fragile JavaScript based injection method".

I haven't used the OWASP CSRF Guard Project for two years, so it is not fresh for me.
But I used it in a SpringUI app using jsps and a custom javascript framework wrapping jquery.
I think, in the server side I just installed a Filter and in each ajax call I was passing (myself) a header containing the CSRF token.
I have to review my work (I will do it sometime next week) but I don't remember anything funny about the CSRF Guard Project.

I don't understand what you mean by "the fragile JavaScript based injection method".
Can you elaborate?

Anyway, I think that with this, I am now out of comments At last.
It has been a pleasure reading the book and commenting and I hope I did not tire you too much.

Bonne nuit

G
 
Jim Manico
Author
Ranch Hand
Posts: 53
7
Java MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
George,

Looks like we are mostly on the same page. A few final notes from me.

1) I really do not want to get deep into criticism of CSRFGuard, I would rather focus on what I feel are positive patterns. I am happy to discuss this with you offline if necessary. I did keep it out of the book intentionally.
2) As men of intelligence we can respectfully disagree. I do stand by the four sentences or so where I discuss the DOR issues with untrusted-data-driven table names and column names in queries. I have run into this anti-pattern in several significant applications. Once in the 90's at the worlds largest company at the time, then in the 2000's at one of the worlds largest social media apps at the time, and then recently in a OSS project. I intentionally do not want to point out the exact project (it's now fixed) since I prefer to focus on the good and not criticize.
3) However, I do think I need to expand on what other portions of a query cannot be parameterized for certain database vendors. I plan to take the table/column name section and put it in a new more verbose section that goes over "what to do when you cannot parameterize" in more detail.

Is there anything else lingering that we need to discuss, George?

Aloha,
Jim


 
Jim Manico
Author
Ranch Hand
Posts: 53
7
Java MySQL Database Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
George,

One more thing....

> I also feel that you should say something more in the book about IDOR

I would read the access control chapter for that, especially the permission centric and data centric access control discussions. That is the real way to address this issue. Most IDOR issues root cause is a weak access control mechanism. When dealing with these complex issues in a legacy app there is only one path to security - a LOT of hard work.

Many will tell you to put up a "object reference map" to deal with IDOR. That might be a quick fix but it's a weak one. What you really need is a data-contextual permission-based access control system like we see in Apache Shiro, the NIST ABAC standards, and other emerging tools and standards.

Aloha,
Jim
 
George Mournos
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jim,

I think your answers cover everything I would ask.

Also, my suggestion to speak about the Criteria API in JPA is irrelevant to the problematic cases when you cannot use query parametrization.
It can eliminate the need to write messy SQL, but even if one writes this messy SQL, one can use query parametrization.
So it is irrelevant to the problem and of no use in this section.

Well Jim, thanks for your great book and for your prompt answers.
It was my best read for 2014 and I learnt much from it.
Looking forward to your second edition and to more books from you about Security (l liked the idea of Laser-Powered-Armor-Clad Java )

 
Leandro Coutinho
Ranch Hand
Posts: 423
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
George Mournos wrote:
So, in your example of the "order by" columns, if one does an IDOR attack and substitutes one "order by column" with another, he could order results in ways for which his has no access. This is not an attack (no impact)!!!


I think this can be used as an attack. For example if someone can only see a list of the last 10 suppliers, then order by some other thing like supplier owner or contract value. Probably a poor example, but I think there are some cases that this can be bad.
 
Jeanne Boyarsky
author & internet detective
Sheriff
Posts: 37384
531
Eclipse IDE Java VI Editor
 
Book Review Team
Bartender
Posts: 962
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Review by : Ulf Dittmer
Rating        : 9 horseshoes

Putting a web platform out in the open means exposing it to all kinds of threats - internal or external, incidental or deliberate, trivial or life-threatening. This book aims to educate the reader as to what might happen to Java web apps (including web services), and how to secure them against all enemies. While a lot of the content is cross-platform (dealing with HTTP, JavaScript, SSL/TLS etc.), the code examples and the proposed remedies all assume that Java is being used, so the book can only be recommended to those working in a Java context. With that caveat, the threats (XSS, CSRF, SQL injection and many others) are discussed in depth, remedies are proposed, sometimes several with varying levels of implementation effort required.

Since prevention is only part of the security effort, the book also touches on detection and response - while preventing attacks seems the best course of action, sometimes attackers will get through despite the best of efforts, in which case detection of a successful attack comes into play, and then some kind of response. The final chapter discusses how one might adapt the SDLC to incorporate secure coding guidelines.

Security is still not an integral part of the education of most developers. This book is an excellent overview of what's involved in securing Java web apps and web services. While there's a neverending string of attacks (these days even discussed in the mainstream press, if bad enough), it is where a Java developer should start fighting back.

More info at Amazon.com
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!