Why MTLS validation works on CURL, Axios with node.js but not on Axios with React on the browser?

19 Views Asked by At

I have created a block rule in the Cloudfare WAF using a client certificate in order to have identified requests. Now I need to have this certificate loaded in all requests that passes through my Cloudfare WAF. I know it is difficult to secure the certificate file and key on the frontend browser but I will address this later.

Everything works fine if I load the cert and key on the request either using CURL, python or node.js but if fails when I try to make a request using Axios on react from the Web Browser.

Example with curl(copied from the browser and added the --cert and --key):

curl 'myapi.com' \
  --cert cert.crt \
  --key cert.key \
  -H 'authority: myapi.com' \
  -H 'accept: application/json, text/plain, */*' \
  -H 'accept-language: en-US,en' \
  -H 'origin: http://localhost:3000' \
  -H 'referer: http://localhost:3000/' \
  -H 'sec-ch-ua: "Not A(Brand";v="99", "Brave";v="121", "Chromium";v="121"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "macOS"' \
  -H 'sec-fetch-dest: empty' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-site: cross-site' \
  -H 'sec-gpc: 1' \
  -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36' \
  --compressed

Example with node.js:

const crtCertificate = 'cert.crt';
const keyCertificate = 'cert.key';

const fs = require('fs');
const https = require('https');

const httpsAgent = new https.Agent({
    cert: fs.readFileSync(crtCertificate),
    key: fs.readFileSync(keyCertificate),
});


const options = {
    url: apiUrl,
    method: 'GET',
    httpsAgent: httpsAgent,
};

const fetchData = async () => {
    try {
        const axiosResponse = await axios(options);
        console.log(axiosResponse.data);
    } catch (error) {
        console.error(error);
    }
};

fetchData();

Example with React on the browser(being blocked by the WAF rule):

const options = {
    url: url.toString(),
    method: init?.method,
    headers: {
      ['Content-Type']: 'application/json',
    },
    httpsAgent: {
      cert: crtCertificate,
      key: keyCertificate,
    },
    data: init?.body,
};
const axiosResponse = await axios(options).then(async (response) => {
    return response.data;
});

-> It is important to mention that I also tried passing the certificate chain on the "ca" argument. I used the CA chain from https://curl.se .

0

There are 0 best solutions below