1

I'm working on the trigger for the custom object, when we update the custom mail field, it has to be updated in the third-party API (which I've added in the remote site settings).

As we know @future(callout=true) does not allow us to do call another @future(callout=true) method, I've added another PUT callout(mentioned below as PUT Method callout) in the same future method with some conditions met. The first callout for the same API gave us the expected result. But the callout made for updating Mail ID in the API returns us the 403 forbidden error (please refer to the HTML format response from the third party API)

HTML format response

    <!DOCTYPE html>
    <html lang="en">
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <meta name="robots" content="NONE,NOARCHIVE">
      <title>403 Forbidden</title>
      <style type="text/css">
         html * { padding:0; margin:0; }
         body * { padding:10px 20px; }
         body * * { padding:0; }
         body { font:small sans-serif; background:#eee; color:#000; }
         body>div { border-bottom:1px solid #ddd; }
         h1 { font-weight:normal; margin-bottom:.4em; }
         h1 span { font-size:60%; color:#666; font-weight:normal; }
         #info { background:#f6f6f6; }
         #info ul { margin: 0.5em 4em; }
         #info p, #summary p { padding-top:10px; }
         #summary { background: #ffc; }
         #explanation { background:#eee; border-bottom: 0px none; }
      </style>
      </head>
<body>
<div id="summary">
  <h1>Forbidden <span>(403)</span></h1>
  <p>CSRF verification failed. Request aborted.</p>



    <p>You are seeing this message because this HTTPS site requires a “Referer header” to be
 sent by your Web browser, but none was sent. This header is required for security reasons, to
 ensure that your browser is not being hijacked by third parties.</p>

      <p>If you have configured your browser to disable “Referer” headers, please re-enable them, 
at least for this site, or for HTTPS connections, or for “same-origin” requests.</p>

      <p>If you are using the &lt;meta name=&quot;referrer&quot; content=&quot;no-
referrer&quot;&gt; tag or including the “Referrer-Policy: no-referrer” header, please remove them.
 The CSRF protection requires the “Referer” header to do strict referer checking. If you’re 
concerned about privacy, use alternatives like &lt;a rel=&quot;noreferrer&quot; …&gt; for links to
 third-party sites.</p>


</div>

<div id="explanation">
  <p><small>More information is available with DEBUG=True.</small></p>
</div>

</body>
</html>

It seems to be we need to update the CSRF, I added the remote site of the third party URL. Still, we are seeing the issue.

Here is my PUT method code, which updates the mail id we changed. I've tried creating a separate method without @future annotation and passed the values in parameters needed for the setBody.

PUT Method callout

    Http http = new Http();
    HttpRequest request = new HttpRequest();
    request.setEndpoint(My URL);
    request.setMethod('PUT');
    request.setHeader('Accept', 'application/json');
    request.setHeader('Authorization', 'Basic xxxx');
    request.setHeader('Content-Type', 'application/json');

    request.setBody('{\r\n    \"id\": \"'+ userID +'\",\r\n    \"email\": \"'+mailToBeUpdated+'\",\r\n    \"first_name\": \"'+first_name+'\",\r\n    \"last_name\": \"'+first_name+'\"\r\n}');

Even I've tried JSON generator for the request body and passed it as a parameter

JSONGenerator gen = JSON.createGenerator(true);    
  gen.writeStartObject(); 
 
  if(MailUpdateData.containsKey('MailToBeUpdated'))
    gen.writeStringField('email', (String) MailUpdateData.get('MailToBeUpdated'));

  if(MailUpdateData.containsKey('first_name'))
    gen.writeStringField('first_name', (String) MailUpdateData.get('first_name'));

  if(MailUpdateData.containsKey('last_name'))
    gen.writeStringField('last_name', (String) MailUpdateData.get('last_name'));

  if(userID!=null || userID!='')
    gen.writeStringField('id', userID);

  gen.writeEndObject();

  String updateData = gen.getAsString();
  System.debug('update Data ::: ' + updateData);

The only time we got the mail updated is when we send the request with a hardcoded JSON value in the setBody method.

Please help me with what I've missed here.

1 Answer 1

1

This error is stating that you're missing a Referer header, which should be set to a legitimate source URL:

request.setHeader('Referer', 'https://myothersite.com/path/to/file.ext');

Note that Referer is not a typo; the original HTTP specification had this typo, so we've had to deal with it for the past few decades. Refer to your third party documentation for what a valid value would be for this header.


As an aside, your code has a logic bug:

if(userID!=null || userID!='')

Is always true; if userID is null, it will not be '', and if it is '', it will not be null. In other words, this will always be true, as false || true is always true. It should be:

if(userID != null && userID != '')

Or, you can use the isNotBlank method:

if(String.isNotBlank(userId)) 

You shouldn't be manually encoding JSON. Use JSON.serialize instead:

Map<String, Object> requestBody = new Map<String, Object>();
if(MailUpdateData.containsKey('MailToBeUpdated')){
    requestBody.put('email', MailUpdateData.get('MailToBeUpdated'));
}
if(MailUpdateData.containsKey('first_name')){
    requestBody.put('first_name', MailUpdateData.get('first_name'));
}
if(MailUpdateData.containsKey('last_name')){
    requestBody.put('last_name', MailUpdateData.get('last_name'));
}
if(String.isNotBlank(userID)){
    requestBody.put('id', userID);
}
String jsonPayload = JSON.serialize(requestBody);
2
  • Your answer was helpful. but we are still getting the cookie CSRF issue. <p>You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.</p> <p>If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for “same-origin” requests.</p>. Cookie : XXXX; expires=Sun, 30 Mar 2042 06:10:49 GMT; HttpOnly; Max-Age=630720000; Path=/; Secure. Ive added this cookie info in the setheader, we got the error Apr 4, 2022 at 6:18
  • I mean I've added String Cookies = authResponse.getHeader('Set-Cookie'); request.setHeader('Cookie', Cookies); Apr 4, 2022 at 6:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .