Best Practice: Sites and record identifiers

by Ron Hess on April 13, 2009 at 04:19 PM

Now that Force.com Sites is out in the developer community as a preview, we are starting to see several interesting and powerful use cases that involve generating forms that will input data into the Force.com database.  As these use cases come up, we are often asked is it acceptable from a security perspective to allow the Sites Public User to input data directly into the database ? 

The answer is Yes, however as a developer it's important to understand there is a safe way, and there is a casual way that could cause problems.

To explain the alternatives I'll construct a simple scenario, I'll call this the survey problem.  Simply stated you would like to offer a Survey that your contacts can fill out, once and only once and no other public users should be allowed to fill in this survey. 

You can easily and quickly build such a survey using Visualforce, and using Force.com Sites you can make this available to the contacts in your system.  In order to do this you must send them the URL of the survey that they can then visit and fill in.   If you send everyone the same URL, you'll never know which data came from which account / customer, so you construct a URL that contains specific information that allows them to visit this survey and complete the data, storing the resulting info in a record, let's say a custom object called Survey Results.

So far so good, however if you have sent the URL with a valid Force.com custom object Record Identifier ( casual way ) then you will open up your database to potential trouble.  Since the identifier will be used by the Visualforce page, first, the record identifier could be used twice, and the user could guess the identifiers that will allow them to access other records in your system using the Visualforce page that you provided.

The secure solution is to generate a KEY that is specific to something in the system, in the case described this is unique to one contact and one survey.   I have built a simple Survey app that demonstrates this, which I intend to publish in a few weeks.  For today, I'd like to share the method that I used to generate a unique KEY that is not easily guessed.   A user who approaches your Visualforce page with a valid KEY can then be given access to input or edit data, and a user who has hacked a KEY will not.

The KEY is generated by the system using a trigger when you construct an invitation to take the survey, this is a custom object also.  The KEY is both stored in the system and also sent out to the contact in the URL that you provide.  When your contact returns using the URL to your Site, the Visualforce page can match this KEY to one in your system and thus verify that it's valid (because it matches one that you have stored), therefore you can safely allow them to input / update data.

How to build a KEY ?   It's really a simple process of grabing a time-stamp, adding a bit of unique data and then running that string through MD5 to create a digest.  The key is finally url encoded to allow it to be sent as a link in an outbound email.  Here is the code for my custom object trigger, this results in the KEY stored in the  Invite_Code__c field on the Invitation__c custom object.


trigger invite_code on Invitation__c (before insert) {
    for (Invitation__c i : Trigger.new) {
        DateTime now = System.now();        
        String formattednow = now.formatGmt('yyyy-MM-dd')+'T'+ now.formatGmt('HH:mm:ss')+'.'+now.formatGMT('SSS')+'Z';        
        String canonical = i.id + i.Name + formattednow;                       
        Blob bsig = Crypto.generateDigest('MD5', Blob.valueOf(canonical));        
        String token =  EncodingUtil.base64Encode(bsig);                
        if(token.length() > 255) { token =  token.substring(0,254); }       
        i.Invite_Code__c = Encodingutil.urlEncode(token, 'UTF-8').replaceAll('%','_');
    }
}


The tokens or KEY that are generated look like this : N2oruzX_2FNWKEytb1yy6oSA_3D_3D
In order to defeat this method, you are faced with an impossible problem, even if you know how the key is constructed, it's not possible to construct a valid key since an attacker cannot insert the key into your system ahead of time, and if they guess the time stamp correctly they are forced to guess the record ID and the name of the valid record as well.

You can easily modify the source code at the line that constructs the canonical variable to append additional information that is unique to your application and therefore have a unique algorithm that is not knowable by anyone reading this article.

Stay tuned to this blog, I'll be posting additional tips and tricks as I build a simple app that demonstrates the power of Force.com Sites using Visualforce to gather information from your customer.

Debunking the Myth of Control

by Peter Coffee on January 29, 2009 at 02:43 PM

This just in:


Ex-Fannie Mae worker charged with planting computer virus

By Freeman Klopott
Examiner Staff Writer 1/29/09

A fired Fannie Mae contract employee allegedly placed a virus in the mortgage giant’s software that could have shut the company down for at least a week and caused millions of dollars in damage, prosecutors say.

Rajendrasinh Makwana, an Indian citizen, was indicted Tuesday on computer intrusion charges. The former Gaithersburg resident is out on $100,000 bail, court documents said.

Makwana was fired from his contract position at Fannie Mae on Oct. 24 for changing computer settings without permission from his supervisor…


Note: he was fired for changing settings without permission. The system, it appears, had no built-in mechanisms for defining permissions and limiting actions accordingly. But if they catch someone doing it, they'll fire him. Feel safe?

Or would everyone sleep better if the data were in the professional custody of a cloud service provider, with rigorous definition of roles and abilities? And with robust, in-depth data protection technologies and practices?

Bottom line: compared to most people's Mission:Impossible imaginings of Black Hat Hacking, the real-world security of most data has less to do with where it's stored and much more dependence on the mechanisms in place for limiting privileges and blocking destructive behaviors.

Disciples of the on-premise myth of "control of your own IT" are urged to pause and reflect.

Community Update: Intros, Tour de Force, Visualforce

by Jon Mountjoy on May 30, 2008 at 05:03 AM

I'm a new member of the force.com team, and I'll be working here as the community manager and editor-in-chief of developer.force.com. As a result, I hope to be touching base with a lot of you developers, ISVs and admins out there, as well our internal salesforce.com employees. I'll also be working at developing our blog and content strategies, infrastructure and more. There's a lot to do, and I'm keen to help our thriving community grow even bigger. Feel free to ping me at any time about the community, with any suggestions, complaints or comments (jmountjoy at salesforce dot com) or join me on Twitter or other data streams.

I will be producing a community update like this every week or two, highlighting forthcoming events (check out the awesome Tour de Force website with new events in the USA, Ireland and Japan), community members (see Anshu), webinars (Move Beyond S-Controls), interesting board threads, things that catch my eye (like the Dreamforce Session Idea site), external sites (Simon, Joe, Steve and many more) and so on, so please stay tuned.

Regards,
Jon

Resources

We have a couple of new resources for you:

  • A short Visualforce Components Demonstration by Adam Gross shows off some of the capabilities found in Visualforce Components. This is going to big: reusable, modular, user interface components. I need to create a directory listing components that we can start finding them all. Done!
  • A new Visualforce resource page recently went live, pointing to reference material, tutorials and webinars to get you up to speed on the technology.

Blogs

In the blogs, I'd like to welcome new blogger Anshu Sharma. Anshu blogged about being In India, with Force(.com)!, and some of the questions he encountered during a talk he gave on PaaS and Force.com.

Also in the blogs, Ron Hess tells us about Coding The Cloud at Google's I/O Event, where he's presenting on integrating force.com apps with Google GData interfaces. I'm also keen to see how our developers use the new Google Earth API. We've seen plenty of Google Maps mashups - now how can we use Google Earth too?

Finally, Peter Coffee has some interesting thoughts on what it means to be Disconnected. He makes the point that "..it's not the problem of any single technology provider (or even any particular subset of the tech provider ecosystem) to solve the problem of staying up and running even if your public network link is intermittent."

Upcoming Events

From our event calendar, we have the following events that may interest you:

Education Services

Education services have two upcoming courses:


Technorati Tags: , ,

Sforce Single Sign On

by PK on July 25, 2005 at 10:11 AM

There's been some recent discussion on SXIP's decision to build hardware to support Salesforce.com's delegated authentication protocol.  Delegated authentication is a process where Salesforce makes a secure web services call to an endpoint that a customer defines.  Salesforce can delegate authentication to the customer, which can allow for building web single sign on, integration with two-factor, integration with an LDAP directory, and many other possibilities.

What hasn't been discussed is why Salesforce is using a delegated authentication scheme, rather than just accepting SAML tokens.  So why'd we do it?

Supporting SAML on our website would have been easy.  But we have a huge amount of our traffic that doesn't come to our website, but to our Sforce web service APIs. 

We have an outlook plugin, a plugin for word and excel (office edition), an offline edition, and a wireless edition.  We also have many partners who have build products on top of our APIs.  An example we like to use is access Salesforce on a Blackberry.  We have a number of partners who have successful products to allow customers to access Salesforce on a Blackberry.

How do the clients, which all use web services to authenticate (using login and password today calling our login call), know where to get the SAML token from, in a standard way?  There is no standard way to do this today, and even standards like WS-Trust don't seem to solve this problem.  For example, you build a client using our web services apis.  You deploy to all our customers.  Customer A has one SAML provider.  Customer B has another SAML provider.  How does your code know where to go to get the token when deployed at customer A and at customer B, without configuring all of the clients with the location of the SAML provider? 

We suggest customers can use web single sign on, and a shared password for the clients.  So when I login through the web, a SAML token can be passed through.   When I use the web services-based clients, I use my Active Directory password.  This is a simple solution

For our customers, a hardware based solution is a no-brainer.  It's simpler to deploy, and less to maintain on their end.

We'd love to hear how others are thinking about solving the web + web services authentication problem, when there can be an unlimited number of clients that need to authenticate against your service.

Sxip identity appliance

by Simon Fell on July 22, 2005 at 07:44 AM

Interesting comments from Craig Burton, Kim Cameron & Marc Canter on the Sxip identity appliance (which supports delegated authentication and Single Sign On for salesforce.com), and the follow up from Sxip. I think it totally makes sense to offer this as an appliance, that's one less server for your overworked and under resourced IT department to have to manage.

Password Never Expires

by PK on April 14, 2005 at 12:13 PM

Some users get tripped up because their organization has a security policy to cause users to reset their passwords every X days.   After 60 days of the integration working, it fails, because the user got locked out of their account!

If you have an integration user, you have a few options

Your first option is to change your password programmatically when it expires.  LoginResult will come back with the PasswordExpired flag = true, and returns a sessionId that is only good to use the setPassword call.

Another option is a flag on the profile to allow passwords to never expire, called Password Never Expires.

If you plan to enable password never expires we recommend you also lock down access for this integration user by IP ranges.  Use the IP range restriction feature on profiles.

Note that if your organization does not have a security policy to reset passwords every X days, this will not be a problem for you.