Lab Exercise input1

This is a lab exercise on developing secure software. For more information, see the introduction to the labs.

Goal

Practice validating input of a simple data type.

Background

In this exercise, we'll add some simple input validation to a server-side program written in JavaScript using the Express framework (version 4) and the express-validator library. The point isn't to learn about these specific technologies; the point is to learn how to write secure software in general.

Express allows us to state that when the system receives a specific request, it will run a list of functions ("handlers"). The library express-validator provides a set of validation functions to make it easy to add validation checks.

The code below sets up handlers for a get request on path /invoices. If there are no validation errors, the code is supposed to show the invoice id. If there is a validation error, it responds with HTTP error code 422 ("Unprocessable Content"), a status code suggesting that the request was invalid for some reason, along with an error message.

Unfortunately, this program doesn't do proper input validation. In this application id is supposed to only be an integer between 1 and 9999 (including those numbers). As written below it fails to make that check. In fact, as written, this program has a vulnerability we haven't discussed yet called Cross-site Scripting (XSS). Because of this XSS vulnerability, an attacker could provide malicious scripts in id which the viewer would automatically run! This particular vulnerability would be entirely prevented if we did better input validation.

Task Information

To complete this task:

  1. After the first parameter to app.get which says '/invoices', add a new comma-separated parameter.
  2. Start this new parameter with query('id') to select the id parameter for validation (we've filled in this part to help get you started).
  3. After query('id') (and before the terminating comma), add a period (.) and the validation requirement isInt() (isInt validates that the named parameter is an integer).
  4. The isInt method takes, as an optional parameter inside its parentheses, an object providing a minimum and maximum, e.g., isInt({min: YOUR_MINIMUM, max: YOUR_MAXIMUM}). Set min and max to specify the allowed range.

Note: JavaScript names are case-sensitive, so isint won't work. Remember to indicate the end of this parameter with a comma (our starter text does this).

Use the “hint” and “give up” buttons if necessary.

Interactive Lab ()

The code below accepts the query parameter id as input. Please change it so id is only accepted if it is an integer between 1 and 9999 (including those numbers).

// Set up Express framework and express-validator library
const express = require("express");
const app = express();
const { query, matchedData, validationResult } =
    require('express-validator');

// Implement requests, e.g., http://localhost:3000/invoices?id=1
app.get('/invoices',

  (req, res) => { // Execute this code if /invoices seen
    const result = validationResult(req); // Retrieve errors
    if (result.isEmpty()) { // No errors
      const data = matchedData(req); // Retrieve matching data
      return res.send(`You requested invoice id ${data.id}!`);
    }
    res.status(422).send(`Invalid input`);
  })


This lab was developed by David A. Wheeler at The Linux Foundation.