---
title: "I Invented 14 People to Break My University Website"
description: "A plain-language story about testing a university admissions website with fourteen imaginary people, from a careless applicant to a would-be hacker, and the real bugs they found that I never would have."
author: "Syed Ahmer Shah"
date: 2026-10-30
url: https://ahmershah.dev/blogs/i-invented-14-people-to-break-my-university-website
tags: ["ait", "testing", "playwright", "web-security", "qa", "engineering-logs"]
series: "The Engineering Logs" (part 20)
---

# I Invented 14 People to Break My University Website

_A careless applicant, an impatient one, a sneaky one and an actual attacker walk into an admissions office. Here's what they broke._

![The AIT registration page with its quick security check, under the title I invented 14 people to break my university website](https://ahmershah.dev/blog/i-invented-14-people-to-break-my-university-website/cover-dc021d88.webp)


For about two months I was sure my website worked. I had clicked through it a hundred times. I'd register as an applicant, fill in the form, upload a photo, sign in as the admin, approve myself, and sign back in as a brand new student. Everything went green. Every time.

The website is AIT, short for Ahmer Institute of Technology: a made-up university with a real admissions system behind it. Students apply online and upload documents. Admins review and approve them. Teachers take attendance and enter marks. I built it after an internship where I worked on a portal like this one, and I wrote up the technical side in the [AIT case study](/blogs/ait-case-study-university-admissions-portal).

The problem with my hundred clicks was that I was always the same person. I knew where every button was. I never typed my password wrong. I never pressed submit twice. Real people do all of that, and some of them do worse on purpose.

So I invented fourteen of them.

## Meet the cast

Each one is a short script that drives a real web browser, clicking and typing the way a person would. They go through one full admissions season together, in order, and if any of them hits something unexpected, the test fails and tells me where.

Ayesha is a visitor. She reads all fourteen public pages, opens the menu on her phone, and checks that every page has a sensible title and nothing broken.

Bilal is a parent with a question. He uses the contact form like a normal person, and then the test tries it the way a spam bot would: too fast, and with a hidden field filled in that no human can see. The bot version gets refused.

Hamza is the applicant everyone has met. He gets every field on the registration form wrong at least once. Then he forgets his password and keeps guessing.

Sara is the good student. She applies, gets admitted, chooses her own password and sees her classes, marks and announcements. If Sara can't get through, nobody can.

Rabia is impatient. Her internet is slow, so she presses "Submit" three times at once.

Zainab is sneaky. She uploads a program pretending to be a photo, and a PDF with hidden code inside it.

Usman gets rejected and needs to see why.

Then there's the staff. Imran is the head admin. Nadia and Omar are assistant admins who are each allowed to do only one job. Kamran is a new teacher. Farah is a Head of Department. Ali works in security and shouldn't see department records at all.

And then there's Eve. Eve is an attacker. She tries to read other people's files, trick the site into running her code, guess passwords and get into pages she has no business seeing.

![The AIT registration form with name, CNIC, date of birth and password fields and a quick security check asking what 3 plus 9 is](/blog/i-invented-14-people-to-break-my-university-website/1ec9d2188a.webp)

## Hamza found the first bug in about a minute

Hamza's job was simple: get his password wrong five times and get locked out for a while. That's a basic protection. Without it, a bot can try thousands of passwords until one works.

He didn't get locked out. He could keep guessing forever.

The lockout code looked fine. It saved the time when the lock should end, and checked it on every sign-in. The trouble was the clock. The database thought it was one time, and the website code thought it was another, five hours apart. So every lock was saved as already expired. On my laptop, where both happened to agree, it worked. In the Docker setup, which is closer to a real server, it never did.

I would never have found that by clicking around, because I never typed my own password wrong five times.

While fixing the sign-in page I found a second one hiding behind it. Admitted students who typed the correct password were having it counted as a failed attempt. A careful student could lock themselves out just by signing in a few times.

## Sara couldn't even get to her dashboard

This one was embarrassing. After an applicant signed in, the site sent them to a page address that didn't exist. Every single applicant landed on a "page not found" screen.

How did I miss that? Because when I tested, I was already signed in from earlier and went straight to the right page. Sara started from nothing, the way a real person would.

When Sara was finally admitted, she had no classes. Approval gave her a student ID, but never actually enrolled her in her first-semester subjects. Her timetable was empty, and Kamran's class list was empty too. Some approved students were even put in departments that didn't exist.

## Rabia pressed submit three times

If you've ever pressed a button twice because a page was slow, you've done what Rabia does. Her test sends three copies of the same application at the exact same moment.

The right answer is one application. The website now locks the record while it works on it, so the second and third copies wait, see the first one already finished, and stop. And the database itself refuses a second application for the same person in the same admission cycle, as a backstop. Rabia's test checks that exactly one application exists at the end. Not zero, not two.

## Zainab's fake photo

Zainab's "photo" is really a small program with a `.jpg` name. If a website saves that file somewhere public and someone then visits it, the server might run it. That's how a lot of sites get taken over.

AIT checks the first few bytes of every file, which give away what it really is no matter what it's called. Zainab's fake photo fails that check. Her PDF with hidden code inside gets rejected too. Even real photos are rebuilt from scratch before they're saved, so nothing can hide inside them, and they're stored where the public can't reach them.

![The admin applications queue: applicants with their CNIC, program choice, challan status and Approved, Applied or Rejected badges](/blog/i-invented-14-people-to-break-my-university-website/661cdd219b.webp)

## Kamran could mark anyone

Kamran is a teacher. He should only take attendance for students in the subjects he teaches. The test tried to make him mark a student from someone else's class.

It worked. The site checked that Kamran was a teacher, but not that the student was his. Any teacher could have changed anyone's attendance or marks. That's now fixed, and the test makes sure it stays fixed.

Nadia and Omar found the same kind of problem on the admin side. Some admin actions didn't check whether the assistant admin had permission for that job, and an assistant whose access had expired could still use a few pages.

![The teacher attendance page: a subject, a class date and a list of students with Present, Absent, Late and Excused options](/blog/i-invented-14-people-to-break-my-university-website/8761e1575a.webp)

## Eve tried everything

Eve's list is long. She changes numbers in web addresses to try to open other students' documents. She tries to download files by walking up folders. She submits forms from a fake website. She types code into name fields, hoping it runs when an admin views them. She guesses passwords. She asks for files that should never be public, like the site's settings.

Most of her attacks bounced off. Working through her list did turn up one real problem, though: a teacher's name was being dropped straight into a page in the admin panel. A teacher named with a bit of code could have run that code in the head admin's browser. It's an easy mistake to make and a bad one to leave in.

## The ones that made me laugh

Some bugs were just odd. The "what is 3 + 9" check on forms kept showing an old question after a mistake, so someone who fixed their form could never get past it. The pop-up windows on two admin tables were placed in a spot browsers don't allow, so the tables quietly fell apart. And about one in every 500 temporary passwords that the site made up for new students broke the site's own password rules, because it sometimes forgot to include a lowercase letter.

One in 500. I'd have needed to approve a few hundred students by hand to see it once.

## What I took away

Fifty-eight tests and fourteen people found more than a dozen real bugs in a website I was confident about. Not one of them showed up in my own clicking, because I always behaved like someone who built the site.

That's the part I keep coming back to. The bugs weren't in clever code. They were in the ordinary moments: a wrong password, a slow connection, a teacher clicking the wrong student, a clock set to a different time zone. You find those by pretending to be someone else, as many times as you can, and letting a computer do the pretending so you can do it again tomorrow.

All fourteen of them still run every time the code changes. The project and its tests are on [GitHub](https://github.com/ahmershahdev/Ahmer-Institute-of-Technology).


---

*Originally published at https://ahmershah.dev/blogs/i-invented-14-people-to-break-my-university-website — © Syed Ahmer Shah*
