4

In my problem there is an existing system that works as a alerting or clipping service that runs user defined searches and generates results lists. These are setup by authenticated users and this internal system uses a GUID as the identifier to fetch the results, which are stored in a database.

There is a requirement to expose these results via RSS. However, other than embedding username:password@ in the URL, I am not aware of any technique that works across RSS readers. The naive idea is to make the URLs something like /alert/{guid}/rss which has a few problems. Since GUIDs are intended for uniqueness and not randomness, I am worried about guessing attacks since every guess attempt would proxy the request from the web facing system to the internal system, and access the database. I am looking for a way to both add some uniqueness to the URL and prevent unneeded database access, while preserving the GUID based key.

My ideas is to expand the /feed/{guid}/rss URL to something like /feed/v1/{hash}/{guid}/rss which contains an additional hash segment. This segment would be generated by combining the existing guid and an application provided secret via concatenation or XORing or something? This would be the URL that would be provided to RSS readers from inside the application. Then, when a URL comes into the system, the hash segment can be recomputed in memory, compared, and rejected without a trip to the internal service and database. The leading /feed/ segment of the URL is unique in the system to enable future URL routing/load balancing to feed cache. The /v1/ segment is in place if the secret has to change for future feed URLs.

Since I don't want to be another proof for "Schneier's Law", what are the problems with this pattern? I think it helps with the denial-of-service for brute force attacks (but not if at least one valid URL is known). I also think it creates "random" URLs for the sensitivity of the data. I am open to criticism or other ideas, but I am stuck with the GUID based keys.

0

2 Answers 2

2

The basic solution is to encode a single-purpose semi-public password into the URL. Typically the solution looks something like this:

http://<base>/<content_identifier>/<auth_identifier>/<random_password>

So the <base> and <content_identifier> are whatever you want; they make the URL point to something for your site. The <auth_identifier> points to a corresponding authentication token in your database that indicates who authorized this URL, etc. The <random_password> bit is there to guarantee that the URL can't be guessed. It's just plain random. The authentication token in the DB stores the correct random password. You should be able to revoke or expire old URLs by updating (or deleting) the authentication token in your database. You should also be able to issue an additional unique URL after a previous one has been revoked (or perhaps at the same time as another). It's difficult to do this if your secret is a hash, since there's only one correct answer and therefore one correct URL.

If you're worried about secrets, you can encrypt the data before publishing it out in a URL and decrypt it before processing it. Typically that's overkill, but it all depends on what data you're exposing.

Note that your idea of encoding enough information into the URL to make it verifiable without the database means that the contents of the database cannot affect the validity of the URL. Specifically, you can't revoke it. Often that restriction proves problematic down the road.

2
  • I haven't messed with this much but I'm curious; Wouldn't something more along the lines of this be safer? http://<base>/getcontent.ext?contentID=<content_identifier>&authID=<auth_identifier>&token=<random_password> Having the values stored like directories could still allow brueforce if the HTTP host gave up any information for valid vs invalid directories. By making it call via a single page you could return the same error message always upon a any failure to authenticate regardless of which value was the bad one.
    – Nathan V
    Nov 27, 2012 at 6:50
  • @NathanV Modern web frameworks don't require that the URL map to a folder structure. Of course, you can encode everything in a query string or in the URL base. It doesn't matter for security. If the framework you're using maps application URLs to file locations, consider upgrading to something different. Pretty much anything will be better.
    – tylerl
    Nov 27, 2012 at 7:20
0

My first idea is to simply generate a random 16 byte value using a secure PRNG and use that instead of a system generated GUID. This should be a drop in replacement for a GUID(no protocol change :) and it should be secure as long as the url doesn't leak.

Your should should be secure too, if you use a MAC such as HMAC-SHA-2 (essentially a keyed hash). Don't use an ad-hoc combination scheme, use HMAC which is standard and secure.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .