Intro to Whitebox Pentesting  

Code Review - Services

Now that we have covered the /api/auth API endpoints and functions, we can check the /api/service ones found in routes/service-routes.js:

const router = express.Router();

router.use(verifyToken);
router.post("/generate", generateQR);

module.exports = router;

We see that it has a single POST endpoint, which is /generate. We also see that this endpoint requires authentication since the verifyToken function is used before it, as discussed in the previous section. So, let's take a close look at generateQR.


generateQR

The controllers/service-controllers.js file only contains two functions:

  1. validateString
  2. generateQR

We can CMD/CTRL click on validateString to preview its usage, and we see that it is only used once within the generateQR function, so let's review its code.

We see that it starts by obtaining the text parameter from the POST request body and then gets the role parameter from req.user:

const { text } = req.body;
const role = req.user?.role;

We know that req.user gets assigned from the authentication token based on the user's email, as previously discussed. After that, the endpoint runs the validateString function while passing both the text and roles parameters.

Finally, it runs QRCode.toDataURL from the imported qrcode package at the beginning of the file. We can hover the cursor over this function to read its documentation "since it is an external package", and we see that it Returns a Data URI containing a representation of the QR Code image.

Typically, manually testing external packages is outside the scope of a whitebox pentest exercise, besides checking them for public vulnerabilities, which we can do with the npm audit command, as we will see later.

So, this endpoint appears to turn the text from the user input into a QR code. This leaves the validateString function, so let's take a closer look at it.

validateString

The function is relatively short and concise:

function validateString(input, onError) {
  if (
    typeof input !== "string" ||
    input.length == 0 ||
    input.match(/['"`;]/g)
  ) {
    eval(onError);
    return false;
  }
  return true;
}

It takes two parameters: input and onError. Then, it runs an if statement to indicate whether the string is valid or not. The if statement checks the following:

  1. if the input is not a string (e.g. a number or object)
  2. if the input length is 0
  3. if the input matches the specified regular expression pattern

If none of the above conditions is met, then the string is considered valid and true is returned by the function. The first two conditions are clear, but let's ask AI to explain the regular expression for us:

GitHub Copilot tells us it searches for instances of the characters ', ", `, or ;. This is a filter against exploitations to avoid running the user input into the QR code generator if it contains bad characters. If the code violates any of the conditions, false is returned by the function, and the onError string is run through eval:

eval(onError);
return false;

It is not uncommon to see JavaScript functions or code passed as a parameter to another function. However, running any string through eval may be dangerous, so we can shortlist this function for further testing.


Prioritization and Target Selection

So, after going through the different API endpoints, we have shortlisted only one interesting function that may be vulnerable. In addition to that, we need to check the external packages for public vulnerabilities.

This is normal, as we are dealing with a relatively small code base, so we do not expect to find many interesting findings. However, if we were dealing with larger code bases, we can expect to keep shortlisting interesting functions repeatedly, as demonstrated in other modules in Academy.

In the next section, we will start the local testing step to test the above two findings and will see where this leads us.

/ 1 spawns left

Waiting to start...

Optional Exercises

Challenge your understanding of the Module content and answer the optional question(s) below. These are considered supplementary content and are not required to complete the Module. You can reveal the answer at any time to check your work.

Previous

+10 Streak pts

Next