+ Start a Discussion
AndrewTaylorAndrewTaylor 

Stuck - Learn Standard Open Redirect Preventions

I'm currently stuck on the "Learn Standard Open Redirect Preventions" challenge of the "App Logic Vulnerability Prevention" module.

The challenge is to submit a valid open redirect attack starting from the Standard Redirect Protections Challenge tab.

However, the links on this page are all to standard record pages, where the hack (e.g changing retURL to returl) won't work (it only works on VF pages).

Even if I attempt this and check the challenge, the error I get states: "It doesn't appear that you've successfully redirected to an external website using the Visualforce page. Please try again." - so it implies that it expects me executing this from a custom VF page.

Can anyone give me some advice on where I'm missing something on the challenge?
SandhyaSandhya (Salesforce Developers) 
Hi,


Consider below points.

1.Please check if you have connected to same DE org where you have done your work in the trailhead.To do this click on" launch your hands on org" and select the DE org or trailhead playground where you have your work and then check challenge.

 OR

Go to Trailhead Profile -- settings -- make the DE org which you have worked as default then check the challenge.


The Trailhead is released with new updates. Please refer below link how to take challenges in trailhead.

https://force.desk.com/customer/portal/articles/2643793-trailhead-profile-signup-login-faq?b_id=13478

Hope this helps you!

If this helps you, please mark it as solved.

Thanks and Regards
Sandhya
AndrewTaylorAndrewTaylor
Hi Sandhya;

Thanks for replying, but your response doesn't seem to address the actual description of my problem, specifically "However, the links on this page are all to standard record pages, where the hack (e.g changing retURL to returl) won't work (it only works on VF pages)". You're just referencing basic org setup details.
Rachel Black 9Rachel Black 9
The goal of that challenge is to execute an open redirect on the custom visualforce page, not a standard page. But to do this you'll need to bypass the platform protections that are put in place when an application leverages the standard redirect parameters. 

For a hint check out the "salesforce standard protections in custom visualforce/apex" topic. The challenge is very similar to what you do in that demo. Hopefully that helps!

 
Anika-TeppoAnika-Teppo
I also had trouble with this one at first, but I can confirm that it's possible to pass the challenge. I know I'm not supposed to post an answer, but since this is something the Trailhead itself never mentions, and that people new to security probably won't know, I would like to hint that you can trick the Apex controller's validate function by using an encoded triple slash (ie. http:/// -> encode slashes) as part of your solution. I don't actually remember where I learned this, but it's summarized in a blog post on open redirects by Egor Homakov if you want to check it out.

Hope this helps :)
Dan HewDan Hew
Can someone help me complete this challenge?

In the public pageReference seedURL() I have changed

//String saveURL = ApexPages.currentPage().getParameters().get('saveURL'); to

String saveURL = 'https://www.google.com';

what else do I need to do?
Lokesh KumarLokesh Kumar
can anyone please help me here i am not able to solve this challenge.

User-added image 
Amit SahaiAmit Sahai
Hi,

I was also stuck for sometime.

Hint: Please first recall how Redirect basics demo was done.
 You need to modify VF page and also look at "Save" function in controller for the Challenge piece. That should give you the solution. 
whitney lippincott 2whitney lippincott 2
So the way to solve this one is to be aware of what the Salesforce Standard Protections in Custom Visualforce/Apex module states. The key point to this challenge is to be aware of the vulnerabilities that salesforce has with custom visualforce pages and controllers when it comes to open redirects. That being that the Parameters of your url when it comes to the Four cases which are startURL,retURL, saveURL and cancelURL are all CASE SENSITIVE. So when creating these custom visual force pages we must all be extremely careful to account for the multiple cases of possilbe redirects. From this summary you should be able to figure out how to do an open redirect and pass this challenge.
Arun Chaubey 6Arun Chaubey 6
To Pass Open Redirect Basics Challenge -

I also faced the same issue initially, but once I read the previous challanges again and again I was able to solve this challange.
To pass this challange My advise is as belows -
  1. First complete the exercise in the given in Open Redirect Basics Demo.
  2. Notice what exactly you did in step 1 to complete the Open Redirect Basics Demo exercise.
  3. Exactly same way you have to change the url to https://www.google.com to pass this challange.
Please mark my answer as best If it resolved your issue.
Anna RudasAnna Rudas
App Logic Vulnerability Prevention challeng

Hi!
Try this..
  1. On the "Standard Redirect Protections Challenge" page open Apex Controller link.
  2. In Controller find a line 45 and change get('saveURL') to get('retURL'). Save your changes.
  3. Retunt to "Standard Redirect Protections Challenge" page, and add returl as a parameter. It should be like this
  4. https://c.[yourinstance].visual.force.com/apex/standard_redirect_protections_challenge?returl=https://www.google.com&cancelURL=%2Fa08&saveURL=%2Fa08
  5. Submit the page.
  6. Click Save button. You'll be redirect to google page.
  7. Go to Trailhead challeng and click "Check challeng".
I hope it will help.
Please, mark the answer as best If it resolved your issue.
MattGoncalvesMattGoncalves
Try to add Google URL to the end of the variable: completion
Like:

https://c.xxx.force.com/apex/open_redirect_basics_challenge?completion=https://www.google.com

Hit enter to refresh the page using this variable. 
Then click que button save. You must be redirected to Google. In the case of success, go back to Trailhead and check the challenge again. 
MattGoncalvesMattGoncalves

For the next step, same thing, but as shown in the module, you must change the parameter case:

https://c.xxx.force.com/apex/standard_redirect_protections_challenge?cancelurl=https%3A%2F%2Fwww.google.com&saveurl=https%3A%2F%2Fwww.google.com

amit kumar 430amit kumar 430
Update visualforce code as following and then go to visualforce page click on save or cancel button. Then you willbe redirected to google 
<apex:outputPanel >
                <apex:commandButton action="{!save}" value="Save">
                <apex:param name="completion" value="https://www.google.com"/> 
                </apex:commandButton>
                <apex:commandButton action="{!cancel}" value="Cancel">
                <apex:param name="completion" value="https://www.google.com"/> 
                </apex:commandButton>         
            </apex:outputPanel>

 
Lakshmi SirishaLakshmi Sirisha
@AndrewTaylor - Did you find any solution for this?
Justin BehnkeJustin Behnke
For the record you do not need to modify the VF page. Just the APEX. And only the two functions that trigger redirection. And only one line of code in both of them.
Yaroslav ProYaroslav Pro
  public PageReference save(){
        PageReference savePage;
        if (Schema.SObjectType.Personnel__c.isUpdateable()){
            try{
                update unassigned;
                String completion = ApexPages.currentPage().getParameters().get('https://www.google.com');
                completion = (completion == NULL) ? 'https://www.google.com' : completion;
                savePage = new PageReference(completion);
                savePage.setRedirect(true);
                validate(savePage);
                return savePage;
            }catch (exception e){
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'Unable to update requisitions.  Exception: ' + e.getMessage()));
                return null;
            } 
        }else{
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'You do not have permission to update requisitions'));
            return null;
        }
    }

Replace this method from controller

I passed this challenge 
Maybe it helps somebode
Ghanshyam Kumar 9Ghanshyam Kumar 9

The solution is very simple. Just replace the URL Parameter and click on save button. It will redirect you to the google page. 

cancelurl=https%3A%2F%2Fwww.google.com&saveurl=https%3A%2F%2Fwww.google.com

Now check the challenge. It should pass.

Carlos CiceroCarlos Cicero
It was easy, just make sure you are in the challange  Standard Redirect Protections Challenge and not in the same tab as before, then do the same you did for learning it.
Carlos CiceroCarlos Cicero
for Bypass Standard Open Redirect Protections in Apex, it works for me with cancelurl but didn't pass the challenge, i did with saveurl to pass it.
ren nogiren nogi
Giải đáp giấc mơ thấy tắm sông
Nằm mơ thấy tắm sông là điềm gì - Mơ thấy tắm gội đánh con gì? Giải mộng nằm mơ thấy tắm biển, tắm cho con, mơ thấy người khác tắm cùng bộ số lô đề tắm gội chuẩn đẹp. Cùng https://xsvl.me/ (https://xsvl.me/" target="_blank) tham khảo bài viết về giấc mơ tắm sông nhé!
User-added image
Tắm gội là hoạt động thường nhật của con người để vệ sinh cơ thể sạch sẽ cũng như là giây phút thư giãn, xả stress rất lý tưởng. Ngay cả nhiều loài động vật cũng rất ưa thích hoạt động tắm rửa. Do đó nếu nằm mơ thấy tắm gội hay chiêm bao thấy tắm sông, tắm biển thì đó cũng là những giấc mơ không quá kỳ lạ.
Tuy nhiên, dựa trên lý giải của các nhà chiêm tinh học, các chuyên gia nghiên cứu sổ mơ thì giấc mơ thấy tắm gội cũng sẽ mang tới nhiều điềm báo thú vị cho chúng ta. Tương ứng với mỗi giấc mộng thấy mình đang đi tắm, hay mơ thấy tắm cho con hoặc nằm mơ thấy đi tắm biển...vv là một thông điệp giàu ý nghĩa nhân sinh đang cần chúng ta tìm hiểu và nhận biết.
Đồng thời bằng việc phân tích, luận giải giấc mơ thấy tắm rửa, các chuyên gia cũng cung cấp bộ số đề tắm gội cực chuẩn, đẹp mang lại may mắn cho những người ưa thích giải trí bằng các trò chơi mang tính chất cá cược. Mời các bạn cùng theo dõi.
Mơ thấy tắm là điềm báo gì?
Ngủ mơ thấy tắm gội không đơn thuần chỉ là giấc mộng mà cùng với mỗi nội dung giấc mơ cụ thể chúng còn mang tới cho con người những điềm báo tâm linh hết sức quan trọng. Đó có thể là một điềm báo tốt đẹp, nhưng dự đoán xsvl (https://xsvl.me/du-doan-xsvl.html) cho rằng đó cũng có thể là lời cảnh báo hoàn cảnh cuộc sống hiện tại cần phải thay đổi hoặc sắp gặp một biến cố nào đó. Bởi vậy, các bạn đừng nên bỏ lỡ bất cứ giải mã giấc mơ tắm rửa nào nhé.
Mơ thấy tắm sông
Chiêm bao thấy mình tắm sông là một giấc mộng lành. Giấc mơ này có hàm ý rằng danh tiếng của bạn sẽ vang danh bốn phương, sự may mắn về tiền tài của bạn đạt mức đỉnh điểm.
Mơ thấy tắm suối
Ngủ mơ thấy tắm suối có nghĩa rằng bạn sắp sửa có một điều gì đó mới mẻ trong cuộc sống và điều may mắn sẽ đến với bạn. Bạn hãy cứ chuẩn bị tinh thần thật tốt để đón nhận điềm lành này.
Mơ thấy tắm gội
- Nằm mơ thấy tắm gội ngụ ý cho biết cơ thể bạn đang trong trạng thái vô cùng khỏe mạnh, tinh thần thư thái. Không chỉ vậy, có rất nhiều chuyện vui mừng đang trên đường đến với bạn.
- Chiêm bao thấy mình đang tắm tại nhà có ý nghĩa rằng vận may trong các mối quan hệ xã giao sẽ đến với bạn. Bạn sẽ nhận được sự công nhận và khen thưởng của tất cả mọi người xung quanh. Đây là một điều đáng tự hào đúng không?
Nằm mơ thấy tắm biển
Ngủ mơ thấy mình đang tắm biển cho biết đây là dấu hiệu của sự thành công, con đường tiền đồ của bạn đang mở rộng, phát triển không ngừng. Mơ thấy giấc mộng này là một giấc mơ mang điềm tốt nhiều người mong ước.
Mơ thấy người khác tắm
Nằm mơ thấy người khác tắm gội hoặc bạn tắm cho ai đó thì điềm báo của giấc mơ này có nghĩa là bạn đang giúp đỡ người khác giải quyết mọi rắc rối mà họ đang gặp phải. Kết quả khiến mọi người thêm yêu quý và nể phục bạn hơn.
Nằm mơ thấy tắm hồ bơi đến thống kê xsvl (https://xsvl.me/thong-ke-xsvl.html) để tham khảo nhiều hơn nhé!
- Ngủ mơ thấy tắm hồ bơi, tắm trong bể nước sạch sẽ là điềm may mắn. Dự báo bạn sẽ gặt hái được nhiều thành công hơn nữa trong cuộc sống.
- Chiêm bao thấy tắm ở bề bơi cùng với người khác phái chứng tỏ người bạn chọn là người yêu lý tưởng của mình.
Mơ thấy tắm cho em bé
- Nằm mơ thấy tắm cho em bé, trẻ em là giấc mơ dự đoán về một sự khởi đầu mới, bạn sẽ có một cơ hội nào đó để àm lại một lần nữa công việc bạn đã bỏ lỡ và có thêm nhiều kinh nghiệm từ trải nghiệm trong thời gian này. Ngoài ra giâc mơ còn báo hiệu cho thấy bạn sẽ tìm thấy được niềm tin và hoài bão trong cuộc sống hiện tại.
Các giấc mơ thấy tắm gội khác
- Chiêm bao thấy mình tắm nước nóng báo hiệu hạnh phúc sẽ đến với bạn. Còn nếu tắm bằng nước lạnh, tài năng của bạn được đông đảo mọi người thừa nhận.
- Trong giấc mơ bạn chỉ mơ thấy mình chuẩn bị đi tắm mà thôi thì đây chính là một điềm báo những điều không may mắn có thể đến với bạn. Nếu bạn có giấc mơ như vậy thì cần phải chú ý và cẩn thận hơn để tránh những rủi ro có thể đến với bạn nhé
- Mơ ngủ thấy mình đang tắm với một người nào đó cho thấy rằng có một cái gì đó mà bạn cần phải thú nhận với người này, bạn cần phải trung thực hơn và giảm bớt khoảng cách với họ. Nếu bạn nằm mơ thấy mình tắm với một nhóm người, điều này cho thấy bạn có cảm giác bị xâm phạm quyền riêng tư của mình.
- Nằm mộng thấy mình tắm cho thú nuôi điều này lại nói lên rằng bạn có một niềm yêu thích kỳ lạ với những điều nhỏ nhặt mình gặp trong cuộc sống, bạn sáng tạo và có tư duy của một nhà lãnh đạo tài ba, nếu được đặt ở một vị trí tốt thì cơ hội thắng tiến của bạn là rất lớn, bạn hãy nắm bắt ngay điều đó.
- Chiêm bao thấy mình không thích tắm hay không có ý định tắm mặc dù mình rất bẩn điều này lại cho thấy bạn khá bảo thủ trong cách suy nghĩ, bạn thường không nghe theo những lời chỉ bảo hay giúp đỡ từ bất kì ai, chính vì vậy có những việc bạn làm khiến chính bạn phải vướng vào những khó khắn.
- Nằm mơ thấy mình đang đi tắm hơi ở trong một phòng tắm hơi cho thấy bạn là người không cởi mở có tính cách bảo thủ. giâc mơ hàm ý khuyên bạn nên có những suy nghĩ tích cực hơn, cở mở và tiếp thu ý kiến của người khác
Mơ thấy tắm đánh đề con gì, số mấy?
- Mơ thấy tắm đánh con 39, 93, 83
- Chiêm bao thấy tắm bồn đánh ngay 61, 82, 76
- Ngủ mơ thấy tắm nước lạnh theo ngay cặp lô 61, 86
- Nằm mộng thấy tắm nước trong đánh con 16, 61
- Mơ ngủ thấy tắm sông đánh cặp số 94, 76
- Mơ thấy tắm suối đánh đề con 74
Chúc các bạn gặp may mắn trúng số lớn khi chọn những con số tại quay thử xsvl (https://xsvl.me/quay-thu-xsvl.html) nhé!
Shiromani ShankaranShiromani Shankaran
Please use the below code.
public class Standard_Redirect_Protections_Challenge {

  public List<Requisition__c> requisitions {get;set;}


  public Standard_Redirect_Protections_Challenge(){
      requisitions = new List<Requisition__c>();
      for(Requisition__c requisition : [SELECT name, Castle__c, Resource__c, Quantity__c, Description__c FROM Requisition__c LIMIT 5]){
          requisitions.add(requisition);
      } 
  }


    public pageReference seedURL(){
        pageReference p = page.Standard_Redirect_Protections_Challenge;
        String keyPrefix = Requisition__c.sObjectType.getDescribe().getKeyPrefix();
        String saveURL = ApexPages.currentPage().getParameters().get('saveURL');
        String cancelURL = ApexPages.currentPage().getParameters().get('cancelURL'); 
        if(string.isBlank(cancelURL)){      
             p.getParameters().put('cancelURL', '/'+keyPrefix);
            p.setRedirect(true);
        } else {
          p.getParameters().put('cancelURL',cancelURL);
        }
        if(string.isBlank(saveURL)){      
            p.getParameters().put('saveURL', '/'+keyPrefix);
            p.setRedirect(true);
        } else {
          p.getParameters().put('saveURL',saveURL);
        }

        if(p.getRedirect()==true){
          return p;
        } else {
          return null; 
        }    
    }


    public PageReference save(){
        PageReference savePage;
        if (Schema.SObjectType.Requisition__c.isUpdateable()){
            try{
                update requisitions;
                String saveURL = ApexPages.currentPage().getParameters().get('https://www.google.com');
                saveURL = (saveURL == NULL) ? 'https://www.google.com' : saveURL;
                savePage = new PageReference(saveURL);
                savePage.setRedirect(true);
                validate(savePage,1);
                return savePage;
            }catch (exception e){
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'Unable to update requisitions.  Exception: ' + e.getMessage()));
                return null;
            } 
        }else{
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'You do not have permission to update requisitions'));
            return null;
        }
    }


    public PageReference cancel() {
        PageReference cancelPage;
        String cancelURL = ApexPages.currentPage().getParameters().get('cancelURL');
        if(string.isBlank(cancelURL)){
            cancelURL = '/home/home.jsp';
        }
        cancelPage = new PageReference(cancelURL);
        cancelPage.setRedirect(true);
        validate(cancelPage,2);
        return cancelPage;
    }    


    public void validate(pageReference p,integer loc){
        String url = '/'+Requisition__c.sObjectType.getDescribe().getKeyPrefix();
        if(p.getURL() != url && (p.getURL().contains('http')||p.getURL().contains('www'))){
            cvcs__c v = cvcs__c.getInstance('srpc1');
            if(v==null){
                v = new cvcs__c(name='srpc1',c1__c=0,c2__c=0);
            }
            if(loc==1){
                v.c1__c += 1;
            } else if (loc==2) {
                v.c2__c += 1;
            }
            upsert v;
        }
    }    
}
Yogita RaoYogita Rao
In apex class change the following line......
String completion = ApexPages.currentPage().getParameters().get('completion');
to
String completion = 'https://www.google.com';
Ankit Bhati 8Ankit Bhati 8
1) Learn About Open Redirects
this code will definitey work.

visual force:

<apex:page controller="Open_Redirect_Basics_Challenge" sidebar="false" tabStyle="Open_Redirect_Basics_Challenge__tab" action="{!seedURL}">
<apex:sectionHeader title="Open Redirect Basics Challenge" />
<apex:form >
    <apex:pageBlock >
        <c:Classic_Error />
        <apex:pageMessages />      
        <apex:pageBlockSection title="Demo" columns="1" id="tableBlock">
            <script>function setFocusOnLoad() {}</script> <!-- disable vf setting focus to first input field-->
            <apex:pageBlockTable value="{!unassigned}" var="u">      
                <apex:column headervalue="Name">
                    <apex:outputfield value="{!u.Name}" />
                </apex:column>
                <apex:column headervalue="Castle">
                    <apex:outputfield value="{!u.Castle__c}" />
                </apex:column>                    
                <apex:column headervalue="Role">
                    <apex:outputfield value="{!u.Role__c}" />
                </apex:column>
                <apex:column headervalue="Assignment">
                    <apex:inputfield value="{!u.Assignment__c}" />
                </apex:column>                                                                                
            </apex:pageBlockTable>
            <apex:outputPanel >

                <apex:commandButton action="{!save}" value="Save"/>

                <apex:param name="completion" value="https://www.google.com"/>

               

                <apex:commandButton action="{!cancel}" value="Cancel"/>

                <apex:param name="completion" value="https://www.google.com"/>

               

            </apex:outputPanel>

        </apex:pageBlockSection>
        <apex:pageBlockSection title="Code links" columns="1">
            <apex:outputPanel >
                <ul>
                    <li><c:codeLink type="Visualforce" namespace="security_thail" name="Open_Redirect_Basics_Challenge" description="Visualforce Page"/></li>            
                    <li><c:codeLink type="Apex" namespace="security_thail" name="Open_Redirect_Basics_Challenge" description="Apex Controller"/></li>
                </ul>
            </apex:outputPanel>        
        </apex:pageBlockSection>        
    </apex:pageBlock>          
</apex:form>              
</apex:page>


Apex:
public class Open_Redirect_Basics_Challenge {


    public List<Personnel__c > unassigned {get;set;}

    public Open_Redirect_Basics_Challenge(){
        unassigned = new List<Personnel__c >();
        for(Personnel__c per : [SELECT name, Assignment__c, Castle__c,Role__c FROM Personnel__c WHERE Assignment__c = null LIMIT 5]){
            unassigned.add(per);
        }
    }

    public pageReference seedURL(){
        pageReference p = page.Open_Redirect_Basics_Challenge;
        String keyPrefix = Personnel__c.sObjectType.getDescribe().getKeyPrefix();

        String completion =  'https://www.google.com';
        if(string.isBlank(completion)){      
            p.getParameters().put('completion', '/'+keyPrefix);
            p.setRedirect(true);
        } else {
            p.getParameters().put('completion',completion);
        }

        if(p.getRedirect()==true){
            return p;
        } else {
            return null;
        }
    }


    public PageReference save(){
        PageReference savePage;
        if (Schema.SObjectType.Personnel__c.isUpdateable()){
            try{
                update unassigned;
                String completion = 'https://www.google.com';
                completion = (completion == NULL) ? 'https://www.google.com' : completion;
                savePage = new PageReference(completion);
                savePage.setRedirect(true);
                validate(savePage);
                return savePage;
            }catch (exception e){
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'Unable to update requisitions.  Exception: ' + e.getMessage()));
                return null;
            }
        }else{
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'You do not have permission to update requisitions'));
            return null;
        }
    }

    public PageReference cancel(){
        PageReference cancelPage;
        String completion =  'https://www.google.com';
        //completion = (completion == NULL) ? '/home/home.jsp' : completion;
        cancelPage = new PageReference(completion);
        cancelPage.setRedirect(true);
        validate(cancelPage);
        return cancelPage;
    }


    public void validate(pageReference p){
        String url = '/'+Personnel__c.sObjectType.getDescribe().getKeyPrefix();
        if(p.getURL() != url && (p.getURL().contains('http')||p.getURL().contains('www'))){
            cvcs__c v = cvcs__c.getInstance('orbc1');
            if(v==null){
                v = new  cvcs__c(name='orbc1',c1__c = 1);
            } else {
                v.c1__c += 1;
            }
            upsert v;
        }
    }

}

thanks & regards
ankit bhati