Skip to main content
Participant
September 11, 2020
Answered

How to handle Invalid ReturnFormat

  • September 11, 2020
  • 3 replies
  • 1475 views

I have a CFC method that uses a cfscript to define a  structure that is initialized with details from a query and used to create an HTML output which is saved using <cfsavecontent>. The compressed html struct is then returned to the calling AJAX to render the output on the screen. I cannot post the code because of company policies but the url looks something like this : http://appurl/componenetName.cfc?method=methodname&returnFormat=json. Now during a security testing, the person replaced  the json  with  'abc' and it throws an invalid Return Format - which is totally acceptable, but - I want to show a general application Application error instead of the CF error. How and where do I catch this error? Will a cftry and cfcatch work? I tried defining error in the ajax call but I still get the error. I tried to use if,else to see if no input is passed to throw the error, but that still doesnt change the invalid returnType. Any help on this will highly appreciated. 

 

PS: I am new to CF, been only 6 months so please respond with a simple expalnantion. Thanks in advance.

    This topic has been closed for replies.
    Correct answer John123

    The problem is the error is not being thrown insode the CFC function it is thrown when the function is called so you cannot trap it insode the function. Per documentation the only valid values for ReturnFormat are JSON, PLAIN or WDDX, anthing else will result in an error on the call. The only way to trap this is to use the OnError in the Application CFC.

     

    See article by Ben Nadel https://www.bennadel.com/blog/1567-handling-remote-api-errors-with-application-cfcs-onerror-event-method.htm

    3 replies

    WolfShade
    Legend
    September 11, 2020

    So, I've been playing around.  I created a CFC that will return a CFDUMP of the function called.

    test.cfc:

    <cffunction name="myTest1" access="remote" description="This is only a test to see what is returned." output="no" returnformat="plain" secureJSON="no">
    	<cfsavecontent variable="variables.thisStuff">
    		<cfdump var="#this.myTest1#" />
    	</cfsavecontent>
    	<cfreturn variables.thisStuff />
    </cffunction>

    test.cfm:

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Untitled Document</title>
    </head>
    
    <body>
    	<button type="button" id="testBtn" name="testBtn">Click Me</button>
    	<div id="testDiv"></div>
    	<script>
    		var testBtn = document.getElementById('testBtn'),
    			testDiv = document.getElementById('testDiv');
    		function testFunction(event,data){
    			testDiv.innerHTML = this.responseText;
    			}
    
    		testBtn.addEventListener('click',function(){
    			var oReq = new XMLHttpRequest();
    			oReq.addEventListener("load", testFunction);
    			oReq.open("GET", "test.cfc?method=myTest1");
    			oReq.send();
    			});
    	</script>
    </body>
    </html>

    This is what it returned:

    Notice that even though I used the attribute returnFormat, it's not listed.

     

    What happened here, Adobe?  Shouldn't this have all attributes?

     

    V/r,

     

    ^ _ ^

    Yukti5F90Author
    Participant
    September 14, 2020

    Thank you for all the suggestions. Really appreciate it. 

    WolfShade
    Legend
    September 11, 2020

    Actually, I just thought of something else.  Whitelisting.  In the CFC, near the top, use a switch/case that uses the valid formats, and set a default to JSON if nothing matches.  Voila.  Problem solved.

    <cfswitch expression="#arguments.returnFormat#">
       <cfcase value="JSON,WDDX,XML,PLAIN" delimiters=",">
          <!--- Do nothing; it's valid! --->
       </cfcase>
       <cfdefaultcase>
          <!--- Someone is trying something they shouldn't be trying --->
          <cfset arguments.returnFormat = "JSON" />
       </cfdefaultcase>
    </cfswitch>

    HTH,

     

    ^ _ ^

    WolfShade
    Legend
    September 11, 2020

    Hello, and welcome to ColdFusion.  I hope you enjoy working CF as much as I do.

     

    A CFTRY/CFCATCH could work well, and you can use the catch to return a simple error message to the user for display, and also use that to CFMAIL a CFDUMP of the error message (#cfcatch#) to yourself.  At least that is how I would handle it.  I'm sure there are others who can also provide some really good ideas.

     

    HTH,

     

    ^ _ ^

    John123Correct answer
    Participating Frequently
    September 11, 2020

    The problem is the error is not being thrown insode the CFC function it is thrown when the function is called so you cannot trap it insode the function. Per documentation the only valid values for ReturnFormat are JSON, PLAIN or WDDX, anthing else will result in an error on the call. The only way to trap this is to use the OnError in the Application CFC.

     

    See article by Ben Nadel https://www.bennadel.com/blog/1567-handling-remote-api-errors-with-application-cfcs-onerror-event-method.htm

    BKBK
    Community Expert
    Community Expert
    September 12, 2020

    I like the method suggested by John1231 . But I disagree that it is the only way.

     

    You could also use the tag <cferror>.

     

    For example, proceed as follows:

    1) In the same directory as Application.cfc, create a new page, errorHandler.cfm, to handle errors.

    2) Add a cferror tag to Application.cfc, immediately following the "this" settings. Set the tag's template attribute to "errorhandler.cfm".

     

    That's it.

     

    Application.cfc
    <cfcomponent displayname="Application" output="true" hint="Handle the application.">
    	<!--- Set up the application. --->
    	<cfset this.Name = "myApp">
    	<cfset this.ApplicationTimeout = createTimeSpan( 1, 0, 0, 0 )>
    	<cfset this.sessionTimeout = createTimeSpan( 0, 0, 30, 0 )>
    	<cfset this.sessionManagement = true />
    	
    	<cferror template="errorHandler.cfm" type="exception" exception="any">
    
    	<cffunction
    		name="OnApplicationStart"
    		access="public"
    		returntype="boolean"
    		output="false"
    		hint="Fires when the application is first created.">
    		
    		<cfreturn true>
    	</cffunction>
    </cfcomponent>
    
    errorHandler.cfm
    <!--- 
    Dump the details of the error. Select the information you will need to show.
    Then comment out this dump code and proceed such as in the example below.
    --->
    <!---<cfdump var="#error#" label="Error struct in errorHandler">--->
    
    <cfif findNoCase("invalid returnFormat", error.message) gt 0>
    	You specified the wrong value for <b>returnFormat</b>. The value you specify must be <b>wddx</b>, <b>plain</b> or <b>json</b>.
    </cfif>