Skip to content

Another Year, Another Hack of an Unmaintained Website

Posted on:January 1, 2026 at 01:00 PM

I got an email from Google Search Console on 19th December 2025.

New owner for https://nourlwasavailable.com/

To: Owner of nourlwasavailable.com,

Google has identified that …@gmail.com has been added as an owner of https://nourlwasavailable.com/.

Property owners can change critical settings that affect how Google Search interacts with your site. It’s important that only people who need this level of access have owner status. Be sure to revoke this role when it’s no longer needed.

Okay, I lied. It was actually a series of 3 emails adding 3 different emails as co-owners for my domain. It was obviously not intended and someone was trying to hack my website. So, I did the sane thing any person would do: I went to my Google Search Console and checked my users and permissions settings.

I don’t see anyone other than me.

I went to the Activity page to see if there’s been any history. If someone added and removed themselves immediately, maybe they could’ve done something in the meantime. I still saw nothing.

Okay, maybe it was a false alarm.

Still, I wrote a forum question asking about the emails I got, describing the fact that I didn’t see any unusual activity.

Fast forward to a few days later, to the 31st of December. I got another email from Google Search Console, saying that social engineering content was detected on my website.

I obviously didn’t have any social engineering content intended to be on my blog, so I typed in my url in the address bar and pressed enter. To my surprise, I did not see my usual “A blog about a human being”. I saw what was obviously a scam website, a website designed to look like an online betting platform.

Oh, no.

I immediately remembered the forum post I had made, and thankfully saw a reply. It pointed me to the fact that on Google Search Console, your dashboards for the below two URLs are separated:

  1. https://www.nourlwasavailable.com
  2. https://nourlwasavailable.com

Seriously? I understand that subdomains are treated separately, but if my subdomain is the explicit lack of a subdomain, I feel like that’s a little confusing.

Anyway, went to the search console, added a new sub-property, and voila: there were the three random people registered as co-owners of my “sub”domain.

Fixing the Issue

As with tech problems are, when these things happen, you need to first find a way to fix it and have the normal website running before you figure out what went wrong (which is obviously the fact that I didn’t touch the website since August of 2023 and considering the sheer amount of zero-day vulnerabilities we’ve seen on the web world in the last two years).

I quickly went to my repository, looked at my commit history, (expectedly, there was nothing wrong with it) and cloned it to my computer. Quickly ran pnpm install, and pnpm update. Builds were failing, so I did pnpm approve-builds as pnpm kindly told me to. I pushed it, and GitHub wouldn’t deploy my website.

Turns out that I was using outdated versions of github action workflows. I was using actions/checkout@v3 and withastro/action@v0 when the latest recommended actions for astro were actions/checkout@v6 and withastro/actions@v5. Even actions/checkout@v4 was outdated and no longer supported by GitHub…

Okay, easy fix.

I updated the action versions and pushed them to origin.

It still wouldn’t deploy. This time, as it turns out, my GitHub Education had run out. Then, I had trouble getting the automated system to recognize my letter of enrollment, so I did what I had been too lazy to do for the last few months: move my website to Cloudflare.

I logged in to my Cloudflare account that I made 6 months ago when I first wanted to move my website, moved my DNS records from Squarespace, and set up a Cloudflare Page. It was a little complicated since Cloudflare Workers and Pages were created with the same button, and I ended up accidentally making a worker instead of a page when I first did it.

A screenshot of the Create a Worker page
A screenshot of the Create a Worker page

I eventually figured out that there was a small button to deploy a static webpage instead of a worker, and the process went smoothly after that. Visiting https://nourlwasavailable.com was correctly showing my blog again. I turned on all the security related feature buttons I saw on the Cloudflare Domains page and moved on to figuring out what had happened.

So… What Happened?

I checked logs everywhere that I thought was relevant.

  1. Repository: I was pretty sure there couldn’t have been anything there. It’s a private repo, my commit history is just me, and after all, I just cloned my repo from there.
  2. Domain Management: I checked the activity log for Squarespace where my domain was being managed, and I couldn’t see any activity in the past 90 days except for the domain transfer I just made to Cloudflare.
  3. Google Account: 2FA enabled, no suspicious logins.

If my code wasn’t changed, and my DNS wasn’t changed, how was Google serving a scam site to my visitors?

The smoking gun appeared in a dark corner of Google Search Console: “AMP Domain Mismatch.”

It showed that my domain was claiming to have an AMP version located at https://their-scam-site.com. That URL was the attacker’s site. I turned to good old generative AI to help me understand what was going on. I gave it all the information I thought was relevant and asked it to explain what could’ve possibly went down.

XSS Vulnerability

It turns out, you don’t even need to change a file on a server to deface a website. You just need to trick the browser.

I ran pnpm audit to find some high risk vulnerabilities. For example,

  1. devalue prototype pollution vulnerability

  2. Astro vulnerable to reflected XSS via the server islands feature

  3. Astro’s X-Forwarded-Host is reflected without validation

  4. Astro vulnerable to URL manipulation via headers, leading to middleware and CVE-2025-61925 bypass

and a few more that mention possible XSS attacks, middleware bypass, etc.

It’s possible that any or many of these were targeted and used to show essentially whatever the attackers wanted on my domain when searched through Google.

It probably went something like this:

  1. Attackers used bots to scan for sites running old versions of Astro (or any of these vulnerabilities that they can detect). They found mine.
  2. They crafted a special URL for my site that looked something like this: https://nourlwasavailable.com/#<malicious_payload>. They then tricked Google’s crawler into visiting this specific URL.
  3. When Googlebot visited that link, my outdated JavaScript read that payload from the URL and, because it lacked proper security checks, blindly executed it. It dynamically injected a new line of code into the page’s <head> right inside Googlebot’s browser: <link rel="amphtml" href="https://their-scam-site.com">
  4. My site effectively told Google, “Hey, I have a faster mobile version, and it’s located over here at this scam URL.”
  5. Google, wanting to serve the best experience to mobile users, trusted my site. When mobile users searched for me, Google sent them to the scam AMP page instead of my real site.

Update Your Dependencies

All I had to do now was to upgrade, not just update, my dependencies and hopefully everything was good to go and also pray that nothing breaks.

I ran:

> pnpm dlx @astrojs/upgrade
... astro upgrade stuff

and prayed before running:

> pnpm run build
...
PASS 2 - Compressing the rest
 37 files | 822.63 KB 691.32 KB | -131.31 KB
Done: 132.797ms

 Summary
╔════════╤════════════╤═══════════╤════════════╤════════════╗
 Action Compressed  Original Compressed       Gain
╟────────┼────────────┼───────────┼────────────┼────────────╢
 .css      1 / 1  40.57 KB   38.30 KB   -2.27 KB
 .js      4 / 5 185.14 KB  183.66 KB   -1.48 KB
 .svg      5 / 5  52.51 KB   36.77 KB  -15.74 KB
 .png      5 / 5  87.70 KB   48.63 KB  -39.07 KB
 .webp      1 / 1  26.68 KB   25.27 KB   -1.40 KB
 .jpg      2 / 2 210.32 KB  144.09 KB  -66.23 KB
 .html    13 / 13 217.52 KB  212.40 KB   -5.12 KB
 .txt      0 / 1  127.00 B   127.00 B
 .xml      0 / 3   2.06 KB    2.06 KB
╟────────┼────────────┼───────────┼────────────┼────────────╢
 Total    31 / 37 822.63 KB  691.32 KB -131.31 KB
╚════════╧════════════╧═══════════╧════════════╧════════════╝


 No issues

yay

I looked around the built website a little to make sure that nothing seemed visibly broken, and pushed to origin to see if the CI/CD pipeline was functional… and everything worked fine.

So, that’s how I’ve spent the 31st of December 2025, welcoming the new year by embracing up-to-date packages that hopefully won’t get my website hacked, at least until the next time I touch this repository, which I’ll try to do more by writing more blogposts in the year 2026.

Happy new year!

</2025>