I have this method that is executed on page action:

public PageReference validatePage(){
   Id someId;
   MyObject__c myObj;
       someId = ApexPages.currentPage().getParameters().get('id');
       myObj = [Select Id, field__c From MyObject__c Where Id = :someId Limit 1];
   }catch(Exception e){
       return Page.somePage;
   //some conditions and if one evaluates true at some specified case, update a field on that record 
   myObj.field__c = 'Some value';
   update myObj;

It GET's the param Id, then select the record with that Id, and then some if's elses are evaluated and if all Ok a field is updated.
The page that uses this method is only accessible by logged users in Salesforce.
How can I prevent Cross-Site Request Forgery in the Checkmarx report?


Update as at Summer'13: New Feature: Require CSRF protection on GET requests

Since Summer'13 Salesforce have started what looks like a feature to start to address this. Through a checkbox on the Visualforce page metadata called 'Require CSRF protection on GET requests'. When enabled it will ensure your page cannot be used via a GET request without a token generated by Salesforce. Currently only the Delete actions on custom objects support this, but its a start! I've made a request within Salesforce to understand the rollout of this feature, hopefully we will see it for all Custom Buttons soon!

Select Require CSRF protection on GET requests to enable Cross Site Request Forgery (CSRF) protection for GET requests for the page. When checked, it protects against CSRF attacks by modifying the page to require a CSRF confirmation token, a random string of characters in the URL parameters. With every GET request, Visualforce checks the validity of this string of characters and doesn’t load the page unless the value found matches the value expected. Check this box if the page performs any DML operation when it’s initially loaded. When checked, all links to this page need a CSRF token added to the URL query string parameters. This checkbox is available for pages set to API version 28.0 and later.

In Summer ’13, the only way to add a valid CSRF token to a URL is to override an object’s standard Delete link with a Visualforce page. The Delete link will automatically include the required token. Don’t check this box for any page that doesn’t override an object’s standard Delete link.

Original Answer:

As per the definition of this security issue here. The concern is that another page outside of Salesforce or even within it, can make a HTTP GET request to the URL of your page and result in an update to the database without the end user knowing or accepting it. If your code simply performed database SOQL operations in Apex there would be no issue here. You may be able to discuss this with the security team as 'false positive' use case however, if you can convince them its none critical update in respect to your application.

From your statement 'this method that is executed on page action' it sounds like the method is called during the page load (via 'action' attribute on apex:page) and hence would be a result of a HTTP GET then this is likely what it is calling out. As it's observed the link between the method and the reference in the action attribute. It may also be referring to the use of ApexPages.currentPage().getParameters() as well.

Some thoughts to consider...

  1. Change your page to invoke the action from a apex:commandbutton (as apposed to page load) and if possible utilise the StandardController to obtain the ID. This way your user is making a HTTP POST (via apex:commandButton) to your logic and your also leveraging the platform to determine the page context (the Id). The downside of this, is that this approach impacts your user experience with an additional button.
  2. If your invoking from a Custom Button consider using JavaScript button and calling a Apex WebService. This has the downside of using JavaScript and exposing a WebService call, but does avoid the issue.
  3. Consider embedding your page in the layout of your object, it maybe a simple page to invoke your existing page. But this way Salesforce's own CSRF protection kicks in. The downside to this is the lack of customisation of your button amongst the others and the fact that it is positioned visually in a different place then usual.
  4. Implement your own CSRF protection, not recommended, and I've yet to see a good implementation of this that is stable enough (against platform changes) to trust in production code.

In short there is no ideal way to keep what is a good platform feature for binding Custom Button's to Apex code that performs updates. Here are some links to other discussions and ideas on this issue. There is also a Salesforce Idea to enhance Custom Buttons to support this which you can upvote.

Hope this helps!

  • 1
    Thanks Andrew for the feedback. So then I will have to put a commandbutton and request the user to press it. It's the only and fastest way to do it. But like you said it will have an impact on the user experience with this additional button. Thanks.
    – Ivo Rocha
    Jan 23 '13 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.