Tell me more ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have this method that is executed on page action:

....  
public PageReference validatePage(){
   Id someId;
   MyObject__c myObj;
   try{
       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?

share|improve this question

1 Answer

up vote 5 down vote accepted

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!

share|improve this answer
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 at 14:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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