This is Tuleap 16.1.99.73
[tuleap.git] / doc / secure-coding-practices.md
blobf66580de2b28af039eee56fc4f6faf41a2a8a7d4
1 # Secure coding practices
3 This document covers description and expected resolution of security vulnerability that can be encountered when writing
4 code in the Tuleap codebase. The goal is to help developers identify security vulnerabilities early in the  development
5 process.
7 Contributions adding a new class of vulnerability or modifying the proposed mitigations are expected to be approved by a
8 member of the Tuleap Security team.
10 ## Cross Site Scripting (XSS)
12 ### When?
14 Short answer: anywhere where user provided data is displayed (i.e. anywhere).
16 ### What is this?
18 See [OWASP Cross Site Scripting document](https://owasp.org/www-community/attacks/xss/).
20 ### Mitigations
22 For code generating the content on the backend side, use [Mustache](./front-end/mustache.md).
24 For code generating the content on the frontend side, you should also use a template engine. Depending on the situation
25 it can be [Vue](./front-end/vue.md), [lit](https://lit.dev/docs/libraries/standalone-templates/), [hybrids](https://hybrids.js.org/)
26 or possibly [mustache.js](https://github.com/janl/mustache.js/).
28 For situations where user provided HTML code needs to be displayed it needs to be sanitized first:
29 * when building the content on the backend side, use [Codendi_HTMLPurifier](../src/common/include/Codendi_HTMLPurifier.class.php)
30 * when building the content on the frontend side, use [DOMPurify](https://github.com/cure53/DOMPurify). If you are
31   writing Vue code, use [vue-dompurify-html](https://github.com/LeSuisse/vue-dompurify-html) which provides a directive
32   to replace `v-html`.
34 ## SQL Injection
36 ### When?
38 Issue can be encountered when writing SQL queries.
40 ### What is this?
42 See [OWAP SQL Injection document](https://owasp.org/www-community/attacks/SQL_Injection).
44 ### Mitigations
46 Follow the instructions given on [backend database](./back-end/database.md) page.
48 ## Cross Site Request Forgery (CSRF)
50 ### When?
52 Issue can be encountered when processing a request modifying a state on the server.
54 ### What is this?
56 See [OWASP Cross Site Request Forgery document](https://owasp.org/www-community/attacks/csrf).
58 ### Mitigations
60 Make sure that requests that are expected to change a server state can only be done with the appropriate HTTP verb
61 (`POST`, `PUT`, `PATCH` or `DELETE`) and not with an HTTP verb that is expected to be used only to query data
62 (`GET`, `OPTIONS`, `HEAD`, `CONNECT` or `TRACE`).
64 When writing an HTML form, a CSRF synchronizer token is expected to be set and verified, See how to achieve that in [the
65 Mustache templating guide](./front-end/mustache.md).
67 ## Command Injection
69 ### When?
71 Issue can be encountered when creating and executing OS command containing data provided by a user.
73 ### What is this?
75 See [OWASP Command Injection document](https://owasp.org/www-community/attacks/Command_Injection).
77 ### Mitigations
79 Overall, passing user-supplied data to OS commands should preferably be avoided. If it is not possible due to
80 performance reasons or lack of alternatives:
81 * escape arguments: relying on the [Symfony Process component](https://symfony.com/doc/current/components/process.html)
82 is the preferred way to achieve that, [`escapeshellarg()`](https://www.php.net/manual/en/function.escapeshellarg) can be
83 used if necessary
84 * validate arguments against an allow list
85 * use `--` when possible to separate options from arguments
87 ## Server-Side Request Forgery (SSRF)
89 ### When?
91 Issue can be encountered when doing an outbound HTTP request.
93 ### What is this?
95 See [OWASP Server-Side Request Forgery document](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery).
97 ### Mitigations
99 Follow the instructions given on the [Making HTTP requests](./back-end/making-http-requests.md) page.
100 Internal requests needs to be distinguished from requests made for users.
102 ## Permissions
104 ### When?
106 Everytime a new feature or endpoint is implemented.
108 ### What is this?
110 See [OWASP document about access-control](https://owasp.org/www-community/Access_Control) and the [Tuleap Permissions
111 model](https://docs.tuleap.org/administration-guide/users-management/security/site-access.html).
113 ### Mitigations
115 It must be ensured that the Tuleap Permissions model is respected and, if not possible, amended to include to cover the
116 change.
118 The general guidelines about the [expected code](./expected-code.md) must be followed (especially regarding tests) and
119 reviewers must have a special point of vigilance.
121 ## Handling secrets
123 ### When?
125 Special care must be taken when manipulating secrets/credentials to limit the possibility of leaking them.
127 ### What is this?
129 Are considered secrets/sensitive information:
130 * login information such as a username/password
131 * Access keys and tokens (personal access keys, OAuth2 tokens…)
132 * Anything that can be used to authenticate or authorize accesses
134 ### Protection
136 #### At rest
138 Secrets stored in the database are expected to be:
139 * hashed in an appropriate manner when the need is only to compare it against another value
140   * passwords and user provided secrets must be hashed using a key derivation function designed for this use case, use
141     [`StandardPasswordHandler::computeHashPassword()`](../src/common/User/Password/StandardPasswordHandler.php)
142   * for randomly generated keys like personal access keys use the ["split token" pattern](../src/common/Authentication/SplitToken/)
143 * encrypted using [`SymmetricCrypto::encrypt()`](../src/common/Cryptography/Symmetric/SymmetricCrypto.php) if accessing
144   the plaintext value is required
146 #### While processing a request
148 * never log a secret
149 * use [`ConcealedString`](../src/common/Cryptography/ConcealedString.php) when manipulating a sensitive string to avoid
150   leaking inadvertently in a stack trace and preventing it to be serialized
151 * call [`sodium_memzero()`](https://www.php.net/manual/en/function.sodium-memzero.php) once you have wrapped your
152   sensitive string in a `ConcealedString` in order to try to limit  its exposure as much as possible
154 #### In transit
156 * use an encrypted channel like TLS (e.g. HTTPS) when transmitting or receiving credentials
157 * secrets should preferably be sent in the request body instead of the URL parameters as it is less likely to be logged
159 ## Cryptographic failures
161 ### When?
163 Issue can be encountered when doing cryptographic operations such as encrypting, signing or hashing data.
165 ### What is this?
167 See [OWASP Top 10 2021 - Cryptographic failures](https://owasp.org/Top10/A02_2021-Cryptographic_Failures/).
169 ### Mitigations
171 * For encrypting data see the previous section "Handling secrets"
172 * The [`Tuleap\Cryptography`](../src/common/Cryptography/) namespace offers hard to misuse interfaces for some symmetric
173  and asymmetric cryptography operations
174 * If your need is not covered by the existing solutions please reach out to a team member experienced in applied
175   cryptography. The following APIs can be used to design a solution solving your problem:
176   - [`hash()`](https://www.php.net/manual/en/function.hash.php) with SHA-256, SHA-384, SHA-512, SHA-512/256
177   - [`hash_hmac()`](https://www.php.net/manual/en/function.hash-hmac.php) with SHA-256, SHA-384, SHA-512, SHA-512/256
178   - [`sodium_*`](https://www.php.net/manual/en/book.sodium.php) functions