DemonMartin / tlsClient

A wrapper for bogdanfinn/tls-client based on ffi-rs for unparalleled performance and usability. Inspired by @dryft/tlsclient.
https://www.npmjs.com/package/tlsclientwrapper
22 stars 2 forks source link

param order possibly tampered by tls client? #2

Closed caspianite closed 5 months ago

caspianite commented 5 months ago

hello i've noticed that with stock axios the params / query strings are sent exactly as the URLSearchParams object gives, but that with tls client, it seems to: 1) use its own param order 2) remove duplicate param strings

here is the function i use for reordering search params

reorderSearchParams(searchParams, paramsOrder) {
  const orderedParams = new URLSearchParams();
  const allKeys = Array.from(searchParams.keys());
  const keySet = new Set(allKeys);
  // Add parameters in the specified order first, including duplicates
  for (const key of paramsOrder) {
    if (keySet.has(key)) {
      const values = searchParams.getAll(key);
      values.forEach(value => orderedParams.append(key, value));
      // Remove the key from allKeys after processing to handle duplicates correctly
      allKeys.splice(allKeys.indexOf(key), 1);
    }
  }
  // Add any remaining parameters that were not included in paramsOrder
  allKeys.forEach(key => {
    const values = searchParams.getAll(key);
    values.forEach(value => orderedParams.append(key, value));
  });
  return orderedParams;
}
DemonMartin commented 5 months ago

Hey @caspianite !

First, I'd like to clarify that the tlsClientWrapper is only meant to make the usage of the tlsClient Libs provided by @bogdanfinn easier and does not actually tamper with any of the Setting Parameters actually sent to the Lib. As seen here: https://github.com/DemonMartin/tlsClient/blob/d5e600a72db5f3a7a0608fb72d070fb1377378fd/index.js#L159

Therefore, tlsClientWrapper is not meant to be similar to Axios (like @dryft 's TlsClient tries to, if I understood correctly).

Based on my testing using an Echo API, the Query Params are exactly sent as specified, here's my testing code:

import stlsClient from "tlsclientwrapper";
async function oneRequest() {
    const tlsClient = new stlsClient();
    const requestStart = performance.now();
    const request = await tlsClient.get("https://echo.zuplo.io/?first_param=yes&second_param=true&third_param=agreed");
    const responseData = JSON.parse(request.body);
    console.log(responseData);
    const requestEnd = performance.now();
    console.log(`Request took ${requestEnd - requestStart} ms`);
    tlsClient.terminate();
}

(async () => {
    await oneRequest();
})();

Which responds with:

{
  url: 'https://echo.zuplo.io/?first_param=yes&second_param=true&third_param=agreed',
  method: 'GET',
  query: { first_param: 'yes', second_param: 'true', third_param: 'agreed' },
  headers: {
    'accept-encoding': 'gzip, br',
    connection: 'Keep-Alive',
    host: 'echo.zuplo.io',
    'true-client-ip': 'REDACTED',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'x-forwarded-proto': 'https',
    'x-real-ip': 'REDACTED',
    'zp-rid': 'REDACTED'
  }
}

The only issue that might arise, which I couldn't reproduce, is if you use an instance of a URL object instead of a string as the parameter for any of the functions. This is because the URL object is converted into a string using .toString(). As seen here: https://github.com/DemonMartin/tlsClient/blob/d5e600a72db5f3a7a0608fb72d070fb1377378fd/index.js#L114-L117

Therefore, I will close this Issue as it seems like it's not related to the tlsClientWrapper, and I wasn't able to reproduce the issue too.

caspianite commented 5 months ago

Got it, I will test the .tostring hypothesis, thanks