Showing posts with label Hypertext Transfer Protocol. Show all posts
Showing posts with label Hypertext Transfer Protocol. Show all posts

Monday, February 14, 2011

Five Steps to a More Secure Web App

There are a number of different authentication methods available to choose from when launching (or updating) a Web application. Choosing the wrong method can leave the system (or worse, the users) vulnerable to cyber attacks or identity theft.

Below are five rules that should always be obeyed (regardless of the method). By considering these rules and how your users will use your system, you can better understand the security requirements of your Web application and can choose the right method.

1) Never send clear user passwords over an unencrypted channel.

When passwords are sent over an unencrypted channel, anyone who has access to the network (and a little know how) can read them. This should never be done with user supplied passwords (not even for intranet websites). Users often use the same password for multiple systems. Exposing a user's password in one system puts them at risk in another.

Both basic authentication and form-based authentication are vulnerable to this and should never be used when users can choose their own passwords. Digest authentication and encrypted logins do not send clear passwords, and can be used when users can choose their own passwords.

HTTP basic authentication and HTML form-based logins can be used in secure networks to restrict Web access as long as the passwords are pseudo random, unpredictable, and unique across other systems.

For systems that allow user created passwords, care must be taken to ensure the passwords are not readable by others by using HTTPS or digest during logins.

2) Never send session tokens unencrypted over a shared network.

Unencrypted session tokens are visible to anyone who has access to the network. Although session tokens don't expose the user's password, they do allow hijacking accounts with unlimited access. This should never be used over a public wifi network (or other shared network) to access private information or make changes.

Cookie based authentication over HTTP is vulnerable to this. Digest authentication and HTTPS sessions are not vulnerable.

Digest authentication uses a unique "salt" for every request and digest systems prevent the same "salt" being used more than once (although this is optional). By never using and never allowing the same authentication token twice, digest authentication prevents account hijacking.

HTTPS requests are encrypted and prevent eavesdropping from others on the network, preventing access to any request tokens that might be present.

Only allow HTTPS using keys from a certificate authority, HTTPS with self signed keys, HTTPS with mixed content or digest authentication should be used to exchange private information over shared networks.

For more information about the vulnerabilities of using session tokens see Weaning the Web Off of Session Cookies.

3) Always verify information sent over an insecure network.

Insecure networks may be vulnerable to malicious attacks such as DNS posioning, or a trojan Web proxy. These attacks are often called man-in-the-middle and can manipulate the content from the server before it reaches the client (and vice-versa).

Most unencrypted HTTP communication is vulnerable to this. Even mixed content of both HTTPS and HTTP is vulnerable to man-in-the-middle because compromised HTTP content can read and manipulate HTTPS content.

Although digest authentication includes an optional integrity check to prevent this, most browsers either don't check or don't indicate to the user if the content has been verified.

All Web browsers verify HTTPS content (when not mixed) and this should be used for insecure networks. For mobile devises that often connect from potentially insecure networks HTTPS (self signed or CA signed) should be enabled by default for any private information.

4) Never give confidential information without verifying authenticity of the server.

Well disguised URLs and familiar looking pages can trick users into visiting and pseudo-logging into illegitimate websites. If your website asks your users for confidential information, ensure there is a clear way for your users to verify the authenticity of the site before logging in. Otherwise, your users might give confidential information to untrustworthy third parties without even knowing it.

HTTPS using previously distributed keys (such as keys from an established certificate authority) allow the user to verify the organization in their browser (near the address bar). This allows the user to quickly verify authenticity of the server.

HTTPS with self sign certificates cannot be used to verify authenticity unless they have been previously distributed through a secure channel.

Although digest authentication can include authentication-info to verify authenticity, most browsers either ignore it or don't indicate to the user when the site is verified. However, most browsers do show the host name and realm to the user for review before logging in and this does give the user a chance to check to domain name before logging in.

Always use HTTPS for confidential, or sensitive information.

5) Never access sensitive information over an unencrypted channel.

HTTP traffic can be viewed by any who has access to the network. It is vital that all sensitive information is never sent over unencrypted HTTP. Sensitive information should always use HTTPS.

Only exclusively HTTPS with known certificates should be used to exchange sensitive information with its users.

Always use HTTPS for confidential, or sensitive information.

In summary

By obeying these five rules you can pick the right authentication method and prevent your system and users from being vulnerable to cyber attacks and identify theft.

Sunday, November 28, 2010

Status Code 200 vs 303

The public LOD has been dominated by discussions on using 303 in response to a GET request for distinguishing between the requested resource identifier, and a description document identifier.

Some resources can be represented completely on the Web. For these resources, any of their URLs can be used to identify them. This blog page, for example, can be identified by the URL in a browser's address bar. However, some resources cannot be completely viewed on the Web - they can only be described on the Web.

The W3C recommends responding with a 200 status code for GET requests of a URL that identifies a resource which can be completely represented on the Web (an information resource). They also recommend responding with a 303 for GET requests of a URL that identifies a resource that cannot be completely represented on the Web.

Popular Web servers today don't have much support for resources that can't be represented on the Web. This creates a problem for deploying (non-document) resource servers as it can be very difficult to set-up resources for 303 responses. The public LOD mailing list has been discussing an alternative of using the more common 200 response for any resource.

The problem with always responding to a GET request with a 200 is the risk of using the same URL to identify both a resource and a document describing it. This breaks a fundamental Web constraint that says URIs identify a single resource, and causes URI collisions.

It is impossible to be completely free of all ambiguity when it comes to URI allocation. However, any ambiguity can impose a cost in communication due to the effort required to resolve it. Therefore, within reason, we should strive to avoid it. This is particularly true for Web recommendation standards.

URI collision is perhaps the most common ambiguity in URI allocation. Consider a URL that refers to the movie The Sting and also identifies a description document about the movie. This collision creates confusion about what the URL identifies. If one wanted to talk about the creator of the resource identified by the URL, it would be unclear whether this meant "the creator of the movie" or "the editor of the description." Such ambiguity can be avoided using a 303 for a movie URL to redirect to a 200 of the description URL.

As Tim Berners-Lee points out in an email, even including a Content-Location in a 200 response (to indicate a description of the requested resource) "leaves the web not working", because such techniques are already used to associate different representations (and different URLs) to the same resource, and not the other way around.

Using any other 200 status code for representations that merely describe a resource (and don't completely represent it) causes ambiguity because Web browsers today interpret all 200 series responses (from a GET request) as containing an complete representation of the resource identified in the request URL.

Every day, people bookmark and send links of documents they are viewing in a Web browser. It is essential that any document viewed in a Web browser has a URL identifier in the browser's address bar. Web browsers today don't look at the Content-Location header to get the document URL (nor should they). For Linked Data to work with today's Web, it must keep requests for resources separate from requests for description documents.

The community has voiced common concerns about the complexity of URI allocation and the use of 303s using today's software. The LOD community jumped in with a few alternatives, however, we must consider how the Web works today and be realistic on further Web client expectations. The established 303 technique works today using today's Web browsers. 303 redirect may be complicated to setup in a document server, but let's give Linked Data servers a chance to mature.

Monday, November 2, 2009

Why isn't the Web Object-Oriented?

A big part of the Web is web services, but often these services are not modelled using an object oriented paradigm, even though it is well suited for complex behaviours. Web services are often modelled using a simple request/response paradigm or a service oriented paradigm using a RESTful framework, but many of these resource oriented frameworks can be adapted to support some object oriented concepts.

Many people think of classes and methods when they think of Object-Oriented Programming (OOP). However, I like to think of OOP as message passing with class specialization. This is particularly helpful when designing Web services, which also use a message passing model. Even RESTful Web services use forms of message passing between nodes.

Consider the simple URL below. When followed a GET request is sent to a Google server. This can be thought of as sending Google's search object a message with the given search term parameter (using the Google network as the authority). The search object (in this case a proxy) responds with an HTML page with the search results.

   Object Authority
_________|_________
/ \
http://www.google.com/search?q=Why+isn%27t+the+Web+Object-Oriented%3F
\__________________________/ \_____________________________________/
| |
Object Identity message


All HTTP requests can be thought of as messages being sent to remote objects. The request method, query parameters, headers, and body make up the message, and the request URI identifies the message's target object. The HTTP response is the message's return value.

However, OOP is more than simply message passing. A big part of OOP is the association of behaviour with data. The relationship between behaviour and data drives at the difference between service oriented and object oriented paradigms. A service oriented model is like an object oriented model, but all objects are stateless singletons with their own unique behaviour. Because of this, pure service oriented systems can be more efficient (less data access), but is more expensive to maintain, as each service must consider all possible variations at once. In contrast, OOP supports behaviour specialization and can more closely reflect the structure of systems 'in the real world'.

While many services are identified by a single request URI (scheme+authority+path), most RESTful frameworks allow data to also be associated with the URI. JAX-RS, for example, allows path parameters that are often populated with a unique entity ID. By incorporating the entity ID in the URI, data is associated with the behaviour in the same way as in an OOP paradigm. However, most RESTful frameworks fail to provide any support for object or resource behaviour specialization -- a feature that is incredibly powerful in class-based OOP.

The Web is actually fairly close to seamlessly supporting an object-oriented paradigm. Processing efficiency seems to be the only barrier. However, with the growing costs of maintaining complex Web systems, I'm not sure how long this argument can hold up. When do you think we'll have an object oriented Web framework and what would it look it?

Reblog this post [with Zemanta]

Tuesday, June 30, 2009

HTTP Servlet Caching Filter

The nice thing about the HTTP protocol is how easy it is to implement an trivial HTTP server. At some point, however, just responding to HTTP requests is not enough and response caching must be introduced.

If you search for "servlet response caching", you will find advice to ensure you use the correct response headers to facilitate HTTP caching and suggestions to use a servlet filter to cache the response. If you are like me, you would continue to search for a way to use both - a servlet filter that caches based on the correct response headers.

With the HTTP protocol so well supported and J2EE so popular, finding a caching servlet filter that adheres to the HTTP spec should be easy, but it isn't. In fact, it is really hard to find any Java implementations that caches based on the HTTP response headers (servlet filter or otherwise). This seemed like an interesting problem that is fairly common, so I spent some time to see how far I could get with a servlet filter that understands HTTP caching.

Despite my general knowledge of the HTTP spec, implementing it is a lot more difficult. For example, the If-Modified-Since and If-None-Match headers are fairly easy to understand, but when you try and implement this logic, things get a little more complicated. In working through this, I realized that there are nearly 20 possible scenarios that need to be handled by the server. The request might not have an If-Modified-Since header, it might have been modified, and it might not have been modified are three states the server must handle for that header. The If-None-Match may not be present or it might or might not match and it might have a '*' tag, which may not may not have an existing entity. You can't just process these one at a time either, but once you write down the edge cases it can all be handled fairly compactly within a precondition check.

Another area that surprised me was the request Cache-Control directives. There are five boolean directives and three with a specified value. All of these directives are fairly easy to understand and are used to determine if the cache can be used and if it needs to be validated. However, that is a lot of variables to manage and combined with the possible server directives, its gets really harry tracking their state. There were many occasions when adding support for a new header/directive that I inadvertently broke an earlier unit test (couldn't have done it without them).

The HTTP spec is fairly clear is some areas, but less so in others. One area that has had various interpretations is entity tags. It is fairly clear how ETags should be used with static GET requests, although I had to digest their implications on caches before I could understand how to use them with content negotiation. However, their recommended use with PUT and DELETE is still a bit of a mystery. When an entity has no fixed serialized format (such as a data record), it has many entity tags (one for each serialized variation and version). So, which entity tag should be used after a PUT or a DELETE that effects all variations?

This get even more complicated when some URLs are used to represent a property of a data record. If the property is a foreign key, the response has no serializable format, its a 303 See Also response. What does a PUT look like when you want to reference another resource? Furthermore, a DELETE of a property, just deletes the property, but the data record still exists and there is still a version associated with it, shouldn't the client be given the new version?

In the end I have a new appreciation for why there are so many interpretations of the HTTP spec and I have a fairly general purpose HTTP caching servlet filter on top of it.
Reblog this post [with Zemanta]

Wednesday, June 17, 2009

Resource Oriented Framework

What happens when you put an Object oriented Rules Engine in a Resource Oriented Framework? After three years of research, I think I have found the answer and have released it as AliBaba.

AliBaba is separated into three primary modules. The Object Repository provides the Object Oriented Rules Engine. It is based on the Elmo codebase that has been in active development for the past four years. The Metadata Server is a Resource Oriented Framework built around the Object Repository. Finally, the Federation SAIL gives AliBaba more scalability.

In AliBaba, every resource is identified by a URL and can be manipulated through common REST operations (GET, PUT, DELETE). Each resource also has one or more types that enable it to take on Object Oriented features that can be defined in Java or OWL. Each object's properties and methods can be exposed with annotations as HTTP methods or operations. Operations are used with GET, PUT and DELETE HTTP methods by suffixing the URL with a '?' and the operation name. These operations are commonly used for object properties, while object methods are commonly exposed as other HTTP methods (POST) or as GET operations. This HTTP transparency allows the Metadata Server's API to hide within the HTTP protocol and not dictate the protocol used - allowing it to implement many existing RESTful protocols.

AliBaba provides a unique combination of Object Oriented Programming and a Rules Engine, available in a Resource oriented Framework. I believe it combines some of the most promising design paradigms commonly used in Web applications. Its potential to minimize software maintenance costs and maximize productivity by combining these paradigms is very exciting.

Reblog this post [with Zemanta]