Skip to content

Commit

Permalink
Split SQL injection unit
Browse files Browse the repository at this point in the history
We've received many positive comments on the course.  However, one
note we've had from learner feedback, OpenSSF Governing Board /
TAC interviews, and persona analysis, is that the units need to be
"bite-sized" (not too big). I believe the point is that
a few units are larger than they should be and should be broken apart.

I did a word count on each unit of content, and one unit
stood out: the "SQL Injection" unit. This unit was 3,540 words
(using a tool that strips out HTML & punctuation to do word counts).
It's the only unit above 3,000 words.
That unit is about 1/3 larger than the second-largest unit
(2,683 for "Countering Out-of-Bounds Reads and Writes (Buffer Overflow)"),
and far larger than the median of 870 words per unit.
This unit had internal subdivisions, but internal subdivisions
don't seem to be enough.

This commit splits the SQL Injection unit into 3 units, and adds
quizzes for each. The largest revised unit ("SQL Injection")
is only 1,904 words, 54% of its original size.

FYI, the next-largest units (by word count) are the following
(these are the only ones over 2,000 words):

* 2683 Countering Out-of-Bounds Reads and Writes (Buffer Overflow)
* 2306 Privacy Requirements
* 2118 Dynamic Analysis Overview
* 2116 Filenames (Including Path Traversal and Link Following)
* 2091 Formal Methods
* 2036 Cryptographically Secure Pseudo-Random Number Generator (CSPRNG)

This was computed using a simple word-counting tool I wrote.

Signed-off-by: David A. Wheeler <dwheeler@dwheeler.com>
  • Loading branch information
david-a-wheeler committed Apr 5, 2024
1 parent ec06964 commit 992cd01
Showing 1 changed file with 48 additions and 12 deletions.
60 changes: 48 additions & 12 deletions secure_software_development_fundamentals.md
Original file line number Diff line number Diff line change
Expand Up @@ -2428,7 +2428,7 @@ Again, we want to try to use an approach that is easy to use correctly - it need

For databases, there are well-known solutions that are far easier to use securely.

#### SQL Injection Solutions
#### Usual SQL Injection Solution: Parameterized Statements

SQL injection vulnerabilities are one of the most common and devastating vulnerabilities, especially in web applications. They are also easy to counter, once you know how to do it.

Expand Down Expand Up @@ -2538,12 +2538,20 @@ explained in the [PostgreSQL (Command Execution Functions) documentation](https:

The [OWASP Query Parameterization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Query_Parameterization_Cheat_Sheet.html) and [Bobby Tables website](https://bobby-tables.com/) provide examples for a variety of ecosystems.

##### Subtle issues: DBMS (Server) side vs. Application (client) side
#### Quiz 3.2: SQL Injection

\>\>Parameterized statements (including prepared statements) are a valuable countermeasure against SQL injection, but you have to use placeholders for every data value that might possibly be controllable by an attacker. True or False?<<

(x) True

An important security issue is *where* the
( ) False

### SQL Injection: DBMS (Server) side vs. Application (client) side

An important yet subtle security issue when using
SQL parameterized statements is *where* the
parameters of a parameterized statement are processed.
There are two options, DBMS-side and application-side, and
DBMS-side is better from a security point of view.
There are two options, DBMS-side and application-side.

From a security point-of-view it's best if the parameters of
parameterized statements are processed directly
Expand All @@ -2552,6 +2560,7 @@ aka "DBMS-side" parameter processing.
This approach is often called "server-side" since many DBMSs use a
client/server architecture where the client connects over a network
to a server-side DBMS.

There are many advantages to DBMS-side parameter processing.
The DBMS has the current information on escaping rules
(and can often use more efficient mechanisms than adding escape characters),
Expand Down Expand Up @@ -2590,8 +2599,9 @@ This weakness can lead to vulnerabilities. For example:
objects, associative arrays, and/or dictionaries), then there
is a significant risk of a vulnerability.
The fundamental problem is that the application-side library isn't
parsing the query language the same way that the DBMS would -
it is doing simple text substitutions. So if the library implements this
necessarily parsing the query language the same way that the DBMS would -
it is usually doing simple text substitutions.
So if the library implements this
functionality, it must typically make *guesses* of what types are expected.
For example, it may guess that associative arrays are only sent
to the library when that is sensible in the parameterized SQL query.
Expand Down Expand Up @@ -2655,8 +2665,33 @@ only an application-side approach is available.
In some cases requesting a prepared statement forces the library to
use DBMS-side processing, but don't assume it - check the documentation.
If you have a practical choice, prefer a DBMS-side implementation.
Otherwise, carefully validate input and data going to the library
to ensure they are the appropriate types.

This is a good example of a general kind of security issue,
namely, that different components may interpret the same input differently.
In some cases, an attacker can exploit this, by making their input
appear benign to one part while performing something malicious in another.

##### Stored Procedures
#### Quiz: SQL Injection: DBMS (Server) side vs. Application (client) side

\>\>Which of these is an advantage of libraries that implement application-side parameterization?<<

( ) The library necessarily has the current information on the
DBMS' current escaping rules for its particular version and configuration.

( ) The library has the information on this DBMS session's character encodings
and expected data types.

(x) An application-side library is often easier to implement.

### SQL Injection: Alternatives to Parameterized Statements

Database systems are widely used, so there are many ways to
interact with them.
Here we discuss some alternatives.

#### Stored Procedures

Many database systems support "stored procedures", that is,
procedures embedded in the database itself.
Expand All @@ -2674,7 +2709,7 @@ in stored procedures, see your library's documentation, the
[OWASP Query Parameterization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Query_Parameterization_Cheat_Sheet.html#stored-procedure-examples), and the
[OWASP SQL Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html)

##### When Parameterized Statements Won't Work
#### When Parameterized Statements Won't Work

In some situations parameterized statements (including
prepared statements) will *not* work.
Expand Down Expand Up @@ -2710,7 +2745,7 @@ For example, in Python, if you need to write to a user-provided table name, you
cur.execute(f"insert into {table_name}(d, ts) values (?, ?)", (today, now)) # This is safe because we know that table_name can only take trusted values from table_name_map
~~~~

##### Other Approaches for Countering SQL Injection
#### Other Approaches for Countering SQL Injection

Many programs use object-relational mapping (ORM). This is just a technique to automatically convert data in a relational database into an object in an object-oriented programming language and back; lots of libraries and frameworks will do this for you. This is fine, as long as the ORM is implemented using parameterized statements or something equivalent to them. In practice, any good ORM implementation will do so. So if you are using a respected ORM, you are already doing this. That said, it is common in systems that use ORMs to occasionally need to use SQL queries directly… and when you do, use parameterized statements or prepared statements.

Expand All @@ -2720,11 +2755,12 @@ There are other approaches, of course. You can write your own escape code, but t

In summary, properly using parameterized statement libraries makes it much easier to write secure code. In addition, they typically make code easier to read, automatically handle the variations between how databases escape things, and sometimes they are faster than doing metacharacter escapes yourself.

#### Quiz 3.2: SQL Injection
#### Quiz: SQL Injection: Alternatives to Parameterized Statements

\>\>Parameterized statements (including prepared statements) are a valuable countermeasure against SQL injection, but you have to use placeholders for every data value that might possibly be controllable by an attacker. True or False?<<
\>\>True or false: A good object-relational mapping (ORM) system should be implemented using parameterized statements or something equivalent to them.<<

(x) True
DBMS' current escaping rules for its particular version and configuration.

( ) False

Expand Down

0 comments on commit 992cd01

Please sign in to comment.