=================== Security guidelines =================== .. sectionauthor:: Bernhard Posselt , Lukas Reschke This guideline highlights some of the most common security problems and how to prevent them. Please review your app if it contains any of the following security holes. .. note:: **Program defensively**: for instance always check for CSRF or escape strings, even if you do not need it. This prevents future problems where you might miss a change that leads to a security hole. .. note:: All App Framework security features depend on the call of the controller through :php:meth:`OCA\\AppFramework\\App::main`. If the controller method is executed directly, no security checks are being performed! SQL injection ------------- `SQL Injection `_ occurs when SQL query strings are concatenated with variables. To prevent this, always use prepared queries: .. code-block:: php execute($params); If the App Framework is used, write SQL queries like this in a class that extends the Mapper: .. code-block:: php execute($sql, $params); Cross site scripting -------------------- `Cross site scripting `_ happens when user input is passed directly to templates. A potential attacker might be able to inject HTML/JavaScript into the page to steal the users session, log keyboard entries, even perform DDOS attacks on other websites or other malicious actions. Despite the fact that Nextcloud uses Content-Security-Policy to prevent the execution of inline JavaScript code developers are still required to prevent XSS. CSP is just another layer of defense that is not implemented in all web browsers. To prevent XSS in your app you have to sanitize the templates and all JavaScripts which performs a DOM manipulation. Templates ^^^^^^^^^ Let's assume you use the following example in your application: .. code-block:: php to overtake the user account. The same problem occurs when outputting content from the database or any other location that is writable by users. Another attack vector that is often overlooked is XSS in **href** attributes. HTML allows to execute JavaScript in href attributes like this:: To prevent XSS in your app, **never use echo, print() or <\%=** - use **p()** instead which will sanitize the input. Also **validate URLs to start with the expected protocol** (starts with http for instance)! .. note:: Should you ever require to print something unescaped, double check if it is really needed. If there is no other way (e.g. when including of subtemplates) use `print_unescaped` with care. JavaScript ^^^^^^^^^^ Avoid manipulating the HTML directly via JavaScript, this often leads to XSS since people often forget to sanitize variables: .. code-block:: js var html = '
  • ' + username + '
  • "'; If you **really** want to use JavaScript for something like this use `escapeHTML` to sanitize the variables: .. code-block:: js var html = '
  • ' + escapeHTML(username) + '
  • '; An even better way to make your app safer is to use the jQuery built-in function **$.text()** instead of **$.html()**. **DON'T** .. code-block:: js messageTd.html(username); **DO** .. code-block:: js messageTd.text(username); It may also be wise to choose a proper JavaScript framework like AngularJS which automatically handles the JavaScript escaping for you. Clickjacking ------------ `Clickjacking `_ tricks the user to click into an invisible iframe to perform an arbitrary action (e.g. delete a user account) To prevent such attacks Nextcloud sends the `X-Frame-Options` header to all template responses. Don't remove this header if you don't really need it! This is already built into Nextcloud in :php:class:`OC_Template`. Code executions / file inclusions --------------------------------- Code Execution means that an attacker is able to include an arbitrary PHP file. This PHP file runs with all the privileges granted to the normal application and can do an enormous amount of damage. Code executions and file inclusions can be easily prevented by **never** allowing user-input to run through the following functions: * **include()** * **require()** * **require_once()** * **eval()** * **fopen()** .. note:: Also **never** allow the user to upload files into a folder which is reachable from the URL! **DON'T** .. code-block:: php `_ occurs if PHP code executes shell commands (e.g. running a latex compiler). Before doing this, check if there is a PHP library that already provides the needed functionality. If you really need to execute a command be aware that you have to escape every user parameter passed to one of these functions: * **exec()** * **shell_exec()** * **passthru()** * **proc_open()** * **system()** * **popen()** .. note:: Please require/request additional programmers to audit your escape function. Without escaping the user input this will allow an attacker to execute arbitrary shell commands on your server. PHP offers the following functions to escape user input: * **escapeshellarg()**: Escape a string to be used as a shell argument * **escapeshellcmd()**: Escape shell metacharacters **DON'T** .. code-block:: php `_ (see also on `MDN `__) one can trick a user into executing a request that they did not want to make. Thus every POST and GET request needs to be protected against it. The only places where no CSRF checks are needed are in the main template, which is rendering the application, or in externally callable interfaces. .. note:: Submitting a form is also a POST/GET request! To prevent CSRF in an app, be sure to call the following method at the top of all your files: .. code-block:: php `_ (see also on `MDN `__) is a method implemented by browser to access resources from different domains at the same time. Assume, there is a website published on host A. The URL would for example be ``https://A/path/to/index.html``. If there is a _different_ host B that serves a resource (e.g. an image file) as ``https://B/assets/image.jpg``, the index file on host A could simply link to the image on B. However, to protect B and its property (the image), the browsers do not silently embed the image of B into the page of A. Instead, B is kindly asked by the browser if embedding is allowed (the so-called `preflight `_). To do so, there is a first request made to the resource on B with the ``OPTIONS`` HTTP command/verb. The server only answers with the headers as specified and adds ``Access-Control-*`` headers. These define, what the browser is to be allowed to do. Only if the destination server B confirms cross site resource sharing is allowed, the browser access the resource. Basically, accessing foreign resources is not limited to embedding images. Using JavaScript, arbitrary XHR/Ajax requests can be directed at arbitrary other hosts, which might be used to call APIs that leak your data. There are some safety measurements in place (especially about cookie handling), but one has still to be careful not to leak information unwillingly. Especially, if the destination server B allows to sent credentials using ``Access-Control-Allow-Credentials: true``, cross site scripting is very critical. You need :ref:`CSRF protection ` in place or your users are at relatively high risk. Getting help ------------ If you need help to ensure that a function is secure please ask on our `forum `_.