← Back to Feed CACHED · 2026-06-30 00:15:36 · CACHE_KEY CVE-2026-13485
CVE-2026-13485 · CWE-74 · Disclosed 2026-06-28

A vulnerability was found in SourceCodester Class and Exam Timetabling System 1

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A free school-project PHP app dropped on GitHub with a textbook SQL injection, dressed up with a 7.3

SourceCodester's *Class and Exam Timetabling System* v1.0 is a free PHP/MySQL learning project distributed on sourcecodester.com — the kind of codebase students download to learn CRUD. CVE-2026-13485 is an unauthenticated SQL injection in /preview.php via the course_year_section parameter, which is concatenated directly into a query with no sanitization. The bug class is canonical CWE-89 (the CWE-74 label is the parent injection bucket). The same researcher set has filed near-identical SQLi CVEs against preview6.php, preview7.php, archive.php, and others in the same codebase (CVE-2026-13486, -13488, etc.) — the entire project is riddled with the same anti-pattern.

Vendor severity of 7.3 (HIGH) is a mechanical CVSS output, not a reflection of risk. The vector AV:N/AC:L/PR:N/UI:N is technically accurate — anyone who can reach the page can dump the DB — but the population that actually runs this software in production is a rounding error. There is no enterprise install base, no vendor patch pipeline, and no support contract. Treating this like an Oracle or SAP SQLi distorts the patch queue. The honest call is LOW: real, exploitable, public PoC, but blast radius bounded to a handful of student / hobbyist deployments.

"SourceCodester student-project SQLi in a free PHP timetabling demo — vendor 7.3 ignores that this isn't enterprise software."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Locate an exposed instance

Attacker fingerprints a deployed Class and Exam Timetabling System instance — typically via Google dork (inurl:preview.php course_year_section) or Shodan/FOFA HTML title match. The application has no telemetry; instances are usually on shared LAMP hosting or a lab VM.
Conditions required:
  • Instance is reachable from attacker's network position
  • Default PHP routing exposes /preview.php
Where this breaks in practice:
  • Effectively zero enterprise deployment footprint
  • Most installs are on localhost / classroom LAN, not internet-exposed
Detection/coverage: Shodan/Censys do not have a dedicated fingerprint; discovery is opportunistic via search engines.
STEP 02

Inject into course_year_section

Attacker issues GET /preview.php?course_year_section=1' UNION SELECT ...-- - using sqlmap (sqlmap -u 'http://target/preview.php?course_year_section=1' --dbs). The parameter is concatenated unsafely into a MySQL query, so UNION-based and boolean-based payloads both work. PoC is public on VulDB and GitHub issue trackers.
Conditions required:
  • No WAF in front of the app
  • MySQL backend with default error verbosity
Where this breaks in practice:
  • Any generic WAF (ModSecurity CRS, Cloudflare free tier) catches the canonical sqlmap signatures
  • Hosting providers commonly block UNION SELECT patterns at the edge
Detection/coverage: Trivial signature hit in any IDS/WAF — sqlmap user-agent and payload shape are well-known.
STEP 03

Exfiltrate schema and data

Attacker enumerates information_schema.tables, dumps user/account tables, and harvests credentials. If MySQL is running as a privileged account with FILE privilege and secure_file_priv is unset, sqlmap's --os-shell can write a PHP webshell into the docroot.
Conditions required:
  • DB user has SELECT on target tables (default in this app)
  • FILE privilege + writable webroot for shell upload
Where this breaks in practice:
  • Modern MySQL defaults restrict secure_file_priv, blocking file write
  • Shared hosting separates DB user from webroot ownership
Detection/coverage: Outbound large response sizes and INFORMATION_SCHEMA queries are detectable in MySQL general/slow logs if enabled.
STEP 04

Impact bounded to one tenant

Worst case: full read/write of the timetabling database (student names, schedules, faculty accounts) and potential webshell on the single host. There is no federation, no SSO integration, and no lateral pivot story baked into the product itself.
Conditions required:
  • Successful DB compromise from step 3
Where this breaks in practice:
  • No corporate identity integration to abuse
  • Database is single-app, single-host by design
Detection/coverage: Defacement / data dump usually surfaces only post-incident.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. No campaigns tracked. EPSS 0.00412 (≈0.4%) reflects negligible predicted exploitation.
Proof-of-conceptPublic PoC on VulDB and researcher GitHub issues (lffaker/cybersec, yan-124/yan). Trivial sqlmap one-liner.
EPSS0.00412 — bottom of the distribution. Realistic given the audience.
KEV statusNot listed. Will not be — CISA does not catalog SourceCodester student-project bugs.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L → 7.3 HIGH. CVSS v4.0 reassessed to 6.9 MEDIUM, closer to reality.
CWECWE-89 (SQL Injection) — parent label CWE-74 used in NVD entry. Classic concatenation flaw.
Affected versionsSourceCodester Class and Exam Timetabling System v1.0 (only published version). Codebase has sibling CVEs: -13484, -13486, -13487, -13488.
Fixed versionNone. SourceCodester does not maintain a patch pipeline for community-uploaded projects.
Exposure dataShodan/Censys: no meaningful fingerprintable footprint. Effectively zero enterprise install base.
Disclosure2026-06-28 via VulDB. Researcher credit per VulDB entry; coordinated only in the loosest sense.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.1/10)

Downgraded from vendor HIGH (7.3) to LOW because the decisive factor is installed-base reality: SourceCodester is a free PHP learning-project hosting site with no enterprise deployment footprint, no vendor patch pipeline, and effectively zero exposure in Shodan/Censys data. The bug is real and trivially exploitable, but it does not belong in an enterprise patch queue alongside vendor-supported software.

HIGH Exploitability is real and trivially weaponized
HIGH Negligible enterprise install base
MEDIUM No vendor will ship a patch — remediation is removal or fork-and-fix

Why this verdict

  • Installed base near zero in enterprise: SourceCodester is a free code-sample repository, not an enterprise product. If you don't run it (and you almost certainly don't), this CVE is noise.
  • Role multiplier — low-value role only: affected component is a standalone PHP class-scheduling demo. It is never deployed as IdP, hypervisor, CA, backup, EDR, or any high-value role. Blast radius caps at one app database on one host — there is no fleet, domain, or supply-chain pivot path. Floor stays at LOW.
  • Friction — discovery is the bottleneck: there is no Shodan/Censys fingerprint for this product, no fleet scanning, and EPSS predicts <0.5% exploitation probability. Even motivated attackers ignore it because the loot tables are student schedules.
  • No vendor patch pipeline: SourceCodester does not maintain CVE-keyed patches for community uploads, so the realistic remediation is *remove the app* or *replace with a maintained scheduler*, not 'apply update'.

Why not higher?

MEDIUM and above would imply this belongs in a normal patch queue with real ticket velocity. It does not — the product has no enterprise footprint, no patch supply chain, and the only realistic victim population (student-project deployers) is not the audience defending a 10,000-host fleet. Calling this HIGH inflates the queue and dilutes signal on bugs that matter.

Why not lower?

IGNORE would be wrong because the vulnerability IS trivially exploitable with public PoC, and a handful of organizations *might* genuinely run a SourceCodester app inside a lab or staging environment. If your asset inventory surfaces one, you need to act — just at a backlog-hygiene priority, not at incident pace.

05 · Compensating Control

What to do — in priority order.

  1. Inventory: confirm you do not run any SourceCodester PHP app — Grep your asset inventory and webserver vhost configs for sourcecodester, preview.php, class-and-exam-timetabling. If zero hits, close the ticket. If hits exist, proceed. There is no mitigation SLA at LOW severity — handle within the 365-day remediation window.
  2. If found, take the instance off the public internet immediately — Bind to localhost or put behind VPN / authenticated reverse proxy. Public exposure of this codebase is indefensible regardless of CVE — it has at least five sibling SQLi CVEs in the same project.
  3. Drop a WAF rule blocking SQLi payloads on /preview.php and siblings — ModSecurity CRS paranoia level 2+ or any commercial WAF will catch sqlmap signatures. Apply to /preview*.php, /archive.php at minimum.
  4. Replace the application — The entire codebase is unmaintained and bug-saturated. Swap for a maintained scheduling tool (e.g., FET, Untis, or any institutional LMS module). This is the only durable fix.
What doesn't work
  • Waiting for a vendor patch — SourceCodester does not ship CVE-keyed patches for community uploads.
  • Input validation in the calling page alone — sibling CVEs show the same anti-pattern across the whole codebase, so per-file fixes leave you exposed.
  • Database least-privilege as a primary control — it reduces blast radius but the C:L/I:L/A:L impact still lands; do it, but don't call it remediation.
06 · Verification

Crowdsourced verification payload.

Run on any auditor workstation with network reach to the suspected host. Requires curl only; no privileges needed beyond outbound HTTP. Invoke as ./check_cve_2026_13485.sh https://target.example.com — script returns VULNERABLE if the app fingerprints as the SourceCodester scheduler and the vulnerable parameter responds with SQL-error-shaped output.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verifier — CVE-2026-13485
# SourceCodester Class and Exam Timetabling System 1.0 — SQLi in /preview.php
# Usage: ./check_cve_2026_13485.sh <base_url>
set -u

BASE="${1:-}"
if [[ -z "$BASE" ]]; then
  echo "Usage: $0 <base_url>  e.g. https://timetable.lab.local" >&2
  exit 2
fi
BASE="${BASE%/}"

UA="noisgate-verifier/1.0"
TMP="$(mktemp)"
trap 'rm -f "$TMP"' EXIT

# Step 1: fingerprint the app at all
FP=$(curl -sk -A "$UA" --max-time 10 -o "$TMP" -w "%{http_code}" "$BASE/preview.php?course_year_section=1")
if [[ "$FP" == "000" || "$FP" == "404" ]]; then
  echo "UNKNOWN — /preview.php not reachable (HTTP $FP). Asset may not run this product."
  exit 0
fi

# Step 2: probe with a benign single-quote — a vulnerable build returns a MySQL error
PROBE=$(curl -sk -A "$UA" --max-time 10 "$BASE/preview.php?course_year_section=1%27")
if echo "$PROBE" | grep -qiE 'you have an error in your sql syntax|mysql_fetch|mysqli_|sqlstate|warning: mysql'; then
  echo "VULNERABLE — /preview.php course_year_section emits SQL error on single quote."
  exit 1
fi

# Step 3: boolean differential — same length response for 1=1 vs 1=2 means likely sanitized
TRUE_LEN=$(curl -sk -A "$UA" --max-time 10 "$BASE/preview.php?course_year_section=1%20AND%201%3D1" | wc -c)
FALSE_LEN=$(curl -sk -A "$UA" --max-time 10 "$BASE/preview.php?course_year_section=1%20AND%201%3D2" | wc -c)
DIFF=$(( TRUE_LEN > FALSE_LEN ? TRUE_LEN - FALSE_LEN : FALSE_LEN - TRUE_LEN ))
if (( DIFF > 50 )); then
  echo "VULNERABLE — boolean-based differential detected (delta=$DIFF bytes)."
  exit 1
fi

echo "PATCHED or NOT-AFFECTED — no SQL error, no boolean differential on /preview.php."
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: grep your CMDB, webserver vhosts, and any campus / lab inventory for sourcecodester or class-and-exam-timetabling. If you have zero hits — which is the expected outcome for any enterprise — document the rationale and close the ticket. If you DO find an instance, take it off the public internet today, drop a WAF rule on /preview*.php and /archive.php, and queue replacement of the entire codebase since it has multiple sibling SQLi CVEs and no upstream patch pipeline. Per the noisgate mitigation SLA for LOW there is no formal mitigation deadline; per the noisgate remediation SLA treat this as backlog hygiene with a ≤365-day window (sooner if internet-exposed). Do not let the vendor 7.3 push this above genuinely-HIGH bugs in your queue.

Sources

  1. VulDB — CVE-2026-13485
  2. Vulnerability-Lookup CIRCL — CVE-2026-13485
  3. GHSA-Q3VP-2MQC-929R (CIRCL mirror)
  4. Sibling CVE-2026-13488 (preview7.php SQLi)
  5. Researcher PoC — lffaker/cybersec issue #6 (preview.php)
  6. Researcher PoC — lffaker/cybersec issue #4 (archive.php)
  7. Researcher PoC — yan-124/yan issue #4 (preview7.php)
  8. SourceCodester project home
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.