You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: secure_software_development_fundamentals.md
+90-10
Original file line number
Diff line number
Diff line change
@@ -1708,15 +1708,17 @@ The usual way to require a regex to match an entire input is to include *anchors
1708
1708
1709
1709
**ca[brt]**
1710
1710
1711
-
In contrast, this regex will only match *exactly* the words “**cab**”, “**car**”, or “**cat**” in most regex implementations, because “**^**” means *“match the beginning”* and “**$**” means *“match the end”*:
1711
+
In contrast, this regex will only match *exactly* the words “**cab**”, “**car**”, or “**cat**” in many regex implementations, because “**^**” often means *“match the beginning”* and “**$**” often means *“match the end”*:
1712
1712
1713
1713
**^ca[brt]$**
1714
1714
1715
-
In some implementations (depending on the option), “**^**” may mean *“beginning of any line”* not *“beginning of the string”* - and you usually want *“beginning of the string”*. A similar thing can happen with “**$**”. From here on we will assume that “**^**” and “**$**” mean beginning and end of the entire string.
1715
+
In some implementations (depending on the option), “**^**” may mean *“beginning of any line”* not *“beginning of the string”* - and you usually want *“beginning of the string”*. A “**$**” means *"end of the string*" in some implementations, and not in others. Since regular expression notations vary, it's important to know about your specific regex expression system.
1716
1716
1717
1717
#### Know Your Regex Implementation
1718
1718
1719
-
Almost every programming language has at least one good regex implementation. They all share many features, but many are slightly different. So, when you use a regex implementation you have not used before, look at its documentation every time you use an operation that you have not used before. Here are some variations to look for.
1719
+
Regex notations are *not* the same between different languages and libraries. Almost every programming language has at least one good regex implementation and they all share many features. However, they are often slightly different.
1720
+
1721
+
So, when you use a regex implementation you have not used before, look at its documentation every time you use an operation that you have not used before. Also, be careful when reusing a pattern. Here are some variations to look for.
1720
1722
1721
1723
There are three major families of regex language notations:
1722
1724
@@ -1728,19 +1730,97 @@ There are three major families of regex language notations:
1728
1730
1729
1731
Here are some important things that vary:
1730
1732
1731
-
* Sometimes there is an option or alternative method to match the entire input; if available, you can use that instead of the anchoring symbols. Make sure it matches the whole thing, though; some methods only check the beginning.
1733
+
1. Sometimes there is an option or alternative method to match the entire input; if available, you can use that instead of the anchoring symbols. Make sure it matches the whole thing, though; some methods only check the beginning.
1734
+
1735
+
2. Sometimes “**^**” matches the beginning of all the data, while in others it represents the beginning of any line in the data. This is often controlled by a *multiline* option.
1732
1736
1733
-
* Sometimes “**^**” matches the beginning of the whole data, while in others it represents the beginning of any line in the data. The same goes for “**$**”. This is often controlled by a *multiline* option.
1737
+
3. Sometimes “**$**” matches the end of all the data, while in others it represents the end of any line in the data. In some systems, an optional newline character (or similar) is also always accepted. In some systems you must use "**\z**" to match the end of the data, but in Python you must use "**\Z**".
1734
1738
1735
-
* The “**.**” for representing *“any character”* doesn’t always match the newline character (**\n**); often there is an option to turn this on or off.
1739
+
4. The “**.**” for representing *“any character”* doesn’t always match the newline character (**\n**); often there is an option to turn this on or off.
1736
1740
1737
-
* Does it properly support Unicode and the encoding you are using?
1741
+
5. Some properly support Unicode and the encoding you are using; others do not.
1738
1742
1739
-
* Can it handle data with the **NUL** character (byte value 0) within the data? If not, and your input data could have an embedded **NUL** character, you will need to validate the data first to make sure there are no **NUL** characters before passing the data to the regex implementation.
1743
+
6. Some can handle data with the **NUL** character (byte value 0) within the data; others do not. If not, and your input data could have an embedded **NUL** character, you will need to validate the data first to make sure there are no **NUL** characters before passing the data to the regex implementation.
1740
1744
1741
-
* Is matching case-sensitive? Usually it is case-sensitive by default, and there is a trivial way to make it case-insensitive. If it is case-insensitive, remember that exactly what characters have case-insensitive matches depends on the locale. For example, “**I**” and “**i**” match in the English (“**en**”) and the C locale (“**C**”), but not in the Turkish (“**tr**”). In the Turkish locale, the Unicode LATIN CAPITAL LETTER I matches the LATIN SMALL LETTER DOTLESS I - not a lowercase “**i**”.
1745
+
7. Some do case-sensitive matching by default; others do not. Usually it is case-sensitive by default, and there is a trivial way to make it case-insensitive. If it is case-insensitive, remember that exactly what characters have case-insensitive matches depends on the locale. For example, “**I**” and “**i**” match in the English (“**en**”) and the C locale (“**C**”), but not in the Turkish (“**tr**”). In the Turkish locale, the Unicode LATIN CAPITAL LETTER I matches the LATIN SMALL LETTER DOTLESS I - not a lowercase “**i**”.
1742
1746
1743
-
In some languages, such as in Ruby, you normally use **\A** and **\z** instead of “**^**” and “**$**” to match string begin/end, because “**^**” and “**$**” match line begin/end instead.
1747
+
The following table shows how to create a regex pattern that matches an entire input string for some common platforms, as provided by [Correctly Using Regular Expressions for Secure Input Validation](https://best.openssf.org/Correctly-Using-Regular-Expressions). There's no need to memorize this; the point to understand is to make sure you use the correct symbols for the platform you're using:
1748
+
1749
+
<table>
1750
+
<tr>
1751
+
<td>
1752
+
Platform
1753
+
</td>
1754
+
<td>Prepend
1755
+
</td>
1756
+
<td>Append
1757
+
</td>
1758
+
</tr>
1759
+
<tr>
1760
+
<td>POSIX BRE, POSIX ERE, and ECMAScript (JavaScript)
0 commit comments