[[security-best-practices]]
== Security best practices

When writing code for {kib}, be sure to follow these best practices to avoid common vulnerabilities. Refer to the included Open Web
Application Security Project (OWASP) references to learn more about these types of attacks.

=== Cross-site Scripting (XSS) ===

https://owasp.org/www-community/attacks/xss[_OWASP reference for XSS_]

XSS is a class of attacks where malicious scripts are injected into vulnerable websites. {kib} defends against this by using the React
framework to safely encode data that is rendered in pages, the EUI framework to
https://elastic.github.io/eui/#/navigation/link#link-validation[automatically sanitize links], and a restrictive `Content-Security-Policy`
header.

*Best practices*

* Check for dangerous functions or assignments that can result in unescaped user input in the browser DOM. Avoid using:
** *React:* https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml[`dangerouslySetInnerHtml`].
** *Browser DOM:* `Element.innerHTML` and `Element.outerHTML`.
* If using the aforementioned unsafe functions or assignments is absolutely necessary, follow
https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#xss-prevention-rules[these XSS prevention
rules] to ensure that user input is not inserted into unsafe locations and that it is escaped properly.
* Use EUI components to build your UI, particularly when rendering `href` links. Otherwise, sanitize user input before rendering links to
ensure that they do not use the `javascript:` protocol.
* Don't use the `eval`, `Function`, and `_.template` functions -- these are restricted by ESLint rules.
* Be careful when using `setTimeout` and `setInterval` in client-side code. If an attacker can manipulate the arguments and pass a string to
one of these, it is evaluated dynamically, which is equivalent to the dangerous `eval` function.

=== Cross-Site Request Forgery (CSRF/XSRF) ===

https://owasp.org/www-community/attacks/csrf[_OWASP reference for CSRF_]

CSRF is a class of attacks where a user is forced to execute an action on a vulnerable website that they're logged into, usually without
their knowledge. {kib} defends against this by requiring
https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#use-of-custom-request-headers[custom
request headers] for API endpoints. For more information, see <<api-request-headers, API Request Headers>>.

*Best practices*

* Ensure all HTTP routes are registered with the <<http-service, {kib} HTTP service>> to take advantage of the custom request header
security control.
** Note that HTTP GET requests do *not* require the custom request header; any routes that change data should
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods[adhere to the HTTP specification and use a different method (PUT, POST, etc.)]

=== Remote Code Execution (RCE) ===

https://owasp.org/www-community/attacks/Command_Injection[_OWASP reference for Command Injection_],
https://owasp.org/www-community/attacks/Code_Injection[_OWASP reference for Code Injection_]

RCE is a class of attacks where an attacker executes malicious code or commands on a vulnerable server. {kib} defends against this by using
ESLint rules to restrict vulnerable functions, and by hooking into or hardening usage of these in third-party dependencies.

*Best practices*

* Don't use the `eval`, `Function`, and `_.template` functions -- these are restricted by ESLint rules.
* Don't use dynamic `require`.
* Check for usages of templating libraries. Ensure that user-provided input doesn't influence the template and is used only as data for
rendering the template.
* Take extra caution when spawning child processes with any user input or parameters that are user-controlled.

=== Prototype Pollution ===

Prototype Pollution is an attack that is unique to JavaScript environments. Attackers can abuse JavaScript's prototype inheritance to
"pollute" objects in the application, which is often used as a vector for XSS or RCE vulnerabilities. {kib} defends against this by
hardening sensitive functions (such as those exposed by `child_process`), and by requiring validation on all HTTP routes by default.

*Best practices*

* Check for instances of `anObject[a][b] = c` where `a`, `b`, and `c` are controlled by user input. This includes code paths where the
following logical code steps could be performed in separate files by completely different operations, or by recursively using dynamic
operations.
* Validate all user input, including API URL parameters, query parameters, and payloads. Preferably, use a schema that only allows specific
keys and values. At a minimum, implement a deny-list that prevents `__proto__` and `prototype.constructor` from being used within object
keys.
* When calling APIs that spawn new processes or perform code generation from strings, protect against Prototype Pollution by checking if
`Object.hasOwnProperty` has arguments to the APIs that originate from an Object. An example is the defunct Code app's
https://github.com/elastic/kibana/blob/b49192626a8528af5d888545fb14cd1ce66a72e7/x-pack/legacy/plugins/code/server/lsp/workspace_command.ts#L40-L44[`spawnProcess`]
function.
** Common Node.js offenders: `child_process.spawn`, `child_process.exec`, `eval`, `Function('some string')`, `vm.runInContext(x)`,
`vm.runInNewContext(x)`, `vm.runInThisContext()`
** Common client-side offenders: `eval`, `Function('some string')`, `setTimeout('some string', num)`, `setInterval('some string', num)`

See also:

* https://portswigger.net/daily-swig/prototype-pollution-the-dangerous-and-underrated-vulnerability-impacting-javascript-applications[Prototype
pollution: The dangerous and underrated vulnerability impacting JavaScript applications | portswigger.net]
* https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf[Prototype
pollution attack in NodeJS application | Olivier Arteau]

=== Server-Side Request Forgery (SSRF) ===

https://owasp.org/www-community/attacks/Server_Side_Request_Forgery[_OWASP reference for SSRF_]

SSRF is a class of attacks where a vulnerable server is forced to make an unintended request, usually to an HTTP API. This is often used as
a vector for information disclosure or injection attacks.

*Best practices*

* Ensure that all outbound requests from the {kib} server use hard-coded URLs.
* If user input is used to construct a URL for an outbound request, ensure that an allow-list is used to validate the endpoints and that
user input is escaped properly. Ideally, the allow-list should be set in `kibana.yml`, so only server administrators can change it.
** This is particularly relevant when using `transport.request` with the {es} client, as no automatic escaping is performed.
** Note that URLs are very hard to validate properly; exact match validation for user input is most preferable, while URL parsing or RegEx
validation should only be used if absolutely necessary.

=== Reverse tabnabbing ===

https://owasp.org/www-community/attacks/Reverse_Tabnabbing[_OWASP reference for Reverse Tabnabbing_]

Reverse tabnabbing is an attack where a link to a malicious page is used to rewrite a vulnerable parent page. This is often used as a vector
for phishing attacks. {kib} defends against this by using the EUI framework, which automatically adds the `rel` attribute to anchor tags,
buttons, and other vulnerable DOM elements.

*Best practices*

* Use EUI components to build your UI whenever possible. Otherwise, ensure that any DOM elements that have an `href` attribute also have the
`rel="noreferrer noopener"` attribute specified. For more information, refer to the
https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/HTML5_Security_Cheat_Sheet.md#tabnabbing[OWASP HTML5 Security Cheat
Sheet].
* If using a non-EUI markdown renderer, use a custom link renderer for rendered links.

=== Information disclosure ===

Information disclosure is not an attack, but it describes whenever sensitive information is accidentally revealed. This can be configuration
info, stack traces, or other data that the user is not authorized to access. This concern cannot be addressed with a single security
control, but at a high level, {kib} relies on the hapi framework to automatically redact stack traces and detailed error messages in HTTP
5xx response payloads.

*Best practices*

* Look for instances where sensitive information might accidentally be revealed, particularly in error messages, in the UI, and URL
parameters that are exposed to users.
* Make sure that sensitive request data is not forwarded to external resources. For example, copying client request headers and using them
to make an another request could accidentally expose the user's credentials.
