As a countermeasure to prevent Cross-Site Request Forgeries (CSRF), the Ardexa API requires a CSRF token be submitted with any request that modifies data, e.g. POST.
Two cookies are provided by the API for any request: connect.sid and XSRF-TOKEN. The CSRF token, XSRF-TOKEN, must be passed as an HTTP header, X-XSRF-TOKEN, for any POST, PUT or DELETE operation.
Usage
Here are three examples of fetching and using a CSRF token in Linux shell, Javascript and Python. All three are command line tool that read the TOKEN from the environment and take two arguments: the workgroup ID and the name of the new device, e.g.
#!/bin/sh
# $TOKEN is imported from the environment, it is the API token
ardexa_cloud=app.ardexa.com
arch="Linux 64 bit (x86_64)"
workgroup_id=$1
device_name=$2
# Needs an XSRF token to use POST
xsrf_token=$(curl -s --cookie-jar /tmp/ardexa-cookie.txt -i https://$ardexa_cloud/api/v1/version | grep '^set-cookie: XSRF-TOKEN' | sed -e 's/.*TOKEN=\([^;]*\).*/\1/' -e 's/%2f/\//gi' -e 's/%2b/+/gi' -e 's/%3d/=/gi')
# Create the agent
curl -s -H "X-XSRF-TOKEN: $xsrf_token" -H "authorization: Bearer $TOKEN" -H "content-type: application/json" --cookie /tmp/ardexa-cookie.txt -X POST --output /tmp/agent-sh.zip "https://$ardexa_cloud/api/v1/devices/$workgroup_id" -d "{\"name\": \"$device_name\", \"arch\": \"$arch\"}"
echo "Agent zip file can be found at /tmp/agent-sh.zip"
Javascript
import { writeFileSync } from 'node:fs';
import got from 'got';
import {CookieJar} from 'tough-cookie';
const ardexaCloud = 'app.ardexa.com'
const arch = 'Linux 64 bit (x86_64)'
const workgroupId = process.argv[2]
const deviceName = process.argv[3]
function getXsrf (cookieJar) {
const cookies = cookieJar.getCookiesSync(`https://${ardexaCloud}`)
for (const cookie of cookies) {
if (cookie.key === 'XSRF-TOKEN') return decodeURIComponent(cookie.value)
}
throw new Error('Failed to find XSRF token')
}
async function main () {
const cookieJar = new CookieJar();
const client = got.extend({ cookieJar });
await client.get(`https://${ardexaCloud}/api/v1/version`);
const xsrf = getXsrf(cookieJar)
const res = await client.post(`https://${ardexaCloud}/api/v1/devices/${workgroupId}`, {
headers: {
'X-XSRF-TOKEN': xsrf,
authorization: `bearer ${process.env.TOKEN}`
},
json: {
name: deviceName,
arch
}
});
writeFileSync('/tmp/agent-js.zip', res.rawBody)
console.log('Agent zip file can be found at /tmp/agent-js.zip')
}
main()
Python
import sys
import os
import requests
ardexa_cloud = 'app.ardexa.com'
arch = 'Linux 64 bit (x86_64)'
workgroup_id = sys.argv[1]
device_name = sys.argv[2]
s = requests.Session()
s.get(f'https://{ardexa_cloud}/api/v1/version');
xsrf = requests.utils.unquote(s.cookies.get_dict().get('XSRF-TOKEN'))
headers = {
'X-XSRF-TOKEN': xsrf,
'authorization': f'bearer {os.environ["TOKEN"]}'
}
json = {
'name': device_name,
'arch': arch
}
r = s.post(f'https://{ardexa_cloud}/api/v1/devices/{workgroup_id}', headers=headers, json=json)
with open('/tmp/agent-py.zip', 'wb') as f:
f.write(r.content)
print('Agent zip file can be found at /tmp/agent-py.zip')