Skip to content

Commit 992cd01

Browse files
Split SQL injection unit
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 <[email protected]>
1 parent ec06964 commit 992cd01

File tree

1 file changed

+48
-12
lines changed

1 file changed

+48
-12
lines changed

secure_software_development_fundamentals.md

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,7 +2428,7 @@ Again, we want to try to use an approach that is easy to use correctly - it need
24282428

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

2431-
#### SQL Injection Solutions
2431+
#### Usual SQL Injection Solution: Parameterized Statements
24322432

24332433
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.
24342434

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

25392539
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.
25402540

2541-
##### Subtle issues: DBMS (Server) side vs. Application (client) side
2541+
#### Quiz 3.2: SQL Injection
2542+
2543+
\>\>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?<<
2544+
2545+
(x) True
25422546

2543-
An important security issue is *where* the
2547+
( ) False
2548+
2549+
### SQL Injection: DBMS (Server) side vs. Application (client) side
2550+
2551+
An important yet subtle security issue when using
2552+
SQL parameterized statements is *where* the
25442553
parameters of a parameterized statement are processed.
2545-
There are two options, DBMS-side and application-side, and
2546-
DBMS-side is better from a security point of view.
2554+
There are two options, DBMS-side and application-side.
25472555

25482556
From a security point-of-view it's best if the parameters of
25492557
parameterized statements are processed directly
@@ -2552,6 +2560,7 @@ aka "DBMS-side" parameter processing.
25522560
This approach is often called "server-side" since many DBMSs use a
25532561
client/server architecture where the client connects over a network
25542562
to a server-side DBMS.
2563+
25552564
There are many advantages to DBMS-side parameter processing.
25562565
The DBMS has the current information on escaping rules
25572566
(and can often use more efficient mechanisms than adding escape characters),
@@ -2590,8 +2599,9 @@ This weakness can lead to vulnerabilities. For example:
25902599
objects, associative arrays, and/or dictionaries), then there
25912600
is a significant risk of a vulnerability.
25922601
The fundamental problem is that the application-side library isn't
2593-
parsing the query language the same way that the DBMS would -
2594-
it is doing simple text substitutions. So if the library implements this
2602+
necessarily parsing the query language the same way that the DBMS would -
2603+
it is usually doing simple text substitutions.
2604+
So if the library implements this
25952605
functionality, it must typically make *guesses* of what types are expected.
25962606
For example, it may guess that associative arrays are only sent
25972607
to the library when that is sensible in the parameterized SQL query.
@@ -2655,8 +2665,33 @@ only an application-side approach is available.
26552665
In some cases requesting a prepared statement forces the library to
26562666
use DBMS-side processing, but don't assume it - check the documentation.
26572667
If you have a practical choice, prefer a DBMS-side implementation.
2668+
Otherwise, carefully validate input and data going to the library
2669+
to ensure they are the appropriate types.
2670+
2671+
This is a good example of a general kind of security issue,
2672+
namely, that different components may interpret the same input differently.
2673+
In some cases, an attacker can exploit this, by making their input
2674+
appear benign to one part while performing something malicious in another.
26582675

2659-
##### Stored Procedures
2676+
#### Quiz: SQL Injection: DBMS (Server) side vs. Application (client) side
2677+
2678+
\>\>Which of these is an advantage of libraries that implement application-side parameterization?<<
2679+
2680+
( ) The library necessarily has the current information on the
2681+
DBMS' current escaping rules for its particular version and configuration.
2682+
2683+
( ) The library has the information on this DBMS session's character encodings
2684+
and expected data types.
2685+
2686+
(x) An application-side library is often easier to implement.
2687+
2688+
### SQL Injection: Alternatives to Parameterized Statements
2689+
2690+
Database systems are widely used, so there are many ways to
2691+
interact with them.
2692+
Here we discuss some alternatives.
2693+
2694+
#### Stored Procedures
26602695

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

2677-
##### When Parameterized Statements Won't Work
2712+
#### When Parameterized Statements Won't Work
26782713

26792714
In some situations parameterized statements (including
26802715
prepared statements) will *not* work.
@@ -2710,7 +2745,7 @@ For example, in Python, if you need to write to a user-provided table name, you
27102745
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
27112746
~~~~
27122747

2713-
##### Other Approaches for Countering SQL Injection
2748+
#### Other Approaches for Countering SQL Injection
27142749

27152750
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.
27162751

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

27212756
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.
27222757

2723-
#### Quiz 3.2: SQL Injection
2758+
#### Quiz: SQL Injection: Alternatives to Parameterized Statements
27242759

2725-
\>\>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?<<
2760+
\>\>True or false: A good object-relational mapping (ORM) system should be implemented using parameterized statements or something equivalent to them.<<
27262761

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

27292765
( ) False
27302766

0 commit comments

Comments
 (0)