CSRF token is not generated / unclear how to generate it

Hello everyone.

I’m running a GCP instance with Tomcat 9.0.95 using XWiki 16.7.1 on Java 17 which I have also set up Nginx as a reverse proxy on the same server, I’m currently trying to migrate content from another KB where I am using a python script that was generated via an AI, with a bit of troubleshooting it works up to a certain point, I decided to attach it here (scrubbed) for you to review.
scriptHelpXWiki.txt (4.1 KB)

My main issue so far, is getting the script to be able to connect to my instance and POST the pages, there are some references to a CSRF token in many different places of the Rest API documentation: REST API (XWiki.org)
But I can’t understand how the “token” should look like in the response. Attached response from Chrome Dev Toolkit, when accessing the home page after login in.

cache-control:
max-age=2592000
cache-control:
public, no-transform
content-encoding:
gzip
content-language:
en
content-script-type:
text/javascript
content-type:
text/html;charset=UTF-8
date:
Mon, 21 Oct 2024 19:44:26 GMT
expires:
Wed, 20 Nov 2024 19:44:26 GMT
permissions-policy:
identity-credentials-get=(), keyboard-map=(), attribution-reporting=(), run-ad-auction=(), private-state-token-redemption=(), private-state-token-issuance=(), join-ad-interest-group=(), idle-detection=(), compute-pressure=(), browsing-topics=()

pragma:
no-cache
server:
nginx/1.22.1
vary:
Accept-Encoding
x-dns-prefetch-control:
off

The problem is that even if I ssh onto my GCP instance and try to get the headers using curl pointing directly onto the Tomcat XWiki instance via localhost:8080, I still don’t see the corresponding XWiki-Form-Token header.

HTTP/1.1 200 
Content-Script-Type: text/javascript
Set-Cookie: JSESSIONID=E7125C8AD17E55B1AE84B0E4EEF3ED0D; Path=/xwiki; HttpOnly
Pragma: no-cache
Cache-Control: no-cache
Expires: Wed, 31 Dec 1969 23:59:59 GMT
Content-Type: text/html;charset=UTF-8
Content-Language: en
Content-Length: 79161
Date: Fri, 18 Oct 2024 22:28:21 GMT

Can I get some pointers on what’s the proper way to get and handle this Header?
I don’t have a profound Web-Dev background so please be patient :slight_smile:
Thanks!

Hi @franciscol,

In the same section from the documentation you referred, there is this phrase: The form token is provided in every response in the same header so a GET request to any supported endpoint can be used to obtain a form token.
You only have to perform the simplest GET request to obtain a token and that would be used in the future requests, until you restart the XWiki instance.

Hello.
That’s exactly the problem I’m having, the response headers I shared are from GET requests. No CSRF token to be found.

Alas, I tried a simplified version using HTTP Auth, and then it worked!
The token is available there:

Thanks, it was just a matter of “KISS” (Keep it simple stupid!)

In case anyone wants the code, it is just sending the request and printing the response, here it is:

import requests
from requests.auth import HTTPBasicAuth

# Constants
XWIKI_URL = "redacted"
XWIKI_USERNAME = "redacted"
XWIKI_PASSWORD = "redacted"

def fetch_xwiki_page(url, username, password):
    # Send a GET request to the XWiki instance with Basic Authentication
    response = requests.get(url, auth=HTTPBasicAuth(username, password))
    
    # Store response headers and content
    response_headers = response.headers
    response_content = response.text
    
    return response_headers, response_content

# Main execution
if __name__ == "__main__":
    headers, content = fetch_xwiki_page(XWIKI_URL, XWIKI_USERNAME, XWIKI_PASSWORD)
    
    # Print the results for verification
    print("Response Headers:")
    print(headers)
    
    print("\nResponse Content:")
    print(content)