+ Start a Discussion
Prem rajPrem raj 

URL Redirection Attack - Security review issue while using PageReference()

I'm triying to query FullPhotoUrl from an User object and creating a PageReference for that URL. But this runs me into the security scan issue URL Redirection Attack.

Can someone please help me to fix this?

String userId = String.escapeSingleQuotes(Apexpages.currentpage().getparameters().get('ID'));
list<User> lstUsers = [select FullPhotoUrl from User where Id=:userId limit 1];
String strPhotoURL = lstUsers[0].FullPhotoUrl;

strPhoto = EncodingUtil.base64encode(new PageReference(strPhotoURL).getContent());

Thank you in advance!
Vasani ParthVasani Parth
Prem,

You should make sure that the redirect url meets one of the following conditions:
 
1) The URL starts with "/" (%2F escaped).
2) The URL starts with System.URL.getCurrentRequestURL().
3) The URL starts with System.URL.getSalesforceBaseURL().
4) The URL is otherwise on a whitelist of allowed URLs (e.g. if you allow a redirect to Google, this might be acceptable).
 
Try taking a look at the String or Pattern classes for examples of how you might check this. More information here (https://developer.salesforce.com/page/Secure_Coding_Arbitrary_Redirect)

Please mark this as the best answer if this helps
Prem rajPrem raj
Hello Parth,

Thanks for the reply. I saw a similar post in https://developer.salesforce.com/forums/?id=906F000000092MSIAY
But can you please let me know how exactly can I fix it in my code.

When I debug, I get the value of strPhotoURL as https://c.na15.content.force.com/profilephoto/729i0000000IcKk/F . In this case how can I convert my URL to meet any of the above conditions?
VineetKumarVineetKumar
Well, my first suggestion would be to avoid such directions at all, if there is no other approach to your solution, then you need to create the similar URL, rather than directly querying and using it.
i.e., use of System.URL.getCurrentRequestURL() or System.URL.getSalesforceBaseURL()
I wonder if just giving /profilephoto/729i0000000IcKk/F might also work rather than giving the whole URL.
Prem rajPrem raj
Hello Vineet,

Thanks for your response.
I tried just giving /profilephoto/729i0000000IcKk/F. But in apex end I'm afraid it works.
I also tried with System.URL.getCurrentRequestURL() and System.URL.getSalesforceBaseURL() . I get https://na15.salesforce.com as opposed to https://c.na15.content.force.com. Please can you help me generate the exact base URL.
VineetKumarVineetKumar
/profilephoto/729i0000000IcKk/F : relative path works in Apex, since this your controller it should work.
Just to get some background, can you let me know what you are trying to accomplish here, do you just want to display the profile pic, or are you going to save it somewhere?
Prem rajPrem raj
Right Vineet,
The relative path works in Apex. But it gives the base URL of the org. And if you notice, the FullPhotoURL in the User field stores the data in a different domain(https://c.na15.content.force.com). So that is the reason that I'm not able to use relative URL, which is (https://na15.salesforce.com) . 

Basically I'm trying to download a user-profile, via VF page. Something like a VCard, which also has the profile image which is stored in FullPhotoURL field of the User.
VineetKumarVineetKumar
So, why do you want to save the photo, why not just save the URL and reference in your VCard page.
Something like below :
<apex:image id="profileImage" url="{!User.smallphotourl}" />
<apex:image id="profileImage" url="{!User.FullPhotoUrl}" />
Just a thought.
Prem rajPrem raj
Hello Vineet, 
That was not something which I was trying for. I was trying to create a vcard in VF with the attributes mentioned in this link: https://en.wikipedia.org/wiki/VCard

Found a solution which is working but with one drawback that we explicitly need to add the remote site for the URL link https://c.na15.content.force.com
 
lstUser =    [select FullPhotoUrl from User where Id=:strUserId limit 1];
photoURL = lstUser[0].FullPhotoUrl;

Http h = new Http();
HttpRequest webReq = new HttpRequest();
webReq.setMethod('GET');
webReq.setHeader('Authorization','Bearer '+UserInfo.getSessionId());
webReq.setEndpoint(photoURL);
HttpResponse res = h.send(webReq);
Blob strImage = res.getBodyAsBlob();

// get the base64 of user profile picture
strPhoto = EncodingUtil.base64encode(strImage);

Thank you all for you help!