cloud-sdk-js
cloud-sdk-js copied to clipboard
Fetching csrf token fails
Describe the Bug
This is an indirect issue which originates from builtin CSRF-Token Handling in sap cap.
Fetching the csrf token fails because the on-premise system does return http status 405 when fetching the token and also does not return a x-csrf-token header in the response, but only set-header (w/ the cookie).
As seen in the code https://github.com/SAP/cloud-sdk-js/blob/ac506e453805d13c63e6c19ff55754b9082317d4/packages/http-client/src/csrf-token-middleware.ts#L140C11-L140C48 the cloud sdk will only check for x-csrf-token not for set-header.
Is this an expected issue and / or is there any way to get around this?
Related cds config:
{
"requires": {
"CE_QUALITYNOTIFICATION_0001": {
"kind": "odata",
"model": "srv/external/CE_QUALITYNOTIFICATION_0001",
"csrf": {
"method": "get"
},
"credentials": {
"path": "/sap/opu/odata4/sap/api_qualitynotification/srvd_a2x/sap/qualitynotification/0001"
}
}
}
}
Related error logs:
info backend-proxy-middleware /odata/v4/documents/Documents(ID=60298dbf-f89f-4903-b81e-b73bcf517e64,IsActiveEntity=true)/DocumentsService.createQualityNotification
(node:42806) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
[odata] [INFO] POST /odata/v4/documents/Documents(ID=60298dbf-f89f-4903-b81e-b73bcf517e64,IsActiveEntity=true)/DocumentsService.createQualityNotification
[DocumentsService] [INFO] createQualityNotification {
...
}
[cds] [INFO] connect to CE_QUALITYNOTIFICATION_0001 > odata {
path: '/sap/opu/odata4/sap/api_qualitynotification/srvd_a2x/sap/qualitynotification/0001',
url: '...',
authentication: '...',
username: 'RFC_USER',
password: '...',
queries: { 'sap-client': '...' },
isTrustingAllCertificates: true,
queryParameters: { 'sap-client': '...' }
}
[2025-06-13T09:58:26.757Z] DEBUG (authorization-header): Getting authentication related headers for authentication type: BasicAuthentication
[2025-06-13T09:58:26.757Z] WARN (http-agent): "isTrustingAllCertificates" property in the provided destination is set to "true". This is highly discouraged in production.
[2025-06-13T09:58:26.758Z] DEBUG (jwt): JWT zid is: undefined, app_tid is: undefined.
[2025-06-13T09:58:26.930Z] WARN (csrf-middleware): Failed to get CSRF token from URL: /sap/opu/odata4/sap/api_qualitynotification/srvd_a2x/sap/qualitynotification/0001/QualityNotification/.
[2025-06-13T09:58:27.040Z] WARN (csrf-middleware): Failed to get CSRF token from URL: /sap/opu/odata4/sap/api_qualitynotification/srvd_a2x/sap/qualitynotification/0001/QualityNotification.
[2025-06-13T09:58:27.041Z] DEBUG (http-client): Execute 'POST' request with target: /sap/opu/odata4/sap/api_qualitynotification/srvd_a2x/sap/qualitynotification/0001/QualityNotification.
The headers of the request are:
authorization:<DATA NOT LOGGED TO PREVENT LEAKING SENSITIVE DATA>
accept:application/json,text/plain
content-type:application/json
content-length:77
x-correlation-id:42738df5-d0a8-4be6-bb16-9493ce712842
x-correlationid:42738df5-d0a8-4be6-bb16-9493ce712842
[remote] [WARN] Error: Error during request to remote service: CSRF token is missing
at run (/Users/some/project/node_modules/@sap/cds/libx/_runtime/remote/utils/client.js:233:31)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async RemoteService.on_handler (/Users/some/project/node_modules/@sap/cds/libx/_runtime/remote/Service.js:273:20)
at async next (/Users/some/project/node_modules/@sap/cds/lib/srv/srv-dispatch.js:61:17)
at async RemoteService.handle (/Users/some/project/node_modules/@sap/cds/lib/srv/srv-dispatch.js:59:10)
at async DocumentsService.onCreateQualityNotification (/Users/some/project/srv/documents/service.ts:274:19)
at async next (/Users/some/project/node_modules/@sap/cds/lib/srv/srv-dispatch.js:61:17)
at async DocumentsService.handle (/Users/some/project/node_modules/@sap/cds/lib/srv/srv-dispatch.js:59:10) {
statusCode: 502,
reason: [AxiosError]
}
[DocumentsService] [ERROR] Error submitting quality notification {
error: {
code: '/IWBEP/CM_V4H_RUN/043',
message: 'CSRF token is missing',
'@SAP__common.ExceptionCategory': 'CSRF_Token_Missing'
}
}
Steps to Reproduce
- using
@sap/cds - CSRF-Token Handling
- Trigger remote request to on-premise system not setting
x-csrf-tokenheader, but onlyset-cookie
Expected Behavior
Ideally the sdk should also handle set-cookie header
Screenshots
No response
Used Versions
| package | version |
|---|---|
| @cap-js/asyncapi | 1.0.3 |
| @cap-js/cds-test | 0.3.0 |
| @cap-js/cds-types | 0.11.0 |
| @cap-js/db-service | 2.1.2 |
| @cap-js/hana | 2.1.1 |
| @cap-js/openapi | 1.2.3 |
| @cap-js/sqlite | 2.0.1 |
| @sap/cds | 9.0.3 |
| @sap/cds-compiler | 6.0.12 |
| @sap/cds-dk | 9.0.5 |
| @sap/cds-fiori | 2.0.1 |
| @sap/cds-mtxs | 3.0.1 |
| Node.js | v22.16.0 |
| rpm | 11.4.1 |
| @sap-cloud-sdk/connectivity | 4.0.2 |
| @sap-cloud-sdk/http-client | 4.0.2 |
| @sap-cloud-sdk/resilience | 4.0.2 |
Code Examples
const qn = await cds.connect.to('CE_QUALITYNOTIFICATION_0001')
// WORKAROUND: manually fetch CSRF token before sending POST request
// Fetching token via config fails because of 405 status code and missing x-csrf-token header
// See: https://cap.cloud.sap/docs/node.js/remote-services#advanced-configuration
const cookie = await qn
.send('HEAD', 'QualityNotification', {
'x-csrf-token': 'fetch',
})
.then((response: AxiosResponse) => {
const { headers } = response
return headers['set-cookie']
})
.catch((error: unknown) => {
const { reason: { response: { headers } } } = error as Error & {
reason: {
response: AxiosResponse
}
}
return headers['set-cookie']
})
const res = await qn.send<object>('POST', 'QualityNotification', {
NotificationType: 'F1',
NotificationText: 'Short description of the issue',
}, {
cookie,
})
Log File
No response
Affected Development Phase
Development
Impact
Impaired
Timeline
No response
Additional Context
No response
Hi @pwasem ,
The SDK, by design, always checks for the x-csrf-token header first, and only if it's present does it proceed to check for the set-cookie. So your workaround makes sense in this context.
We do offer a way to override the default CSRF implementation using middlewares, as described here.
Closing this issue due to inactivity.