In the new Ajax chapter of the OWASP Guide, you write that Ajax applications face the same security issues as all Web applications, plus they have their own set of risks. What are the key risks developers need to be concerned about?
Essentially, the primary additional risks are:
(1) Ajax apps, by definition, have a greater attack surface than normal apps.
(2) Ajax apps have to store state and process code on a completely untrustworthy client -- the user's browser. Don't believe everything you get from the user, and don't trust client-side validation as your client-side validation routines are completely optional for attackers.
(3) Ajax apps have a few more methods of performing interesting HTML injections.
(4) Ajax apps can do things in the background (the "asynchronous" bit), and an unauthorized action doesn't necessarily need to appear on the user's screen, so they may not be aware of an attack. Attackers have already extended session hijacking attacks (cross-site request forgery) in Ajax-enabled apps, such as the Samy MySpace worm. We expect more.
And (5) data mashups can have serious privacy concerns -- be careful about who you send private data, particularly if you're in the European Union or other strong privacy regimes. You also write that use of Ajax requires careful consideration of architecture, server-side access control, state management and strong validation to prevent attacks. Let's look at these areas one by one. Will appropriate architecture solve a good portion of Ajax security vulnerabilities?
Yes. Ajax is essentially a client-side model, and there is a strong temptation to write code just once to avoid added expense and development time. With Ajax, that means writing code on the client first and leaving the dregs for the server (if there's anything on the server at all). This is the wrong approach from a security perspective. Reusing server-side controls to revalidate, perform canoncalization and encoding and properly authorize actions is vital.
Architects should design their Ajax apps around a lean-client, service-orientated architecture model (you don't have to use Web services to be "SOA"). Leave the authorization, validation and business logic smarts on the server. The client is essentially untrustworthy and should be treated with extreme care.You give an example of an Ajax framework connected to an SOA end point as being insecure. Can Ajax safely be used in an SOA environment?
Often I find SOA services are 20-plus years old semi- or completely stateless CICS transactions written in COBOL or PL/1. Ancient CICS transactions do not expect the inquisition of a skilled hostile attacker armed with a capable testing tool and a working knowledge of z/OS, EBCDIC and XML injections. It's hard to justify the expense of hiring guru COBOL graybeards to add XML awareness, validation and canoncalization to such old code. The original coders assumed that the CICS transaction would be mapped onto a 3270 green screen terminal and that the user was a trusted staff member. That is not a valid assumption when you've exposed the transaction via Web services or an Ajax-compatible Web interface.
Ajax apps run on untrusted clients and generally implement very basic methods of performing server-side calls, such as simple GETs or POSTs. To allow such apps to call "pay $2,500 to my mortgage from account X" by calling an SOA endpoint without that dollop of security goo known as WS-Security means placing a lot of trust in the client.What types of security measures should all SOA endpoints implement?
All SOA endpoints should implement (1) access control -- authentication and authorization -- to prevent rogue callers; (2) confidentiality and integrity for data in transit, such as SSL, as per the value of the transaction or asset being protected; (3) some form of strong sequence control to prevent replay attacks, such as cryptographically strong random reference numbers; (4) validation to enforce server-side data validation; (5) awareness of many forms of injection, such as XML, HTML or DOM injections and prevent "interesting" data; (6) business logic validation to enforce business rules; and (7) a place to stash sensitive state without exposing it to the caller between transactions.
I believe that most SOA endpoints are not sufficiently hardened to accept a connection from an attacker with even a fraction of my skills -- and penetration testing is not my forte. I feel it is inappropriate to give untrusted/potentially infected browsers mainline access to exposed SOA services calling ancient code, particularly when real money or goods can be lost to a motivated attacker.
The SOA layer should be fronted by a Web application server. This allows the Ajax client to have a place to log in and identify itself properly, be properly authorized to call an SOA service, stash sensitive state securely, and control the application a little more, particularly if you go for the lean-client approach.
It also allows the application server to remain one of a handful of callers to the SOA layer (rather than thousands), allowing existing controls such as firewalls and WS-Security to exist and remain manageable for most enterprises. Scalability can also be handled by using reliable messaging methods, such as MQ or queuing components. Ajax is not a reliable messaging layer, which is important for messages like "pay my mortgage."
Andrew van der Stock is a leading Australian Web application researcher. He is the moderator of webappsec and helped organize the Melbourne OWASP chapter. Van der Stock is leading Version 3.0 of the OWASP Guide to Building Secure Web Applications, which includes a new chapter on Ajax.