Skip to main content

Student worksheet: Whose record is this?

Your mission: allow Alex to read Alex's record, but not Sam's. You will change one line in one supplied file. You do not have to build a server, design a website or implement login.

Use only the supplied local app and fictional data. Read safety first. Record your observations in the submission template.

1. Start the supplied app: about 10 minutes​

You need Node.js 22 or newer, a browser and a plain-text editor such as VS Code. Ask your instructor for help installing Node before the lesson if needed.

Choose your folder:

What you downloadedOpen this folder in your editor
Complete classroom repositoryexercises/05-broken-access-control/student
Student-only kitapp inside the extracted kit

Open the editor's terminal in that folder. In VS Code, open the folder first, then choose Terminal → New Terminal. A terminal accepts typed commands; press Enter after each command. You should see server.mjs and authorize.mjs in the editor's file list.

node --version
node server.mjs

The first command prints your Node version. The second starts the supplied program and prints the local URL. Open http://127.0.0.1:3000 in your browser. Keep the terminal open; it is running your server. You do not need npm install or an internet connection once Node and the exercise are present.

Checkpoint: you can see the CVE Lite Classroom portal. If not, use the troubleshooting section below before continuing.

2. Understand the two sides: about 10 minutes​

  • Browser: the page and buttons you see. It asks for a record.
  • Server: the program you started with Node. It receives the request, decides whether it is allowed, and sends a response.
  • Request: a question from the browser, such as “may I see record 101?”
  • Response: the server's answer: a record or an error message.
  • Record ID: a label identifying a record. It is not a password or permission.
  • Authentication: establishing who a user is. This practice server already supplies the fictional identity Alex; you are not building authentication.
  • Authorization: deciding what that user is allowed to do. This is what you will fix.

Both browser and server run on your computer. 127.0.0.1 means your own computer, not a public website. The page is a teaching app, not your university's real portal.

Our rule is simple: a student may read only records they own.

3. Observe the problem: about 10 minutes​

In the portal's record request panel:

  1. Request 101. It belongs to Alex, the current demonstration user. Seeing this record is correct.
  2. Change the record ID to 102 and request it. It belongs to Sam. The starter incorrectly returns it even though you are still Alex.
  3. Record what the server returned for each ID. You have permission to test these fictional records only in this lab.

The record ID changed; the user's identity did not. That is the problem. Do not “repair” it by removing the request box or hiding a button. A different browser or program could still send the same request to the server.

The request display shows something like GET /api/records/102. GET means “read”; the rest is the server's address for the requested record. You do not need to memorize it or write request code; the form does that for you. The response's Owner ID identifies the student who owns that record; it is different from the record's own ID.

4. Learn the small amount of JavaScript you need: about 10 minutes​

Open authorize.mjs in your editor. Do not edit the other files.

This file contains a function, a small named piece of code. The server calls canReadRecord(user, record) before returning a record. It supplies two objects, which group related values:

// Example values to read, not additional code to paste:
const user = { id: 'student-1' };
const record = { ownerId: 'student-1' };

user.id means “the id value inside user.” record.ownerId means “the ownerId value inside record.” The dot selects a value. === asks whether two values are exactly equal. return gives the function's answer back to the server: true means allow; false means deny.

For example, 'blue' === 'blue' is true, and 'blue' === 'green' is false.

The starter returns true for every record. It never compares the owner with the user. The surrounding export function line makes the function available to the supplied server; keep that line unchanged.

5. Repair the permission decision: about 10 minutes​

Replace the function in authorize.mjs with the scaffold below and fill the one blank:

export function canReadRecord(user, record) {
return record.ownerId === ____;
}

Hint: compare the record's owner with the current user's id, using the dot notation explained above. Do not put quotation marks around the expression. You must fill in the blank; ____ is not valid finished code for this exercise.

Save the file. In the terminal running the server, press Ctrl+C, then run this again from the same folder:

node server.mjs

Refresh the browser page. Saving and refreshing alone will not restart the server's JavaScript; you must stop and restart it.

6. Prove the repair: about 15 minutes​

Repeat both requests:

RequestRequired result after repair
101: Alex's recordAllowed; Alex's record is shown.
102: Sam's recordDenied; Sam's record contents are not shown.
999: no such recordNot found; no record contents.
abc: not a valid IDInvalid request; no record contents.

An HTTP status is the number describing the response. Here, 200 means success, 403 means forbidden, 404 means not found and 400 means an invalid request. Seeing 403 for Sam after your repair is a success, not a broken app.

Stop the server with Ctrl+C. From the same student/app folder, run:

node checks.mjs

This starts a temporary server, tests it and stops it automatically. Read the PASS/FAIL explanations. The starter has intentional security failures; the repaired app should pass all checks. The checker uses your saved code, so save first. To use the browser again afterward, run node server.mjs again.

Blocking every record is not a correct repair: Alex must still be able to read record 101.

7. Explain what changed: about 10 minutes​

Complete the submission template. Explain the difference between an ID and permission, why the server must enforce the rule, and how you verified that the fix did not block legitimate access. Submit your edited authorize.mjs and observations. The guided route can earn full credit.

Troubleshooting​

SymptomWhat to do
node is not recognized / command not foundAsk your instructor to install or enable Node 22 or newer, then reopen your terminal.
Cannot find server.mjsYour terminal is in the wrong folder. Open the student folder (repository) or app folder (kit) in the editor, then open a new terminal there.
Port 3000 is already in useStop your earlier copy with Ctrl+C. If another program owns the port, ask your instructor; do not terminate unfamiliar processes.
Browser cannot connectKeep node server.mjs running and use the exact printed http://127.0.0.1:3000 address, not HTTPS or a file opened by double-clicking.
Syntax error or ____ is not definedCheck brackets, fill the blank and save authorize.mjs. Check that your editor did not add .txt to the filename. Restart the server.
I still see Sam's record after editingConfirm you saved the correct app's file, stopped and restarted that server, refreshed, then made a new request for 102.
Alex is denied tooDo not return false for every request. Compare owner and user values, then retest both cases.

Optional discussion: not needed for full credit​

What changes if teachers are allowed to read their students' records? Why would changing IDs to long random strings not replace this check? Why should a production app obtain identity from a verified session rather than a user-editable request field? Discuss these questions; do not build those features for this exercise.

Screenshot preview