+ Start a Discussion
Albert BarbieriAlbert Barbieri 

Stuck on Prevent Open Direct Challenge

I am having an issue verifying the Prevent Open Redirect Challenge. The code I put into the VF page is actually working correctly, but the verify is coming back with a standard error message.
 
Also I happen to notice that the code displayed for the "Force Local Redirects Only" section on the trailhead page for "Prevent Open Redirects in Your Code" is inconsistent and possibly in error.
 
In the larger code display it shows the line (09) as being
 
           completion.replaceFirst('/','');
 
but in the follow on description it shows that line of code to be
 
completion.replaceFirst('/+','');
 
And according to the documentation for the ReplaceFirst method it returns a string with the desired changes and does not change the target string. That would seem to indicate that the code in the example given in the module content given is not going to actually remove any initial '/' from completion.
 
The code I put in the VF page which is working, but not verifying for the "Check Challenge" is
 
              if(finishURL.startsWith('/')){ 
                    finishURL = finishURL.replaceFirst('/+',''); 
                    }
                savePage = new PageReference('/'+finishURL);
 
Can someone tell me what I need to change in order to get past this challenge? I have actually completed all the other challenges for this module so this is holding up my completion of this particular module.
 
Thanks in advance for any assistance!
Best Answer chosen by Albert Barbieri
Suley KaboreSuley Kabore
Hello Albert,
I have had the same problem, and it looks like the instructions in the unit are somewhat misleading. I just rmoved the '+' sign on line 9 and it worked for me. Here is the code I passes the challenge with. Have a good one

 if(finishURL.startsWith('/')){
                finishURL.replaceFirst('/','');
                }
                savePage = new PageReference('/'+finishURL);

All Answers

Suley KaboreSuley Kabore
Hello Albert,
I have had the same problem, and it looks like the instructions in the unit are somewhat misleading. I just rmoved the '+' sign on line 9 and it worked for me. Here is the code I passes the challenge with. Have a good one

 if(finishURL.startsWith('/')){
                finishURL.replaceFirst('/','');
                }
                savePage = new PageReference('/'+finishURL);
This was selected as the best answer
Albert BarbieriAlbert Barbieri
Thnaks, Suley.

Removing the '+' worked and got me past the challenge.
Suley KaboreSuley Kabore
You are welcome Albert.
Anton ZeefAnton Zeef
Strange.... the code does the correct thing, however Trailhead does not accept the challenge when we use
replaceFirst('/+', '')
vs
replaceFirst('/', '')

which on non-salesforce servers would be vulnerable to inserting //www.google.com like URLs...

Thanks Suley for pointing that out!
Suley KaboreSuley Kabore
You are welcome Anton
Andrew WeinsteinAndrew Weinstein
had the same issue. seems like it should be '/+' to replace all slashes, but the "prevent open redirect challenge" fails with the + and succeeds if you just do the one forward slash.
Shiromani ShankaranShiromani Shankaran
Please use the below code:
public class Prevent_Open_Redirect_Challenge {

    public Resource_Type__c rtype {get;set;}

    public Prevent_Open_Redirect_Challenge(){
        if(rtype==null){
            string rtid = [select id from recordType where sObjectType = 'Resource_Type__c' and DeveloperName = 'Personnel' limit 1].id; 
            rtype = new Resource_Type__c(recordtypeid=rtid);
        }
    }

    public PageReference save(){
        PageReference savePage;
        if (Schema.SObjectType.Resource_Type__c.isCreateable()){
            try{


                insert rtype;

                String finishURL = ApexPages.currentPage().getParameters().get('finishURL');
                
                if(finishURL.startsWith('/')){
                finishURL.replaceFirst('/','');
                }
                savePage = new PageReference('/'+finishURL);
                
               // savePage = new PageReference(finishURL);
                
                savePage.setRedirect(true);
                
                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 seedURL(){
        pageReference p = page.Prevent_Open_Redirect_Challenge;
        String keyPrefix = Resource_Type__c.sObjectType.getDescribe().getKeyPrefix();

        String finishURL = ApexPages.currentPage().getParameters().get('finishURL');
        if(string.isBlank(finishURL)){      
            p.getParameters().put('finishURL', '/'+keyPrefix);
            p.setRedirect(true);
        } else {
            p.getParameters().put('finishURL',finishURL);
        }

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

}
Karime C. S.Karime C. S.

Thanks Shiromani Shankaran
My code simply wouldn't work

Ankit Bhati 8Ankit Bhati 8
1) prevent Open Redirects in Your Code
Add Protection Against Open Redirect
this code will work 100%

visual code

<apex:page controller="Prevent_Open_Redirect_Challenge" sidebar="false" tabStyle="Prevent_Open_Redirect_Challenge__tab" action="{!seedURL}">
<apex:sectionHeader title="Prevent Open Redirect Challenge" />
<apex:form >
    <apex:pageBlock >
        <c:Classic_Error />
        <apex:pageMessages />      
        <apex:pageBlockSection title="Demo" columns="1" id="tableBlock">
            <apex:outputPanel >
                <apex:outputText value="Create a new resource of type: "/><apex:outputField value="{!rtype.recordtypeid}"/><br/>
                <br/>
                <apex:outputText value="New Resource Name: "/><apex:inputField value="{!rtype.name}"/> <br/>
            </apex:outputPanel>
            <apex:outputPanel >
                <apex:commandButton action="{!save}" value="Save"/>            
            </apex:outputPanel>      
        </apex:pageBlockSection>
        <apex:pageBlockSection title="Code links" columns="1">
            <apex:outputPanel >
                <ul>
                    <li><c:codeLink type="Visualforce" namespace="security_thail" name="Prevent_Open_Redirect_Challenge" description="Visualforce Page"/></li>            
                    <li><c:codeLink type="Apex" namespace="security_thail" name="Prevent_Open_Redirect_Challenge" description="Apex Controller"/></li>
                </ul>
            </apex:outputPanel>        
        </apex:pageBlockSection>        
    </apex:pageBlock>          
</apex:form>              
</apex:page>


Apex:
public class Prevent_Open_Redirect_Challenge {

    public Resource_Type__c rtype {get;set;}

    public Prevent_Open_Redirect_Challenge(){
        if(rtype==null){
            string rtid = [select id from recordType where sObjectType = 'Resource_Type__c' and DeveloperName = 'Personnel' limit 1].id;
            rtype = new Resource_Type__c(recordtypeid=rtid);
        }
    }

   public PageReference save() {

        PageReference savePage;

        if (Schema.SObjectType.Resource_Type__c.isCreateable()) {

            try {

 

                insert rtype;

 

                String finishURL = ApexPages.currentPage().getParameters().get('finishURL');

                system.debug('First$' + finishURL);

                if (finishURL.startsWith('/')) {

                    system.debug('Second$' + finishURL);
                    finishURL.replaceFirst('/','');

 

                    system.debug('Third$' + finishURL);

                }

                savePage = new PageReference('/' + finishURL);

 

                savePage.setRedirect(true);

                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 seedURL(){
        pageReference p = page.Prevent_Open_Redirect_Challenge;
        String keyPrefix = Resource_Type__c.sObjectType.getDescribe().getKeyPrefix();

        String finishURL = ApexPages.currentPage().getParameters().get('finishURL');
        if(string.isBlank(finishURL)){      
            p.getParameters().put('finishURL', '/'+keyPrefix);
            p.setRedirect(true);
        } else {
            p.getParameters().put('finishURL',finishURL);
        }

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

}