7/25/2011

Protect KML / KMZ Files from Unauthorized Access Using Cryptography

In this blog post, I want to detail out the way we can protect KML files from unauthorized access in an Enterprise environment. In this approach, we can use the simple cryptography principles to make sure that the access to the KML files is granted only to authorized users, who are already authenticated in an enterprise context. But the problem here is that the KML files are accessed by Google server directly and there is no way for the Google server to send any authentication/authorization information on its own.

To understand this, we need to understand the basic flow of the request when a user accesses the KML from the browser. In the following diagram, I tried to capture this basic flow.
In an enterprise environment, before any of this request, we assume the user is already logged into the server and access the application.  

Google Accessing KML resource without any protection

  1. User accesses the maps application, which will have overlays mentioned as KML Url(which is located in the web server).
  2. The maps applications return the maps related HTML, JavaScript with the KML Url in the JavaScript.
  3. The JavaScript sends a request to the Google Maps server to access and parse the KML file with the KML Url in the request.
  4. Google Maps server accesses the KML Url directly from the server (not via the browser)
  5. The KML request reaches our own server and the server returns the KML content. This is the reason why the KML should be accessible from the Internet directly.
  6. Google Maps server parses the request and sends the parsed response to the JavaScript back and the Maps JavaScript draws the overlays necessary.
With these basic steps in view, let’s see how we can authenticate and authorize the user when the KML request reaches our server from the Google Maps server (Step 4 and 5). The main aim of this method is to establish a token and pass it as part of the KML Url. This token will be used when a KML request reaches the web server to verify the originator of the message, user who really requested the KML file, so that the server can do the verification, validation of the token and also the authorization, access-control for the KML resource (some group or role check). For this description, I am going to use the symmetric key encryption but it’s quite feasible to use the PKI based digital signatures too.

Google accessing the KML resource with cryptography based protection

  1. User accesses the maps application, which will have overlays mentioned as KML Url.
  2. The web/app server upon request for the map application, forms the crypto token to be included as part of the KML Url. This token is just a representation of the user identity (loginId of the user), valid from and valid to timestamps.  The reason for including these two timestamps is to establish a unique token for every request and also to introduce the expiry of the token, so that the same request cannot be replayed after the token is expired. The web server has to establish some secret key for the symmetric encryption.
    An example of the token:
    tokenBuffer = concat(userId, “:”, validFrom, “:”, validTo)  //”:” is used as a delimiter
    token = base64encoding(AESCipher(tokenBuffer, symmetricKey))  //using AES for this example


    This token will be appended as a query string to the KML url. Instead directly accessing the KML file, here we use a component (a servlet, PHP script or similar) for KML request processing. If the KML Url is http://:/test.kml then this Url will become http://:/webapp/KMLController?token=&kmlFile=test.kml
  3. The maps application responds to the browser with the maps HTML+JavaScirpt along with the KML Url containing the token.
  4. Google Maps “google.maps.KmlLayer” JavaScript object requests the Google maps server to fetch and process the KML as indicated by the Url. Please note that the Url contains the token we just formed as part of step 2.
  5. Upon request, the Google maps server sends a request to our web server’s KML Controller component to process a request for the KML file. The KML file name is passed as part of the query string.
  6. When KML controller receives the request for KML file content, it performs the following steps:
    1. It first extracts the token, which is available as part of the query string.
    2. This token is decrypted using the same symmetric key to get the clear text of the token.
    3. Extract the token values using the delimiter. In this step we get the user id, valid from and valid to values.
    4. Do the access control checks and validate the timestamps.
    5. If everything is fine send the KML content in the response with proper mimetype, i.e. application/vnd.google-earth.kml+xml for KML files and application/vnd.google-earth.kmz for KMZ files. (KML file name is available as part of the query string).
    6. If any of the steps failed, send proper response code (401, 403, 400 etc).
  7. Send the response back to the Google server’s HTTP request.
  8. Google server parses the KML if the KML is sent properly. Otherwise, it ignores the errors.
This way, we can protect the KML resource access from an unauthorized access.

References

  1. Book "Beginning Cryptography with Java" by David Hook
  2. Icons used in the above drawings are taken from the following site:
  3. Browser icon: http://www.iconfinder.com/icondetails/17856/128/browser_icon Maps icon: http://lab.iirojappinen.com/idroid/

6 comments:

tom said...

Nice article.
We have noticed that Google retrieves the data again after one hour. So you open a map with a KML-layer, Google fetches the data correctly with the token, you play with the map for more than an hour and then Google wants to retrieve the data again, so executes the webservice again and the token is no longer valid, leaving the map in an incorrect state.

Alex said...

Hi there,

Thank you for the article.

I came across it while searching on how to do just what you describe.

Most of this is new to me, but I'm trying to learn and teach myself as I go... is it possible to get more information on how I could implement something like this in my kml project?

Pavan Keely said...

HI Alex,

Please contact me at keelypavan(at)yahoo(dot)com for any help you may require.

Thanks
Pavan

FutureNerd said...

I thought I'd mention my security goal in this situation even though it's different.

I want to authorize a user to access a web page that uses Google Maps with KML. I want to authorize Google to read the KML file. I specifically want to prevent the user from reading the KML directly.

With this goal in mind, passing the KML access token through the user's hands (the user's browser's javascripts' hands) is a problem.

Given that I'm paying Google for this service, and my app already passes them my Google Maps API key, it would seem reasonable to expect the service to have provision for this. You seem to be saying this is definitely not the case. Do you know (say) a Google Maps doc page that confirms this?

As an aside, it's often assumed that authentication or authorization for a low-level operation (like writing a file) should be based on knowing what user is being served, and whether that user has permission to do the low-level thing. That was never really right, always both too loose (a game can read my mail) and too tight (I can't install software for my own use because I'm not an administrator for the whole computer), but now it's even more problematic when web pages are mashed up out of components across the world. The general problem is to assign specific access to specific software objects or processes including user logins as one case.

Vinit said...

Hey Pavan Keely, Thanks for this intresting blog. I was looking for a similar thing. I read your other blog as well, which said about using geoxml and other open-layer technology.
I am actually using geoxml, but since my site is public i need to keep the KML files on the server itself, and so it is accessible to everyone.
Now is there a way to protect these files from being accessed by anyone. Since Google has no role to play when i am geoxml, what are my options?

Sathiyaseelan said...

I need to protect a Kml file after creating..is there anyway?