Exercise 3: SQL Injection Inside a PL/pgSQL Function, and the Fix — Possible Solution ==================================================================== THE RISK ------------------------------ Per this chapter's own warn-box, "building a SQL string inside a PL/pgSQL function via string concatenation and running it with EXECUTE is exactly as vulnerable to SQL injection as building an unparameterized query in application code." If a function accepts some input (say, a column name or search term) and builds a SQL string by directly concatenating that input into the query text before calling EXECUTE, an attacker who can influence that input can inject additional SQL logic into the string — exactly the same data-vs-code confusion sqli1 identified as the root cause of SQL injection in application code, just relocated one layer deeper, into the database's own procedural code. WHY IT DOESN'T MATTER THAT THE VULNERABLE CODE IS INSIDE THE DATABASE ------------------------------ Per this chapter, "sqli1's own material applies unchanged, whether the vulnerable code lives inside the application or inside the database itself." A common but mistaken intuition is that code running inside the database itself is somehow inherently safer than application code — but the underlying mechanism of the vulnerability (untrusted input being concatenated directly into a string that's then interpreted as executable SQL) is identical regardless of which layer that concatenation happens in. A PL/pgSQL function using EXECUTE on a concatenated string is just as exploitable as an application backend doing the same thing. THE CORRECT FIX ------------------------------ Per this chapter, "the fix is the same principle sqli1 taught: EXECUTE ... USING with real parameters, rather than concatenating untrusted input directly into the SQL string." Instead of building the entire query as one dynamically-assembled string that embeds the untrusted value directly, EXECUTE ... USING passes the value as a genuine, separate parameter — the same underlying idea as sqli1's own parameterized-query recommendation for application code. The database keeps the SQL structure (the "code") and the actual data value cleanly separated, so a value containing SQL-like syntax is still treated purely as data, never as part of the executable query structure, regardless of what it contains. WHY THIS WORKS AS AN ANSWER ------------------------------ It explains the vulnerability mechanism precisely, explicitly addresses the "it's inside the database, so it must be safer" misconception the chapter implicitly counters, and states the correct fix (EXECUTE ... USING) while explicitly tying it back to sqli1's own parameterized-query principle as the chapter itself does.