Disallowing path manipulation attempt

Hello,
We recently bumped dependencies and are getting this error in our staging env.
I tried to find anything on the topic but could not.
Any help where to start would really be appreciated.

Something went wrong
Trace ID: 000000000000000099c90818591d36d8
There was an error invoking the function - Disallowing path manipulation attempt

Error: Disallowing path manipulation attempt
    at escapeParameter (/tmp/tunnel-7-aJnqlPs5QVHp/ProtectedFieldHandler.js:740:23)
    at route (/tmp/tunnel-7-aJnqlPs5QVHp/ProtectedFieldHandler.js:767:19)
    at _callee$ (/tmp/tunnel-7-aJnqlPs5QVHp/ProtectedFieldHandler.js:56679:75)
    at tryCatch (/tmp/tunnel-7-aJnqlPs5QVHp/ProtectedFieldHandler.js:56666:1062)
    at Generator.<anonymous> (/tmp/tunnel-7-aJnqlPs5QVHp/ProtectedFieldHandler.js:56666:3012)
    at Generator.next (/tmp/tunnel-7-aJnqlPs5QVHp/ProtectedFieldHandler.js:56666:1699)
    at asyncGeneratorStep (/tmp/tunnel-7-aJnqlPs5QVHp/ProtectedFieldHandler.js:56668:103)
    at _next (/tmp/tunnel-7-aJnqlPs5QVHp/ProtectedFieldHandler.js:56669:194)
    at /tmp/tunnel-7-aJnqlPs5QVHp/ProtectedFieldHandler.js:56669:364
    at new Promise (<anonymous>)

We simply get data using this small code:

const getDataFromJira = async (url) => {
  try {
    const response = await api.asUser().requestJira(route`${url}`);
    return await response.json();
  } catch (error) {
    console.log("getDataFromJira error: ", error);
    throw error;
  }
};

Can you tell us what is in the url variable you’re sending into the route function?

The route function is meant to be used at the point where you are constructing the URL from its parts, incorporating the user input into it. For example:

const url = route`/rest/api/3/issue/${issueKey}`;
await api.asUser().requestJira(url);

Instead of:

const url_bad = `/rest/api/3/issue/${issueKey}`;  // bad
await api.asUser().requestJira(route`${url_bad}`);

When route is called, it can check for possible path manipulation attempts (e.g. issueKey coming from the user as ../../../evil_api_call) and escape or block them properly.

If URL is constructed separately, route has no way of knowing which parts might have been manipulated by the user, so it might throw this error as a false positive.

I suggest rewriting your getDataFromJira function to accept the result of calling route, and move the route wherever the URLs are being constructed.

3 Likes

Thanks a lot for the answer, that was the problem, this seems to been allowed before but checking the change log, there has been some updates around this CWE. Great answer!

Above solution is not working for me. Any other solutions?

Sorry to hear that. Can you please show your code and what is happening?

Yeah sure. thanks for the reply

Defining resolver at the backend part

resolver.define("MAKE_API", async (req) => {
    const { url, method, body } = req?.payload;
    const options = {
        method: method,
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
        },
        body: JSON.stringify(body)
    }
    const apiUrl = route`${url}`
    const response = await api?.asUser()?.requestJira(apiUrl, options);
    const data = await response?.json();
    return data ? data : [];
})

Below is the code where i am invoking the resolver from frontend side

const GET_CURRENT_USER = async () => {
  const result = await invoke('GET_INFO', { key: '__info' })
  const response = await invoke('MAKE_API', {
    url: `${USER}?accountId=${result?.user?.id}`,     // Here USER = '/rest/api/3/user'
    method: 'GET',
    body: undefined
  })
  return response
}

@GaneshXDev First of all, you don’t need to use invoke for this code as you can call requestJira from the frontend directly.

If you have more involved logic, please follow the advice above:

  • Only pass the necessary information to the backend (in your case result.user.id).
  • Construct only the endpoint you actually need on the backend, starting with /rest/api/3/user.

Otherwise a malicious user can manipulate the url into an entirely different call with unintended effects.

1 Like

Thanks @AlexeyKotlyarov , Better I will go with requestJira from frontend side.