views:

90

answers:

4

I am using the Key value of entities in my datastore as the unique identifier in the URL for pulling up a record:

http://mysite.appspot.com/myaction/1x7s3fgdlbnRlcklkcicLAbcXc2VyQWNjb3VudCIFYW9uZ

This is not a very attractive solution, nor is it SEO friendly, but it's the easiest way I've found to identify an entity uniquely in App Engine/Java.

My main concern, though, is whether there is any security concern related to displaying the unique Key value for the entity?

A: 

This is not a security concern in my opinion. Lots of sites use id as identifier within the site. A key is just a key to a row in a database table, you do want to refrain from showing much detail about your database in terms of table and user accounts etc.

In this regard, you want to prohibit your site from dumping out database errors when they occur, catch them and handle nicely.

Chris
-1 I think you fail to understand the details of a GAE db.Key. They're a *lot* more than just a row ID.
tc.
Explanation please?
Chris
+3  A: 

The security concern is that a potential hacker knows something, however small, about your database.

If parts of your database are ever compromised the entity id could prove useful for the hacker.

Like you I don't really like displaying database IDs but IF you secure your application properly it isn't worth worrying about as knowing the entity id isn't going to be useful.

Joe R
Agree. Also would consider what the DB holds. If it holds the full content of a credit card number, I would be more careful than if it held a post to a forum like stack overflow.
bwawok
@bwawok: You can't just secure the "critical" parts of the database, since there's a trivial privilege escalation attack: people reuse passwords. For credit card numbers, I would just use a payment provider (Google Checkout, PayPal, etc).
tc.
+5  A: 

The encoded key contains your app ID, namespace (if any), entity kind name, and key name or ID. There's two possible issues here: the disclosure of that information (probably not problematic), and the fact that you're accepting an encoded key. If you don't check that the entity specified by the key being passed in is of the correct kind, and that the user should have access to it, then they could pass in their own key to cause you to disclose information you shouldn't.

Almost universally, however, you already know the kind name of the entity you're fetching, so a much better idea is to use just the key name or ID of the key, and construct the full key on demand. This also makes for much cleaner URLs.

Nick Johnson
+1  A: 

Are you sure that's an actual key? It doesn't look like one (the un-base64'd data generally includes your app identifier, for one).

The documentation covers it, though:

Note: A string-encoded key can be converted back to the raw key data. This makes it easy to guess other keys when one is known. While string-encoded key values are safe to include in URLs, an application should only do so if key guessability is not an issue.

It's a lot cleaner to do something like this:

foo = FooModel.get_by_id(int(foo_id))

That doesn't stop attackers from guessing IDs, but at least it doesn't fool you into thinking that IDs are "opaque" (and you can trivially change the ID to test access control, instead of needing to mess around with base64-protobuf-encoded data).

tc.