Issue with CSRF Token Handling in Celigo When Posting to SAP Endpoint

Hi,

I have a question about a HTPP connection with CSRF token handling in Celigo when posting to a SAP endpoint.

The setup is as follows: I need to do a POST to SAP using Basic Auth. Before that, I perform a GET (also with basic auth) with the header x-csrf-token: Fetch, which returns a token in the response. That token then needs to be included in the POST request header as x-csrf-token.

This works fine in Postman.

However, in Celigo, it doesn’t work as expected. I tried doing a GET to fetch the token and then using that token in the POST step, but it still fails. I noticed that SAP returns a different token depending on the IP address making the request, so I’m wondering if the GET and POST are being executed from different IPs in Celigo, causing the token to become invalid.

I also tried manually adding the x-csrf-token in the flow headers and setting up a connection using custom auth, where I filled in both the Basic Auth header and the token inside the http headers:

No success. Even hardcoding the token didn’t work — possibly because it’s bound to a different IP/session.

I even tried triggering a failed call to force a token refresh, but that didn’t resolve it.

I also tried using the connection Basic Auth and filling in the token manually but this also doesnt work.

So in postman its:
Get > Receive token in header
Use that token in the POST

Success

In Celigo
Get > Receive token in header
Use that token in the POST

Fail

Hope someone can help

What if you try {{{responseHeaders.x-csrf-token}}} for the “Path to token field in the HTTP response header”?

Ah, I tried using {{this.response.headers.x-csrf-token}}, but it looks like it should be {{responseheaders}}. I’ll test that later.

So just to confirm:
I need to create a bubble with a GET step, then do result mapping, and in that result mapping, extract responseheaders.
Then I can use that value in the HTTP header of the next import step — correct?

No, I mean in the connection setup where you are specifying which where to get the token, try putting that.

I followed all the steps, but I'm getting this error: "Failed to generate request headers from template: {{{responseHeaders.x-csrf-token}}}. Details: 'x-csrf-token' not defined in undefined - 1:3."

Here's what I'm doing:

  1. Source fetches data from Business Central
  2. Sends the data to SAP via HTTP POST

It seems the x-csrf-token is not being stored properly in the responseHeader.

I also tried doing a GET request before the POST, expecting the token to be picked up—but even after that, the POST still doesn't include the token.

In the Connections section, when I navigate to the Handlebars view:

I notice that the preview does not render correctly:

@tylerlamparter
I got some info from @bhavikshah, so in short: it's best to use the SAP S/4HANA connector instead of a HTTP connection.

According to Celigo’s documentation, the SAP S/4HANA connector automatically handles CSRF tokens and session cookies, so you don’t need to manually configure CSRF headers:

"When you make HTTP requests to SAP S/4HANA Cloud APIs, you can pass Cross-Site Request Forgery (CSRF) tokens in your export or import to protect data. For this, you don't have to configure any parameters in the HTTP header. The Celigo platform (integrator.io) automatically gets the CSRF token and cookies to be passed in your export or import. Click Preview in your export or import to view the CSRF token in the HTTP header."

For additional background on how CSRF works in SAP, this article gives a good overview:

Key takeaway from the article:
The client must store the CSRF token and session cookies from the Set-Cookie response header and send them with every modifying request. When the session expires, the token must be refreshed.

..

Going back to the connection. It worked and I created a connection:

However doing a POST to the endpoint gave me again the same error:

PS:
I had to add the Accept / as and Header or else I was getting a connection error.

@nuriensing Could you do a preview on import and provide screenshot ? Please mask the actual token.Also, if you're doing anything different in your import.

@bhavikshah
Below is the response header after sending a POST request using Preview:

I also ran the flow with the connection debug enabled. Here’s the connection debug log from the flow execution using the same SAP POST step:

{
  "headers": {
    "set-cookie": "removed",
    "content-type": "text/plain; charset=utf-8",
    "content-length": "28",
    "x-csrf-token": "Required",
    "sap-processing-info": "ODataBEP=,crp=,st=,MedCacheHub=,codeployed=X,softstate=",
    "sap-perf-fesrec": "20895.000000",
    "authorization": "Basic ********"
  },
  "body": "CSRF token validation failed"
}

I also tested a GET request to the same endpoint (for metadata), which does work in Postman, but not in Celigo.

These are the preview GET Request Headers when fetching the metadata:

{
  "Accept": "*/*",
  "User-Agent": "axios/1.8.2",
  "Accept-Encoding": "gzip, compress, deflate, br",
  "authorization": "Basic ********"
}

GET Response Headers:

{
  "set-cookie": "********",
  "content-type": "application/xml",
  "content-length": "********",
  "last-modified": "********",
  "cache-control": "********",
  "dataserviceversion": "********",
  "sap-processing-info": "********",
  "sap-perf-fesrec": "********",
  "authorization": "********"
}

Parsed Output Error:

[
  {
    "code": "invalid_json",
    "message": "An invalid JSON is sent in the response.body, error: please ensure that you have wrapped all JSON property names in quotes. details: Unexpected token '<', \"<?xml vers\"... is not valid JSON",
    "occurredAt": 1753689625368,
    "resolved": false,
    "source": "resource"
  }
]

PS: I did not send any json, and even when doing so, the same error returned.

Meeting with @prudhvivemulapati tomorrow, will share any updates afterward.

Update:
As mentioned in my earlier post in this thread, Celigo is currently handling the sending and fetching of the CSRF token.

However, after chatting with Bhavik Shah, he clarified the following:

Bhavik Shah – 10:51 AM
If the base URL contains sapbydesign or s4hana, you don't need to handle CSRF tokens or cookies manually — Celigo manages that automatically.

We identify this based on specific URL patterns and trigger custom logic accordingly. That said, instead of relying solely on the URL, we may expose this logic more generically in the future or use other SAP parameters to identify when CSRF handling is needed.

Proposed Improvement:
It seems that if an endpoint uses an IP address instead of a domain name, Celigo’s auto-detection may not work as expected. A possible solution might be to introduce a checkbox or toggle (e.g. “Fetch CSRF Token”) in the connection configuration, so that CSRF handling logic can be explicitly triggered when needed, even without a recognizable domain.

Just had a meeting with the Celigo team, and they flagged this as a future enhancement (SAP S/4HANA CSRF token to work without DNS; see my previous reply on this post). They’ll update accordingly.

CC: @praveenbasani

@praveenbasani Can you give any ETC for this?

Hi @nuriensing

As previously noted, addressing this will require an enhancement.

We’re currently evaluating a potential solution that is more application aware and not dependent on URL patterns for triggering app-specific policies (such as the CSRF token for SAP4Hana). This approach is still under discussion, and once approved, it will go through our feature prioritisation cycle. We’ll need some additional time before we can confirm the release timelines, and we’ll keep you updated.

thanks

1 Like