flawopen.com/Cross-Site Scripting/C/C++
Imagine a guestbook where visitors write a public note. Stored XSS is like someone writing a note that isn't just text — it's a hidden trick that makes the guestbook page itself start doing things, like stealing the next visitor's login session, the moment anyone opens the page to read it.
Cross-site scripting happens when untrusted input reaches the rendered page without proper output encoding. C/C++ web contexts (CGI programs, embedded HTTP servers) build HTML responses manually — there's no template engine providing default escaping, so every output point needs its own explicit encoding.
In 2005, an 19-year-old user exploited a stored XSS flaw on MySpace to create the "Samy" worm — a script that added itself to every profile that viewed it, infecting over a million profiles within about 20 hours and forcing MySpace offline to contain it. It remains one of the most-cited demonstrations of how quickly stored XSS can self-propagate.
Source: widely documented in security industry retrospectives — see References below./* comment text written with no encoding */
fprintf(response,
"<div>%s</div>", comment_text);
/* encode before insertion */
char *encoded = html_encode(comment_text);
fprintf(response,
"<div>%s</div>", encoded);
free(encoded);
html_encode() (a custom function or a library like libxml2's escaping utilities) converts <, >, &, and quote characters into their entity equivalents before the string is written to the response — the browser displays them as text rather than parsing them as tags. fprintf performs no such transformation; it writes the format arguments exactly as given.
Unlike higher-level languages, C/C++ has nothing built in that understands HTML escaping — every project either writes its own encoding function or links a library for it, and it's easy for one output path to be missed.
Just as with SQL injection, building output with sprintf into a fixed buffer risks a buffer overflow independent of whether the content is HTML-encoded — fixing one doesn't fix the other, and both need addressing.
QUERY_STRING, HTTP_REFERER, and other CGI environment variables are attacker-controlled exactly like a parsed request parameter in a higher-level framework — code that reads them directly into output without encoding has the same exposure.
The vulnerability lives in the HTML the program generates and sends to a browser, not in the program's own execution model — a C program that emits unencoded HTML is exactly as exploitable as a scripting-language equivalent.
Buffer safety and HTML-encoding safety are independent — a perfectly bounds-checked snprintf call still produces exploitable output if the inserted content isn't encoded.
grep -rn "fprintf(.*<\|sprintf(.*<" --include="*.c" --include="*.cpp" .
Same underlying shape — untrusted data mixed into a command's structure without encoding — but the target and damage differ: SQL injection targets the database, XSS targets other users' browsers.
Yes — a device's local admin web UI, often built the same way with hand-written HTML generation, carries the identical risk if it reflects any request-derived value unencoded.