Skip to content

Commit 63cdbbd

Browse files
Merge branch 'main' into translate-input1
Signed-off-by: David A. Wheeler <[email protected]>
2 parents 5931ca0 + 3c2baf3 commit 63cdbbd

25 files changed

+637
-322
lines changed

docs/Secure-Coding-Guide-for-Python/readme.md

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,37 @@
11
# Secure Coding One Stop Shop for Python
22

3-
Promote secure products by knowing the difference between secure compliant
4-
and non-compliant code with `CPython >= 3.9` using modules listed on
3+
An initiative by the OpenSSF to provide new Python programmers a resource to study secure coding in `CPython >= 3.9` with working code examples.
54

6-
[Python Module Index](https://docs.python.org/3.9/py-modindex.html) [Python 2023].
5+
Documentation is written in academic style to support security researchers while using plain English to cater for an international audience.
76

8-
This page is an initiative by the OpenSSF to improve secure coding in Python by providing a location for study. Its structure is based on
9-
Common Weakness Enamurator (CWE) [Pillar Weakness](https://cwe.mitre.org/documents/glossary/#Pillar%20Weakness) [mitre.org 2023].
10-
11-
Some rules only contain code examples, documentation will follow.
7+
Python modules outside of the _Python Module Index_ [[Python 2023](https://docs.python.org/3.9/py-modindex.html)] are specifically not covered by this document.
8+
The structure is based on Common Weakness Enumeration (CWE) _Pillar Weakness_ [[MITRE Pillar 2024](https://cwe.mitre.org/documents/glossary/#Pillar%20Weakness)].
129

1310
## Disclaimer
1411

15-
Content comes WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, as stated in the license text [CC-BY-4.0](LICENSE/CC-BY-4.0.txt) for documentation and [MIT](LICENSE/MIT.txt).
12+
Content comes __WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED__, as stated in the license text [CC-BY-4.0](LICENSE/CC-BY-4.0.txt) for documentation and [MIT](LICENSE/MIT.txt).
1613
Following or using the documentation and or code is at your own risk. Code examples are intended purely for educational use and not for products in parts or in full.
1714
Code examples are NOT to be used to cause harm of any kind to anyone or anything.
1815

1916
## Introduction
2017

2118
Every person writing code shall study the following:
2219

23-
* OWASP Secure Coding [Practices-Quick Reference Guide](https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/) [OWASP 2022]
24-
* OWASP Top 10 Report [OWASP 2022](https://owasp.org/www-project-top-ten/) [OWASP 2022]
25-
* CWE Top 25 2022 [CWE 2022](https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html) [MITRE 2023]
20+
* _OWASP Developer Guide_ [[OWASP dev 2024](https://owasp.org/www-project-developer-guide/release/)]
21+
* _OWASP Top 10 Report_ [[OWASP 2021](https://owasp.org/www-project-top-ten/)]
22+
* _CWE Top 25_ [[MITRE 2024](https://cwe.mitre.org/top25/index.html)]
2623

2724
## Secure Coding Standard for Python
2825

29-
Code examples are written to explain security design with as little code as possible demonstrating the issue in the `noncompliantXX.py` titled Python file.
30-
The `compliantXX.py` file demonstrates only the mitigation or removal of the described risk.
31-
None of the code examples are intendet to be used 'as is' for production. Using the code is at your own risk.
26+
Code examples are written to explain security design with as little code as possible. __None__ of the code examples are intendet to be used 'as is' for production. Using the code is at your own risk!
27+
28+
__Code file naminng conventions:__
29+
30+
* `noncompliantXX.py` anti-pattern.
31+
* `compliantXX.py` mitigation for mitigating or removal of __ONLY__ the described risk.
32+
* `exampleXX.py` to allow understanding the documented behaviour.
3233

33-
It is **not production code** and requires code-style or python best practices to be added such as:
34+
It is __not production code__ and requires code-style or python best practices to be added such as:
3435

3536
* Inline documentation
3637
* Custom exceptions
@@ -41,20 +42,20 @@ It is **not production code** and requires code-style or python best practices t
4142

4243
|[CWE-664: Improper Control of a Resource Through its Lifetime](https://cwe.mitre.org/data/definitions/664.html)|Prominent CVE|
4344
|:-----------------------------------------------------------------------------------------------------------------------------------------------|:----|
44-
|[CWE-134: Use of Externally-Controlled Format String](CWE-664/CWE-134/README.md)|[CVE-2022-27177](https://www.cvedetails.com/cve/CVE-2022-27177/),<br/>CVSSv3.1: **9.8**,<br/>EPSS: **00.37** (01.12.2023)|
45+
|[CWE-134: Use of Externally-Controlled Format String](CWE-664/CWE-134/README.md)|[CVE-2022-27177](https://www.cvedetails.com/cve/CVE-2022-27177/),<br/>CVSSv3.1: __9.8__,<br/>EPSS: __00.37__ (01.12.2023)|
4546
|[CWE-197: Numeric Truncation Error](CWE-664/CWE-197/README.md)||
4647
|[CWE-197: Control rounding when converting to less precise numbers](CWE-664/CWE-197/01/README.md)||
4748
|[CWE-400: Uncontrolled Resource Consumption](CWE-664/CWE-400/README.md)||
4849
|[CWE-409: Improper Handling of Highly Compressed Data (Data Amplification)](CWE-664/CWE-409/.)||
4950
|[CWE-410: Insufficient Resource Pool](CWE-664/CWE-410/README.md)||
50-
|[CWE-426: Untrusted Search Path](CWE-664/CWE-426/README.md)|[CVE-2015-1326](https://www.cvedetails.com/cve/CVE-2015-1326),<br/>CVSSv3.0: **8.8**,<br/>EPSS: **00.20** (23.11.2023)|
51-
|[CWE-501: Trust Boundary Violation)](CWE-664/CWE-501/README.md)|[CVE-2023-28597](https://www.cvedetails.com/cve/CVE-2023-28597),<br/>CVSSv3.0: **7.5**,<br/>EPSS: **00.11** (05.11.2024)|
52-
|[CWE-502: Deserialization of Untrusted Data)](CWE-664/CWE-502/.)|[CVE-2018-8021](https://www.cvedetails.com/cve/CVE-2018-8021),<br/>CVSSv3.0: **9.8**,<br/>EPSS: **93.54** (05.11.2024)|
53-
|[CWE-532: Insertion of Sensitive Information into Log File](CWE-664/CWE-532/README.md)|[CVE-2023-45585](https://www.cvedetails.com/cve/CVE-2023-45585),<br/>CVSSv3.1: **9.8**,<br/>EPSS: **0.04** (01.11.2024)|
51+
|[CWE-426: Untrusted Search Path](CWE-664/CWE-426/README.md)|[CVE-2015-1326](https://www.cvedetails.com/cve/CVE-2015-1326),<br/>CVSSv3.0: __8.8__,<br/>EPSS: __00.20__ (23.11.2023)|
52+
|[CWE-501: Trust Boundary Violation)](CWE-664/CWE-501/README.md)|[CVE-2023-28597](https://www.cvedetails.com/cve/CVE-2023-28597),<br/>CVSSv3.0: __7.5__,<br/>EPSS: __00.11__ (05.11.2024)|
53+
|[CWE-502: Deserialization of Untrusted Data)](CWE-664/CWE-502/.)|[CVE-2018-8021](https://www.cvedetails.com/cve/CVE-2018-8021),<br/>CVSSv3.0: __9.8__,<br/>EPSS: __93.54__ (05.11.2024)|
54+
|[CWE-532: Insertion of Sensitive Information into Log File](CWE-664/CWE-532/README.md)|[CVE-2023-45585](https://www.cvedetails.com/cve/CVE-2023-45585),<br/>CVSSv3.1: __9.8__,<br/>EPSS: __0.04__ (01.11.2024)|
5455
|[CWE-665: Improper Initialization](CWE-664/CWE-665/README.md)||
5556
|[CWE-681: Incorrect Conversion between Numeric Types](CWE-664/CWE-681/README.md)||
5657
|[CWE-833: Deadlock](CWE-664/CWE-833/README.md)||
57-
|[CWE-843: Access of Resource Using Incompatible Type ('Type Confusion')](CWE-664/CWE-843/.)|[CVE-2021-29513](https://www.cvedetails.com/cve/CVE-2021-29513),<br/>CVSSv3.1: **7.8**,<br/>EPSS: **00.05** (05.11.2024)|
58+
|[CWE-843: Access of Resource Using Incompatible Type ('Type Confusion')](CWE-664/CWE-843/.)|[CVE-2021-29513](https://www.cvedetails.com/cve/CVE-2021-29513),<br/>CVSSv3.1: __7.8__,<br/>EPSS: __00.05__ (05.11.2024)|
5859
|[XXX-005: Consider hash-based integrity verification of byte code files against their source code files](CWE-664/XXX-005/.)||
5960

6061
|[CWE-682: Incorrect Calculation](https://cwe.mitre.org/data/definitions/682.html)|Prominent CVE|
@@ -83,12 +84,12 @@ It is **not production code** and requires code-style or python best practices t
8384
|[CWE-390: Detection of Error Condition without Action](CWE-703/CWE-390/)||
8485
|[CWE-392: Missing Report of Error Condition](CWE-703/CWE-392/README.md)||
8586
|[CWE-754: Improper Check for Unusual or Exceptional Conditions](CWE-703/CWE-754/.)||
86-
|[CWE-755: Improper Handling of Exceptional Conditions](CWE-703/CWE-755/README.md)|[CVE-2024-39560](https://www.cvedetails.com/cve/CVE-2024-39560),<br/>CVSSv3.1: **6.5**,<br/>EPSS: **0.04** (01.11.2024)|
87+
|[CWE-755: Improper Handling of Exceptional Conditions](CWE-703/CWE-755/README.md)|[CVE-2024-39560](https://www.cvedetails.com/cve/CVE-2024-39560),<br/>CVSSv3.1: __6.5__,<br/>EPSS: __0.04__ (01.11.2024)|
8788

8889
|[CWE-707: Improper Neutralization](https://cwe.mitre.org/data/definitions/707.html)|Prominent CVE|
8990
|:----------------------------------------------------------------|:----|
90-
|[CWE-78: Improper Neutralization of Special Elements Used in an OS Command ("OS Command Injection")](CWE-707/CWE-78/README.md)|[CVE-2024-43804](https://www.cvedetails.com/cve/CVE-2024-43804/),<br/>CVSSv3.1: **8.8**,<br/>EPSS: **00.06** (08.11.2024)|
91-
|[CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')](CWE-707/CWE-89/README.md)|[CVE-2019-8600](https://www.cvedetails.com/cve/CVE-2019-8600/),<br/>CVSSv3.1: **9.8**,<br/>EPSS: **01.43** (18.02.2024)|
91+
|[CWE-78: Improper Neutralization of Special Elements Used in an OS Command ("OS Command Injection")](CWE-707/CWE-78/README.md)|[CVE-2024-43804](https://www.cvedetails.com/cve/CVE-2024-43804/),<br/>CVSSv3.1: __8.8__,<br/>EPSS: __00.06__ (08.11.2024)|
92+
|[CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')](CWE-707/CWE-89/README.md)|[CVE-2019-8600](https://www.cvedetails.com/cve/CVE-2019-8600/),<br/>CVSSv3.1: __9.8__,<br/>EPSS: __01.43__ (18.02.2024)|
9293
|[CWE-117: Improper Output Neutralization for Logs](CWE-707/CWE-117/.)||
9394
|[CWE-175: Improper Handling of Mixed Encoding](CWE-707/CWE-175/README.md)||
9495
|[CWE-180: Incorrect behavior order: Validate before Canonicalize](CWE-707/CWE-180/.)||
@@ -103,11 +104,12 @@ It is **not production code** and requires code-style or python best practices t
103104

104105
|Ref|Detail|
105106
|-----|-----|
106-
|[Python 2023]|[3.9 Module Index](https://docs.python.org/3.9/py-modindex.html)|
107-
|[mitre.org 2023]|[CWE - CWE-1000: Research Concepts](https://cwe.mitre.org/data/definitions/1000.html)|
108-
|[OWASP 2022]|[Secure Coding Practices-Quick Reference Guide](https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/)|
109-
|[OWASP 2022]|[OWASP Top 10 Report 2022](https://owasp.org/www-project-top-ten/)|
110-
|[MITRE 2023]|[CWE Top 25 2022](https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html)|
107+
|[Python 2023]|3.9 Module Index [online], available from [https://docs.python.org/3.9/py-modindex.html](https://docs.python.org/3.9/py-modindex.html) [accessed Dec 2024]|
108+
|[mitre.org 2023]|CWE - CWE-1000: Research Concepts [online], available from [https://cwe.mitre.org/data/definitions/1000.html](https://cwe.mitre.org/data/definitions/1000.html) [accessed Dec 2024]|
109+
|[OWASP dev 2024]|OWASP Developer Guide [online], available from [https://owasp.org/www-project-developer-guide/release/](https://owasp.org/www-project-developer-guide/release/) [accessed Dec 2024]|
110+
|[OWASP 2021]|OWASP Top 10 Report 2021 [online], available from [https://owasp.org/www-project-top-ten/](https://owasp.org/www-project-top-ten/)|
111+
|[MITRE Pillar 2024]|_Pillar Weakness_ [online], available form [https://cwe.mitre.org/documents/glossary/#Pillar%20Weakness](https://cwe.mitre.org/documents/glossary/#Pillar%20Weakness) [accessed Dec 2024]|
112+
|[MITRE 2024]|CWE Top 25 [online], available form [https://cwe.mitre.org/top25/index.html](https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html) [accessed Dec 2024]|
111113

112114
## License
113115

docs/labs/argument-injection.js

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,78 @@
1+
// Copyright (C) Open Source Security Foundation (OpenSSF) and its contributors.
2+
// SPDX-License-Identifier: MIT
3+
14
info =
25
{
36
hints: [
47
{
58
present: String.raw`exec \(`,
6-
text: "The `exec` function is vulnerable to command injection. Replace it with `execFile` to improve security."
9+
text: "The `exec` function is vulnerable to command injection. Replace it with `execFile` to improve security.",
710
},
811
{
912
absent: String.raw`^[\n\r]*\s*execFile\s*\(`,
10-
text: "Use the `execFile` function instead of `exec` to avoid shell interpretation. Your line should start with `execFile(`."
13+
text: "Use the `execFile` function instead of `exec` to avoid shell interpretation. Your line should start with `execFile(`.",
1114
},
1215
{
1316
absent: String.raw`execFile\s*\(\s*['"${BACKQUOTE}]git['"${BACKQUOTE}]\s*,`,
14-
text: "Separate the command and its arguments. The first argument to `execFile` should be the command 'git' without any of the command arguments."
17+
text: "Separate the command and its arguments. The first argument to `execFile` should be the command 'git' without any of the command arguments.",
1518
},
1619
{
1720
present: String.raw`['"${BACKQUOTE}]git\x20blame['"${BACKQUOTE}]`,
18-
text: "Separate the command and its arguments. The first argument to `execFile` should be the command 'git', followed by an array with parameters, like this: `execFile('git', ['blame', ...])`."
21+
text: "Separate the command and its arguments. The first argument to `execFile` should be the command 'git', followed by an array with parameters, like this: `execFile('git', ['blame', ...])`.",
1922
},
2023
{
2124
absent: String.raw`\[ ['"${BACKQUOTE}]blame`,
22-
text: "Pass the arguments as an array, like this: `execFile('git', ['blame', ...])`."
25+
text: "Pass the arguments as an array, like this: `execFile('git', ['blame', ...])`.",
2326
},
2427
{
2528
present: "--",
2629
absent: String.raw`['"${BACKQUOTE}]--['"${BACKQUOTE}]`,
27-
text: "To pass `--` you need to pass it as a literal string. Typically this is notated as `'--'` or `\"--\"`."
30+
text: "To pass `--` you need to pass it as a literal string. Typically this is notated as `'--'` or `\"--\"`.",
2831
},
2932
{
3033
absent: String.raw`\[ ['"${BACKQUOTE}]blame['"${BACKQUOTE}] , ['"${BACKQUOTE}]--['"${BACKQUOTE}] ,`,
31-
text: "Pass the arguments as an array. Include '--' before the file path to prevent argument injection. Your array should look like `['blame', '--', ...`."
34+
text: "Pass the arguments as an array. Include '--' before the file path to prevent argument injection. Your array should look like `['blame', '--', ...`.",
3235
},
3336
{
3437
present: String.raw`['"${BACKQUOTE}]filePath['"${BACKQUOTE}]`,
35-
text: "`filePath` is a variable, use it directly without using quote marks."
38+
text: "`filePath` is a variable, use it directly without using quote marks.",
3639
},
3740
{
3841
present: String.raw`['"]\$\{filePath\}['"]`,
39-
text: "`filePath` is a variable, use it directly without using quote marks."
42+
text: "`filePath` is a variable, use it directly without using quote marks.",
4043
},
4144
{
4245
present: String.raw`${BACKQUOTE}\$\{filePath\}${BACKQUOTE}`,
43-
text: "Strictly speaking, using a backquoted template with a single reference to a variable name works. In this case, it's being done to `filePath`. However, this is unnecessarily complicated. When you want to simply refer to a variable's value, use the variable name."
46+
text: "Strictly speaking, using a backquoted template with a single reference to a variable name works. In this case, it's being done to `filePath`. However, this is unnecessarily complicated. When you want to simply refer to a variable's value, use the variable name.",
4447
},
4548
{
4649
absent: String.raw`\[ ['"${BACKQUOTE}]blame['"${BACKQUOTE}] , ['"${BACKQUOTE}]--['"${BACKQUOTE}] , filePath \]`,
47-
text: "Pass the arguments as an array. Include '--' before the file path to prevent argument injection. Your array should look like `['blame', '--', filePath]`."
50+
text: "Pass the arguments as an array. Include '--' before the file path to prevent argument injection. Your array should look like `['blame', '--', filePath]`.",
4851
},
4952
{
5053
present: "shell = [fF]alse",
51-
text: "When passing options to execFile, you need an option with the options, and those use `:` not `=`. So you should say something like: `{shell: false}`."
54+
text: "When passing options to execFile, you need an option with the options, and those use `:` not `=`. So you should say something like: `{shell: false}`.",
5255
},
5356
{
5457
present: "[F]alse",
55-
text: "JavaScript is case-sensitive. The false value is spelled as `false` and not `False`."
58+
text: "JavaScript is case-sensitive. The false value is spelled as `false` and not `False`.",
5659
},
5760
{
5861
absent: String.raw`\{ shell : false \}`,
5962
present: "shell : false",
60-
text: "When passing options to execFile, you must provide those options as a JavaScript object. That means you must surround them with `{...}` like this: `{shell: false}`."
63+
text: "When passing options to execFile, you must provide those options as a JavaScript object. That means you must surround them with `{...}` like this: `{shell: false}`.",
6164
},
6265
{
6366
absent: String.raw`\{ shell : false \}`,
64-
text: "We encourage you to explicitly set `shell: false` in the options object to prevent shell interpretation. That is something like this: `execFile('git', ['blame', '--', filePath], { shell: false }, ...`"
67+
text: "We encourage you to explicitly set `shell: false` in the options object to prevent shell interpretation. That is something like this: `execFile('git', ['blame', '--', filePath], { shell: false }, ...`",
6568
},
6669
{
6770
absent: String.raw`\(\s*[a-zA-Z_$][a-zA-Z0-9_$]*\s*,\s*[a-zA-Z_$][a-zA-Z0-9_$]*\s*,\s*[a-zA-Z_$][a-zA-Z0-9_$]*\s*\)\s*=>`,
68-
text: "Maintain the callback function structure with three parameters (typically named error, stdout, and stderr, but any valid variable names are acceptable)."
71+
text: "Maintain the callback function structure with three parameters (typically named error, stdout, and stderr, but any valid variable names are acceptable).",
6972
},
7073
{
7174
present: String.raw`\) \) =>`,
72-
text: "The `exec` function should be closed in later lines, not here."
75+
text: "The `exec` function should be closed in later lines, not here.",
7376
},
7477
],
7578
expected: [

docs/labs/assert.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Copyright (C) Open Source Security Foundation (OpenSSF) and its contributors.
2+
// SPDX-License-Identifier: MIT
3+
14
info =
25
{
36
hints: [
@@ -17,11 +20,11 @@ info =
1720
},
1821
{
1922
present: "(bindingresult|BindingResult)",
20-
text: "Java is case-sensitive. Use `bindingResult`, not `bindingresult` nor `BindingResult`."
23+
text: "Java is case-sensitive. Use `bindingResult`, not `bindingresult` nor `BindingResult`.",
2124
},
2225
{
2326
present: "(haserrors|HasErrors)",
24-
text: "Java is case-sensitive. Use `hasErrors`, not `haserrors` nor `HasErrors`."
27+
text: "Java is case-sensitive. Use `hasErrors`, not `haserrors` nor `HasErrors`.",
2528
},
2629
{
2730
present: String.raw`^\s*if\s*[^\(\s]`,
@@ -39,25 +42,25 @@ info =
3942
},
4043
{
4144
absent: String.raw`^ if \( bindingResult \. hasErrors \( \) \) `,
42-
text: "Begin the answer with the text `if (bindingResult.hasErrors())` so that a statement will be executed if that condition is true."
45+
text: "Begin the answer with the text `if (bindingResult.hasErrors())` so that a statement will be executed if that condition is true.",
4346
},
4447
{
4548
present: String.raw`if \( bindingResult \. hasErrors \( \) \) [^\{\s] `,
46-
text: "Follow the conditional with an open brace, e.g., `if (bindingResult.hasErrors()) {...`."
49+
text: "Follow the conditional with an open brace, e.g., `if (bindingResult.hasErrors()) {...`.",
4750
},
4851
{
4952
absent: String.raw`return "form"
5053
`,
51-
text: "You need to use `return \"form\";` somewhere."
54+
text: "You need to use `return \"form\";` somewhere.",
5255
},
5356
{
5457
present: String.raw`return "form"`,
5558
absent: String.raw`return "form" ;`,
56-
text: "You need to use `;` (semicolon) after `return \"form\"` because in Java statements must be followed by a semicolon."
59+
text: "You need to use `;` (semicolon) after `return \"form\"` because in Java statements must be followed by a semicolon.",
5760
},
5861
{
5962
absent: String.raw`\} $`,
60-
text: "The answer needs to end with `}` (closing brace)."
63+
text: "The answer needs to end with `}` (closing brace).",
6164
},
6265
],
6366
expected: [

0 commit comments

Comments
 (0)