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
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)
14 Short answer: anywhere where user provided data is displayed (i.e. anywhere).
18 See [OWASP Cross Site Scripting document](https://owasp.org/www-community/attacks/xss/).
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
38 Issue can be encountered when writing SQL queries.
42 See [OWAP SQL Injection document](https://owasp.org/www-community/attacks/SQL_Injection).
46 Follow the instructions given on [backend database](./back-end/database.md) page.
48 ## Cross Site Request Forgery (CSRF)
52 Issue can be encountered when processing a request modifying a state on the server.
56 See [OWASP Cross Site Request Forgery document](https://owasp.org/www-community/attacks/csrf).
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).
71 Issue can be encountered when creating and executing OS command containing data provided by a user.
75 See [OWASP Command Injection document](https://owasp.org/www-community/attacks/Command_Injection).
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
84 * validate arguments against an allow list
85 * use `--` when possible to separate options from arguments
87 ## Server-Side Request Forgery (SSRF)
91 Issue can be encountered when doing an outbound HTTP request.
95 See [OWASP Server-Side Request Forgery document](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery).
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.
106 Everytime a new feature or endpoint is implemented.
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).
115 It must be ensured that the Tuleap Permissions model is respected and, if not possible, amended to include to cover the
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.
125 Special care must be taken when manipulating secrets/credentials to limit the possibility of leaking them.
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
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
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
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
163 Issue can be encountered when doing cryptographic operations such as encrypting, signing or hashing data.
167 See [OWASP Top 10 2021 - Cryptographic failures](https://owasp.org/Top10/A02_2021-Cryptographic_Failures/).
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