views:

248

answers:

3

I have a Silverlight application that communications with an ASP.NET backend through WCF. I have a set of DataContract objects that I defined that (for the most part) match my LINQ to SQL generated types that my ASP.NET backend works with. My WCF code generates instances of my DataContract objects from LINQ to SQL generator types when I need to transfer data to my Silverlight client.

My question is the following: What are the security implications of exposing an index (which is used as the primary key in the database) through my DataContract objects?

An example table (Position) in my database has the following columns:

  • PositionIndex : int (primary key)
  • PositionName : string
  • PositionType : int

And the corresponding object is (more or less) this:

public class Position
{
    public int PositionIndex { get; set; }
    public string PositionName { get; set; }
    public int PositionTYpe { get; set; }
}

I'm concerned because I know how easy it is to reverse engineer Silverlight DLLs through Reflection - any potential bad guy will know I'm giving a database index to the client, and since they can reverse engineer Silverlight DLLs, they can easily get the URL of my WCF services and try to break them. Now, I've been good and taken the advice of the many who came before me and I've made many, many checks on the ASP.NET side to verify that my WCF services are getting legal input, but I'm still concerned that I'm doing something bad by giving potential bad guys some, not much, but some, insight into how the backend of my system is designed, and I've been around long enough to know that's more than enough for a determined person to start with.

What do you guys think? If I'm doing something bad by using the index in my DataContracts, can you suggest an alternative? I'm finding it difficult to come up with a design that doesn't provide that index, as I have a need for the Silverlight client to update rows already in my database, and having the index is the best way I can think to help the ASP.NET side determine which row in the database it needs to update.

+2  A: 

One thing that would help would be to have some kind of authorization in place so that you keep track of what clients "own" what keys, so that they can't alter records they're not supposed to alter.

Chad Okere
+2  A: 

http://stackoverflow.com/questions/454771/is-it-safe-to-expose-database-indices-to-silverlight-clients

It is standard practice to use primary keys in URLs and such. What you have to be careful about is to make sure the client is permitted to view the resource before sending it back.

:)

nlaq
+1  A: 

It doesn't matter whether you use a database id or a "natural key" - the security issue is the same: you need a way to uniquely identify a record, and that knowledge can potentially be abused.

The main advantage of a natural key would be if you need to store the record mid-to-long term disconnected from the system, or transfer the record between parallel systems (where a primary key ceases to be useful) - but that doesn't seem to be the issue here.

If security is a major concern, you could issue transient keys (perhaps guids) for objects that only exist for a client's session - re-map them back at the server. However, this would be quiet painful in practice.

Of course, you could use Guids as the primary key (uniqueidentifier): another advantage of guid-based keys is that (if generated randomly) they don't let you use the "key+1, key+2" approach to data querying.

Either way, you should validate that the client is allowed to [create/read/update/delete as appropriate] the record they are attempting to manipulate.

Marc Gravell
Hmm - using Guids as the primary key is interesting, I'll look into that. I do validate that the client is allowed to do anything server-side, so I don't think I need to do anything as extreme as issuing transient keys...but that's an interesting approach.
unforgiven3