Compare commits

...

12 Commits

Author SHA1 Message Date
Alex Vandiver
06810ab8d9 docs: Fix a typo in supported backups_compression_method values.
(cherry picked from commit bcdc2bd491)
2025-10-21 16:01:15 -04:00
Alex Vandiver
0430e25dcf docs: Update some broken links.
(cherry picked from commit ef238f2bf5)
2025-10-21 16:01:15 -04:00
Alya Abbott
1dbf60cb43 docs: Revamp production doc on security.
- Remove duplicative content.
- Move content to topic-focused pages.

(cherry picked from commit d3ca0fc7ae)
2025-10-21 16:01:15 -04:00
Alya Abbott
ccd99b2924 help: Organize details on bots overview page.
Also document can_forge_sender permission.

(cherry picked from commit be0fc99b58)
2025-10-21 16:01:15 -04:00
Alya Abbott
53da2d6b6f help: Add a note about DMs privacy model.
(cherry picked from commit 9e3fea7ed3)
2025-10-21 16:01:15 -04:00
Alya Abbott
31b75891bb help: Add links to related articles.
(cherry picked from commit 10ce39a82c)
2025-10-21 16:01:15 -04:00
Alya Abbott
d95f0f6eb6 help: Update password reset instructions for new UI.
(cherry picked from commit 0edacce98e)
2025-10-21 16:01:15 -04:00
Alya Abbott
909d48e2de docs: Clarify how security releases are done.
(cherry picked from commit 36a63f7963)
2025-10-21 10:37:53 -07:00
Lauryn Menard
75f6d543bb docs: Rename "security-model.md" to "securing-your-zulip-server.md".
Updates relative links and any "security-model" label for ref links.

(cherry picked from commit 04275d8e14)
2025-10-21 10:37:53 -07:00
Lauryn Menard
967ba5432c prod-template: Fix link for LDAP email sync unique ID.
(cherry picked from commit b4c63b73dc)
2025-10-21 10:37:53 -07:00
Alya Abbott
569d37afe5 docs: Reorganize authentication backends documentation.
(cherry picked from commit f20035e2ad)
2025-10-21 10:37:53 -07:00
Alex Vandiver
c4c189894b Revert "compose: Track when the recipient box has recently had focus."
This reverts commits 5ce956c9bb and
14c51bd0ec, which broke the compose box
in channels with "only general chat" set.

(cherry picked from commit 52ba675a26)
2025-10-21 14:30:14 +00:00
29 changed files with 410 additions and 496 deletions

View File

@@ -11,7 +11,7 @@ response within 24 hours.
Please include details on the issue and how you'd like to be credited
in our release notes when we publish the fix.
Our [security model][security-model] document may be a helpful
Our [security model][securing-your-zulip-server] document may be a helpful
resource.
## Security announcements
@@ -32,6 +32,6 @@ reason to run older major releases.
See also our documentation on the [Zulip release
lifecycle][release-lifecycle].
[security-model]: https://zulip.readthedocs.io/en/latest/production/security-model.html
[securing-your-zulip-server]: https://zulip.readthedocs.io/en/latest/production/securing-your-zulip-server.html
[upgrades]: https://zulip.readthedocs.io/en/stable/production/upgrade.html#upgrading-to-a-release
[release-lifecycle]: https://zulip.readthedocs.io/en/latest/overview/release-lifecycle.html

View File

@@ -6,7 +6,7 @@
# version e.g. to say that something is likely to have changed.
# For more info see: https://www.sphinx-doc.org/en/master/templating.html
#}
{% if pagename in ["production/system-configuration", "production/reverse-proxies"] and release.endswith('+git') %}
{% if pagename in ["production/securing-your-zulip-server"] and release.endswith('+git') %}
{#
# This page doesn't exist in the stable documentation yet.
# This temporary workaround prevents test failures and should be removed after the next release.

View File

@@ -60,5 +60,5 @@ Here are the top things to know:
to the _index_ (that is _stage_) with `git add`. _Commit_ to the HEAD of the
current branch with `git commit`.
[gitbook-basics]: https://git-scm.com/book/en/v2/Getting-Started-Git-Basics
[gitbook-basics]: https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository
[understanding-git]: https://web.mit.edu/nelhage/Public/git-slides-2009.pdf

View File

@@ -443,8 +443,8 @@ complicated rebase.
[gitbook-git-pull]: https://git-scm.com/docs/git-pull
[gitbook-git-rebase]: https://git-scm.com/docs/git-rebase
[gitbook-git-status]: https://git-scm.com/docs/git-status
[gitbook-other-envs-bash]: https://git-scm.com/book/en/v2/Git-in-Other-Environments-Git-in-Bash
[gitbook-other-envs-zsh]: https://git-scm.com/book/en/v2/Git-in-Other-Environments-Git-in-Zsh
[gitbook-other-envs-bash]: https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-Bash
[gitbook-other-envs-zsh]: https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-Zsh
[gitbook-rm]: https://git-scm.com/docs/git-rm
[github-help-closing-issues]: https://help.github.com/en/articles/closing-issues-via-commit-messages
[github-help-push]: https://help.github.com/en/articles/pushing-to-a-remote

View File

@@ -52,9 +52,12 @@ chamber with its own users, channels, customizations, and so on. This
means that one person might be a user of multiple Zulip realms. The
administrators of an organization have a great deal of control over
who can register an account, what permissions new users have, etc. For
more on security considerations and options, see [the security model
section](../production/security-model.md) and the [Zulip help
center](https://zulip.com/help/).
more on security considerations and options, see our [guide on securing
your Zulip server][security-guide], [security overview][security-overview],
and the [Zulip help center](https://zulip.com/help/).
[security-overview]: https://zulip.com/security/
[security-guide]: ../production/securing-your-zulip-server.md
## Components

View File

@@ -1842,8 +1842,8 @@ _Released 2023-05-31_
- Removed the `application_server.no_serve_uploads` setting in
`/etc/zulip/zulip.conf`, as all uploads requests go through Zulip now.
- Installations using the previously undocumented [JWT authentication
feature](../production/authentication-methods.md#jwt) will need
to make minor adjustments in the format of JWT requests; see the
feature](../production/authentication-methods.md#json-web-tokens-jwt) will
need to make minor adjustments in the format of JWT requests; see the
documentation for details on the new format.
- High volume log files like `server.log` are now by default retained
for 14 days, configured via the `access_log_retention_days`
@@ -1957,8 +1957,8 @@ _Released 2023-01-23_
[Rocket.Chat imports](https://zulip.com/help/import-from-rocketchat).
- Updated the Intercom integration to return success on `HEAD`
requests, which it uses to verify its configuration.
- Documented how each
[rate limit](../production/security-model.md#rate-limiting)
- Documented how each [rate
limit](../production/securing-your-zulip-server.md#6-understand-zulips-rate-limiting-system)
category is used.
- Documented the `reset_authentication_attempt_count` command for when users
lock themselves out.

View File

@@ -47,13 +47,14 @@ When we discover a security issue in Zulip, we publish a security and
bug fix release, transparently documenting the issue using the
industry-standard [CVE advisory process](https://cve.mitre.org/).
When new security releases are published, we simultaneously publish
the fixes to the `main` and stable release branches, so
that anyone using those branches can immediately upgrade as well.
When new security releases are published, we simultaneously publish the fixes to
the `main` branch and the release branch for the current major release series.
See also our [security model][security-model] documentation.
See also our [security overview][security-overview], and our [guide on securing
your Zulip server][securing-your-zulip-server].
[security-model]: ../production/security-model.md
[security-overview]: https://zulip.com/security/
[securing-your-zulip-server]: ../production/securing-your-zulip-server.md
### Git versions

View File

@@ -1,14 +1,34 @@
# Authentication methods
Zulip supports a wide variety of authentication methods. Some of them
require configuration to set up.
Zulip supports a wide variety of authentication methods:
- [Email and password](#email-and-password), which is enabled by default.
- [Social authentication](#social-authentication) with Google, GitHub,
and GitLab, which is easy to set up with a few lines of configuration.
Authentication with Apple additionally requires registering with Apple.
- [Microsoft Entra ID](#microsoft-entra-id) (AzureAD), which is similarly easy to
configure.
- [LDAP (including Active Directory)](#ldap-including-active-directory). Zulip
supports retrieving information about users via LDAP, and optionally using LDAP
as an authentication mechanism.
- [SAML](#saml), which is supported by Okta, OneLogin, Entra ID (AzureAD),
Keycloak, Auth0 and many other identity providers.
- [OpenID Connect](#openid-connect). Zulip can be integrated with any OpenID
Connect (OIDC) authentication provider.
- [JSON Web Tokens (JWT)](#json-web-tokens-jwt)
- [Apache-based SSO with `REMOTE_USER`](#apache-based-sso-with-remote_user)
To configure or disable authentication methods on your Zulip server,
edit the `AUTHENTICATION_BACKENDS` setting in
`/etc/zulip/settings.py`, as well as any additional configuration your
chosen authentication methods require; then restart the Zulip server.
Details on each method below.
If your authentication provider is not supported out-of-the-box, you can
configure [custom authentication backends](#custom-authentication-backends). If
you need help, best-effort community support is available in the [Zulip
development community](https://zulip.com/development-community/). To inquire
about options for custom development, [contact Zulip
Sales](mailto:sales@zulip.com).
## Email and password
@@ -21,21 +41,124 @@ email and password.
When first setting up your Zulip server, this method must be used for
creating the initial realm and user. You can disable it after that.
## Plug-and-play SSO (Google, GitHub, GitLab)
### Passwords
Zulip stores user passwords using the standard Argon2 algorithm.
When the user is choosing a password, Zulip checks the password's
strength using the popular [zxcvbn][zxcvbn] library. Weak passwords
are rejected, and strong passwords encouraged. The minimum password
strength allowed is controlled by two settings in
`/etc/zulip/settings.py`:
- `PASSWORD_MIN_LENGTH`: The minimum acceptable length, in characters.
Shorter passwords are rejected even if they pass the `zxcvbn` test
controlled by `PASSWORD_MIN_GUESSES`.
- `PASSWORD_MIN_GUESSES`: The minimum acceptable strength of the
password, in terms of the estimated number of passwords an attacker
is likely to guess before trying this one. If the user attempts to
set a password that `zxcvbn` estimates to be guessable in less than
`PASSWORD_MIN_GUESSES`, then Zulip rejects the password.
By default, `PASSWORD_MIN_GUESSES` is 10000. This provides
significant protection against online attacks, while limiting the
burden imposed on users choosing a password. See
[password strength](password-strength.md) for an extended
discussion on how we chose this value.
Estimating the guessability of a password is a complex problem and
impossible to efficiently do perfectly. For background or when
considering an alternate value for this setting, the article
["Passwords and the Evolution of Imperfect Authentication"][bhos15]
is recommended. The [2016 zxcvbn paper][zxcvbn-paper] adds useful
information about the performance of zxcvbn, and [a large 2012 study
of Yahoo users][bon12] is informative about the strength of the
passwords users choose.
<!---
If the BHOS15 link ever goes dead: it's reference 30 of the zxcvbn
paper, aka https://dl.acm.org/citation.cfm?id=2699390 , in the
_Communications of the ACM_ aka CACM. (But the ACM has it paywalled.)
.
Hooray for USENIX and IEEE: the other papers' canonical links are
not paywalled. The Yahoo study is reference 5 in BHOS15.
-->
[zxcvbn]: https://github.com/dropbox/zxcvbn
[bhos15]: http://www.cl.cam.ac.uk/~fms27/papers/2015-BonneauHerOorSta-passwords.pdf
[zxcvbn-paper]: https://www.usenix.org/system/files/conference/usenixsecurity16/sec16_paper_wheeler.pdf
[bon12]: http://ieeexplore.ieee.org/document/6234435/
## Social authentication
With just a few lines of configuration, your Zulip server can
authenticate users with any of several single-sign-on (SSO)
authentication providers:
authenticate users with:
- Google accounts, with `GoogleAuthBackend`
- GitHub accounts, with `GitHubAuthBackend`
- GitLab accounts, with `GitLabAuthBackend`
- Microsoft Entra ID (AzureAD), with `AzureADAuthBackend`
Each of these requires one to a handful of lines of configuration in
`settings.py`, as well as a secret in `zulip-secrets.conf`. Details
are documented in your `settings.py`.
### Sign in with Apple
Zulip supports using the web flow for Sign in with Apple on
self-hosted servers. To do so, you'll need to do the following:
1. Visit [the Apple Developer site][apple-developer] and [Create a
Services ID][apple-create-services-id]. When prompted for a "Return
URL", enter `https://zulip.example.com/complete/apple/` (using the
domain for your server).
1. Create a [Sign in with Apple private key][apple-create-private-key].
1. Store the resulting private key at
`/etc/zulip/apple-auth-key.p8`. Be sure to set
permissions correctly:
```bash
chown zulip:zulip /etc/zulip/apple-auth-key.p8
chmod 640 /etc/zulip/apple-auth-key.p8
```
1. Configure Apple authentication in `/etc/zulip/settings.py`:
- `SOCIAL_AUTH_APPLE_TEAM`: Your Team ID from Apple, which is a
string like "A1B2C3D4E5".
- `SOCIAL_AUTH_APPLE_SERVICES_ID`: The Services ID you created in
step 1, which might look like "com.example.services".
- `SOCIAL_AUTH_APPLE_APP_ID`: The App ID, or Bundle ID, of your
app that you used in step 1 to configure your Services ID.
This might look like "com.example.app".
- `SOCIAL_AUTH_APPLE_KEY`: Despite the name this is not a key, but
rather the Key ID of the key you created in step 2. This looks
like "F6G7H8I9J0".
- `AUTHENTICATION_BACKENDS`: Uncomment (or add) a line like
`'zproject.backends.AppleAuthBackend',` to enable Apple auth
using the created configuration.
1. Register with Apple the email addresses or domains your Zulip
server sends email to users from. For instructions and background,
see the "Email Relay Service" subsection of
[this page][apple-get-started]. For details on what email
addresses Zulip sends from, see our
[outgoing email documentation][outgoing-email].
[apple-create-services-id]: https://help.apple.com/developer-account/?lang=en#/dev1c0e25352
[apple-developer]: https://developer.apple.com/account/resources/
[apple-create-private-key]: https://help.apple.com/developer-account/?lang=en#/dev77c875b7e
[apple-get-started]: https://developer.apple.com/sign-in-with-apple/get-started/
[outgoing-email]: email.md
## Microsoft Entra ID
Set up authentication with Microsoft Entra ID (AzureAD) by modifying the
`AzureADAuthBackend` configuration in `settings.py`, as well as a secret in
`zulip-secrets.conf`. Details are documented in your `settings.py`.
(ldap)=
## LDAP (including Active Directory)
@@ -45,10 +168,10 @@ optionally using LDAP as an authentication mechanism.
In either configuration, you will need to do the following:
1. These instructions assume you have an installed Zulip server and
are logged into a shell there. You can have created an
organization already using EmailAuthBackend, or plan to create the
organization using LDAP authentication.
1. [Install a Zulip server](./install.md), and log into a shell.
1. _(optional)_ Create an organization using EmailAuthBackend. Alternately, you
can plan to create the organization using LDAP authentication.
1. Tell Zulip how to connect to your LDAP server:
@@ -815,7 +938,7 @@ integration](../production/scim.md).
### Using Authentik as a SAML IdP
1. Make sure you reviewed [this article](https://goauthentik.io/integrations/services/zulip/), which
1. Make sure you reviewed [this article](https://integrations.goauthentik.io/chat-communication-collaboration/zulip/), which
details how to integrate Zulip with Authentik.
1. Verify that `SOCIAL_AUTH_SAML_ENABLED_IDPS[{idp_name}]['entity_id']` and
`SOCIAL_AUTH_SAML_ENABLED_IDPS[{idp_name}]['url']` are correct in your Zulip
@@ -1040,56 +1163,6 @@ to debug.
sees the cookie, treats them as logged in, and proceeds to serve
them the main app page normally.
## Sign in with Apple
Zulip supports using the web flow for Sign in with Apple on
self-hosted servers. To do so, you'll need to do the following:
1. Visit [the Apple Developer site][apple-developer] and [Create a
Services ID.][apple-create-services-id]. When prompted for a "Return
URL", enter `https://zulip.example.com/complete/apple/` (using the
domain for your server).
1. Create a [Sign in with Apple private key][apple-create-private-key].
1. Store the resulting private key at
`/etc/zulip/apple-auth-key.p8`. Be sure to set
permissions correctly:
```bash
chown zulip:zulip /etc/zulip/apple-auth-key.p8
chmod 640 /etc/zulip/apple-auth-key.p8
```
1. Configure Apple authentication in `/etc/zulip/settings.py`:
- `SOCIAL_AUTH_APPLE_TEAM`: Your Team ID from Apple, which is a
string like "A1B2C3D4E5".
- `SOCIAL_AUTH_APPLE_SERVICES_ID`: The Services ID you created in
step 1, which might look like "com.example.services".
- `SOCIAL_AUTH_APPLE_APP_ID`: The App ID, or Bundle ID, of your
app that you used in step 1 to configure your Services ID.
This might look like "com.example.app".
- `SOCIAL_AUTH_APPLE_KEY`: Despite the name this is not a key, but
rather the Key ID of the key you created in step 2. This looks
like "F6G7H8I9J0".
- `AUTHENTICATION_BACKENDS`: Uncomment (or add) a line like
`'zproject.backends.AppleAuthBackend',` to enable Apple auth
using the created configuration.
1. Register with Apple the email addresses or domains your Zulip
server sends email to users from. For instructions and background,
see the "Email Relay Service" subsection of
[this page][apple-get-started]. For details on what email
addresses Zulip sends from, see our
[outgoing email documentation][outgoing-email].
[apple-create-services-id]: https://help.apple.com/developer-account/?lang=en#/dev1c0e25352
[apple-developer]: https://developer.apple.com/account/resources/
[apple-create-private-key]: https://help.apple.com/developer-account/?lang=en#/dev77c875b7e
[apple-get-started]: https://developer.apple.com/sign-in-with-apple/get-started/
[outgoing-email]: email.md
## OpenID Connect
Zulip can be integrated with any OpenID Connect (OIDC) authentication
@@ -1123,7 +1196,7 @@ assumes the name is correct, and new users will not be presented with
a registration form unless they need to accept Terms of Service for
the server (i.e. `TERMS_OF_SERVICE_VERSION` is set).
## JWT
## JSON Web Tokens (JWT)
Zulip supports using JSON Web Tokens (JWT) authentication in two ways:
@@ -1146,7 +1219,9 @@ configure the JWT secret and algorithm via `JWT_AUTH_KEYS` in
`/etc/zulip/settings.py`; see the inline comment documentation in that
file for details.
## Configuring a custom Python wrapper around the `authenticate` mechanism
## Custom authentication backends
### Configuring a custom Python wrapper around the `authenticate` mechanism
Zulip supports configuring a custom authentication function that will
work as a wrapper around every login attempt to Zulip, enabling custom
@@ -1239,11 +1314,11 @@ request), this is where it should happen.
[django-authenticate-details]: https://docs.djangoproject.com/en/5.0/topics/auth/customizing/#writing-an-authentication-backend
## Adding more authentication backends
### Adding more authentication backends
Adding an integration with any of the more than 100 authentication
providers supported by [python-social-auth][python-social-auth] (e.g.,
Facebook, Twitter, etc.) is easy to do if you're willing to write a
Facebook, X, etc.) is easy to do if you're willing to write a
bit of code, and pull requests to add new backends are welcome.
For example, the

View File

@@ -49,10 +49,10 @@ email addresses and send notifications.
For sending outgoing email from your Zulip server, we highly recommend
using a "transactional email" service like
[Mailgun](https://documentation.mailgun.com/en/latest/quickstart-sending.html#send-via-smtp),
[SendGrid](https://sendgrid.com/docs/API_Reference/SMTP_API/integrating_with_the_smtp_api.html),
[Mailgun](https://documentation.mailgun.com/docs/mailgun/user-manual/sending-messages/send-smtp),
[SendGrid](https://www.twilio.com/docs/sendgrid/for-developers/sending-email/integrating-with-the-smtp-api),
or, for AWS users,
[Amazon SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-smtp.html).
[Amazon SES](https://docs.aws.amazon.com/ses/latest/dg/send-email-smtp.html).
These services are designed to send email from servers, and are by far
the easiest way to get outgoing email working reliably (Mailgun has
the best documentation).

View File

@@ -14,7 +14,7 @@ system-configuration
mobile-push-notifications
upgrade
modify
security-model
securing-your-zulip-server
authentication-methods
export-and-import
postgresql

View File

@@ -192,7 +192,8 @@ Learning more:
server administrators. This extremely low-traffic list is for
important announcements, including [new
releases](../overview/release-lifecycle.md) and security issues.
- Follow [Zulip on Twitter](https://twitter.com/zulip).
- Follow us on [Mastodon](https://fosstodon.org/@zulip) or
[X/Twitter](https://x.com/zulip).
- Learn how to [configure your Zulip server settings](settings.md).
- Learn about [Backups, export and import](export-and-import.md)
and [upgrading](upgrade.md) a production Zulip

View File

@@ -13,7 +13,7 @@ Moved to [Troubleshooting](troubleshooting.md#monitoring).
### Securing your Zulip server
Moved to [Security model](security-model.md).
Moved to [Securing your Zulip server](securing-your-zulip-server.md).
### Upgrading

View File

@@ -8,8 +8,8 @@ When a user tries to set a password, we use [zxcvbn][zxcvbn] to check
that it isn't a weak one.
See discussion in [our main docs for server
admins](security-model.md#passwords). This doc explains in more
detail how we set the default threshold (`PASSWORD_MIN_GUESSES`) we use.
admins](authentication-methods.md#email-and-password). This doc explains in
more detail how we set the default threshold (`PASSWORD_MIN_GUESSES`) we use.
First, read the doc section there. (It's short.)

View File

@@ -0,0 +1,160 @@
# Securing your Zulip server
This page offers practical information on how to secure your Zulip server. For a
deeper understanding of the security model, take a look at Zulip's [security
overview](https://zulip.com/security/).
Here are some best practices for keeping your Zulip server secure:
1. [Limit shell access to a small set of trusted individuals.](#1-limit-shell-access-to-a-small-set-of-trusted-individuals)
2. [Consider requiring authentication with single sign-on (SSO).](#2-consider-requiring-authentication-with-single-sign-on-sso)
3. [Teach users how to protect their account.](#3-teach-users-how-to-protect-their-account)
4. [Become familiar with Zulip's access management model.](#4-become-familiar-with-zulips-access-management-model)
5. [Understand security for user-uploaded content and user-generated requests.](#5-understand-security-for-user-uploaded-content-and-user-generated-requests)
6. [Understand Zulip's rate-limiting system.](#6-understand-zulips-rate-limiting-system)
If you believe you've identified a security issue, please report it to Zulip's
security team at [security@zulip.com](mailto:security@zulip.com) as soon as
possible, so that we can address it and make a responsible disclosure.
## 1. Limit shell access to a small set of trusted individuals.
Anyone with root access to a Zulip application server or Zulip database server,
or with access to the `zulip` user on a Zulip application server, has _complete
control over the Zulip installation_ and all of its data (so they can read
messages, modify history, etc.). This means that _only trusted individuals_
should have shell access to your Zulip server.
## 2. Consider requiring authentication with single sign-on (SSO).
The preferred way to log in to Zulip is using a single sign-on (SSO)
solution like Google authentication, LDAP, or similar, but Zulip
also supports password authentication. See [the authentication
methods documentation](authentication-methods.md) for
details on Zulip's available authentication methods.
## 3. Teach users how to protect their account.
Every Zulip user has an API key, which can be used to do essentially everything
that users can do when they're logged in. Make sure users know to immediately
[reset their API key and password](https://zulip.com/help/protect-your-account)
if their credentials are compromised (e.g., their cell phone is lost or stolen).
## 4. Become familiar with Zulip's access management model.
Zulip's help center offers a detailed overview of Zulip's permissions management
system. Reading the following guides will give you a good starting point:
- [Channel types and permissions](https://zulip.com/help/channel-permissions)
- [User roles](https://zulip.com/help/user-roles)
- [User groups](https://zulip.com/help/user-groups)
- [Restrict message editing and deletion](https://zulip.com/help/restrict-message-editing-and-deletion)
- [Bots overview](https://zulip.com/help/bots-overview)
## 5. Understand security for user-uploaded content and user-generated requests.
- Zulip supports user-uploaded files. Ideally they should be hosted
from a separate domain from the main Zulip server to protect against
various same-domain attacks (e.g., zulip-user-content.example.com).
We support two ways of hosting them: the basic `LOCAL_UPLOADS_DIR`
file storage backend, where they are stored in a directory on the
Zulip server's filesystem, and the S3 backend, where the files are
stored in Amazon S3. It would not be difficult to add additional
supported backends should there be a need; see
`zerver/lib/upload.py` for the full interface.
For both backends, the URLs used to access uploaded files are long,
random strings, providing one layer of security against unauthorized
users accessing files uploaded in Zulip (an authorized user would
need to share the URL with an unauthorized user in order for the
file to be accessed by the unauthorized user. Of course, any
such authorized user could have just downloaded and sent the file
instead of the URL, so this is arguably pretty good protection.)
However, to help protect against accidental sharing of URLs to
restricted files (e.g., by forwarding a missed-message email or leaks
involving the Referer header), every access to an uploaded file has
access control verified (confirming that the browser is logged into
a Zulip account that has received the uploaded file in question).
- Zulip supports using the [go-camo][go-camo] image proxy to proxy content like
inline image previews, that can be inserted into the Zulip message feed by
other users. This ensures that clients do not make requests to external
servers to fetch images, improving privacy.
- By default, Zulip will provide image previews inline in the body of
messages when a message contains a link to an image. You can
control this using the `INLINE_IMAGE_PREVIEW` setting.
- Zulip may make outgoing HTTP connections to other servers in a
number of cases:
- Outgoing webhook bots (creation of which can be restricted)
- Inline image previews in messages (enabled by default, but can be disabled)
- Inline webpage previews and embeds (must be configured to be enabled)
- Twitter message previews (must be configured to be enabled)
- BigBlueButton and Zoom API requests (must be configured to be enabled)
- Mobile push notifications (must be configured to be enabled)
- Notably, these first 3 features give end users (limited) control to cause
the Zulip server to make HTTP requests on their behalf. Because of this,
Zulip routes all outgoing HTTP requests [through
Smokescreen][smokescreen-setup] to ensure that Zulip cannot be
used to execute [SSRF attacks][ssrf] against other systems on an
internal corporate network. The default Smokescreen configuration
denies access to all non-public IP addresses, including 127.0.0.1.
The Camo image server does not, by default, route its traffic
through Smokescreen, since Camo includes logic to deny access to
private subnets; this can be [overridden][proxy.enable_for_camo].
[go-camo]: https://github.com/cactus/go-camo
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
[smokescreen-setup]: deployment.md#customizing-the-outgoing-http-proxy
[proxy.enable_for_camo]: system-configuration.md#enable_for_camo
## 6. Understand Zulip's rate-limiting system.
Zulip has built-in rate limiting of login attempts, all access to the
API, as well as certain other types of actions that may be involved in
abuse. For example, the email confirmation flow, by its nature, needs
to allow sending an email to an email address that isn't associated
with an existing Zulip account. Limiting the ability of users to
trigger such emails helps prevent bad actors from damaging the spam
reputation of a Zulip server by sending confirmation emails to random
email addresses.
The default rate limiting rules for a Zulip server will change as we improve
the product. A server administrator can browse the current rules using
`/home/zulip/deployments/current/scripts/get-django-setting
RATE_LIMITING_RULES`; or with comments by reading
`DEFAULT_RATE_LIMITING_RULES` in `zproject/default_settings.py`.
Server administrators can tweak rate limiting in the following ways in
`/etc/zulip/settings.py`:
- The `RATE_LIMITING` setting can be set to `False` to completely
disable all rate-limiting.
- The `RATE_LIMITING_RULES` setting can be used to override specific
rules. See the comment in the file for more specific details on how
to do it. After changing the setting, we recommend using
`/home/zulip/deployments/current/scripts/get-django-setting
RATE_LIMITING_RULES` to verify your changes. You can then restart
the Zulip server with `scripts/restart-server` to have the new
configuration take effect.
- The `RATE_LIMIT_TOR_TOGETHER` setting can be set to `True` to group all
known exit nodes of [TOR](https://www.torproject.org/) together for purposes
of IP address limiting. Since traffic from a client using TOR is distributed
across its exit nodes, without enabling this setting, TOR can otherwise be
used to avoid IP-based rate limiting. The updated list of TOR exit nodes
is refetched once an hour.
- If a user runs into the rate limit for login attempts, a server
administrator can clear this state using the
`manage.py reset_authentication_attempt_count`
[management command][management-commands].
See also our [API documentation on rate limiting][rate-limit-api].
[management-commands]: ../production/management-commands.md
[rate-limit-api]: https://zulip.com/api/rest-error-handling#rate-limit-exceeded

View File

@@ -1,320 +0,0 @@
# Security model
This section attempts to document the Zulip security model. It likely
does not cover every issue; if there are details you're curious about,
please feel free to ask questions in [#production
help](https://chat.zulip.org/#narrow/channel/31-production-help) on the
[Zulip community server](https://zulip.com/development-community/) (or if you
think you've found a security bug, please report it to
security@zulip.com so we can do a responsible security
announcement).
## Secure your Zulip server like your email server
- It's reasonable to think about security for a Zulip server like you
do security for a team email server -- only trusted individuals
within an organization should have shell access to the server.
In particular, anyone with root access to a Zulip application server
or Zulip database server, or with access to the `zulip` user on a
Zulip application server, has complete control over the Zulip
installation and all of its data (so they can read messages, modify
history, etc.). It would be difficult or impossible to avoid this,
because the server needs access to the data to support features
expected of a group chat system like the ability to search the
entire message history, and thus someone with control over the
server has access to that data as well.
## Encryption and authentication
- Traffic between clients (web, desktop and mobile) and the Zulip
server is encrypted using HTTPS. By default, all Zulip services
talk to each other either via a localhost connection or using an
encrypted SSL connection.
- Zulip requires CSRF tokens in all interactions with the web API to
prevent CSRF attacks.
- The preferred way to log in to Zulip is using a single sign-on (SSO)
solution like Google authentication, LDAP, or similar, but Zulip
also supports password authentication. See [the authentication
methods documentation](authentication-methods.md) for
details on Zulip's available authentication methods.
### Passwords
Zulip stores user passwords using the standard Argon2 and PBKDF2
algorithms. Argon2 is used for all new and changed passwords as of
Zulip Server 1.6.0, but legacy PBKDF2 passwords that were last changed
before the 1.6.0 upgrade are still supported.
When the user is choosing a password, Zulip checks the password's
strength using the popular [zxcvbn][zxcvbn] library. Weak passwords
are rejected, and strong passwords encouraged. The minimum password
strength allowed is controlled by two settings in
`/etc/zulip/settings.py`:
- `PASSWORD_MIN_LENGTH`: The minimum acceptable length, in characters.
Shorter passwords are rejected even if they pass the `zxcvbn` test
controlled by `PASSWORD_MIN_GUESSES`.
- `PASSWORD_MIN_GUESSES`: The minimum acceptable strength of the
password, in terms of the estimated number of passwords an attacker
is likely to guess before trying this one. If the user attempts to
set a password that `zxcvbn` estimates to be guessable in less than
`PASSWORD_MIN_GUESSES`, then Zulip rejects the password.
By default, `PASSWORD_MIN_GUESSES` is 10000. This provides
significant protection against online attacks, while limiting the
burden imposed on users choosing a password. See
[password strength](password-strength.md) for an extended
discussion on how we chose this value.
Estimating the guessability of a password is a complex problem and
impossible to efficiently do perfectly. For background or when
considering an alternate value for this setting, the article
["Passwords and the Evolution of Imperfect Authentication"][bhos15]
is recommended. The [2016 zxcvbn paper][zxcvbn-paper] adds useful
information about the performance of zxcvbn, and [a large 2012 study
of Yahoo users][bon12] is informative about the strength of the
passwords users choose.
<!---
If the BHOS15 link ever goes dead: it's reference 30 of the zxcvbn
paper, aka https://dl.acm.org/citation.cfm?id=2699390 , in the
_Communications of the ACM_ aka CACM. (But the ACM has it paywalled.)
.
Hooray for USENIX and IEEE: the other papers' canonical links are
not paywalled. The Yahoo study is reference 5 in BHOS15.
-->
[zxcvbn]: https://github.com/dropbox/zxcvbn
[bhos15]: http://www.cl.cam.ac.uk/~fms27/papers/2015-BonneauHerOorSta-passwords.pdf
[zxcvbn-paper]: https://www.usenix.org/system/files/conference/usenixsecurity16/sec16_paper_wheeler.pdf
[bon12]: http://ieeexplore.ieee.org/document/6234435/
## Messages and history
- Zulip message content is rendered using a specialized Markdown
parser which escapes content to protect against cross-site scripting
attacks.
- Zulip supports both public channels and private channels.
- Any non-guest user can join any public channel in the organization,
and can view the complete message history of any public channel
without joining the channel. Guests can only access channels that
another user adds them to.
- Organization owners and administrators can see and modify most
aspects of a private channel, including the membership and
estimated traffic. Owners and administrators generally cannot see
messages sent to private channels or do things that would
indirectly give them access to those messages, like adding members
or changing the channel privacy settings.
- Non-admins cannot easily see which private channels exist, or interact
with them in any way until they are added. Given a channel name, they can
figure out whether a channel with that name exists, but cannot see any
other details about the channel.
- See [channel types and permissions](https://zulip.com/help/channel-permissions)
for more details.
- Zulip supports editing the content and topics of messages that have
already been sent. As a general philosophy, our policies provide
hard limits on the ways in which message content can be changed or
undone. In contrast, our policies around message topics favor
usefulness (e.g., for conversational organization) over faithfulness
to the original. In all configurations:
- Message content can only ever be modified by the original author.
- Organization administrators can configure who has permission to
delete their own message, and who can delete other users'
messages that they can see.
- See
[Restrict message editing and deletion](https://zulip.com/help/restrict-message-editing-and-deletion)
for more details.
## Users and bots
- There are several types of users in a Zulip organization: organization
owners, organization administrators, members (normal users), guests,
and bots.
- Owners and administrators have the ability to deactivate and
reactivate other human and bot users, archive channels, add/remove
administrator privileges, as well as change configuration for the
organization.
Being an organization administrator does not generally provide the ability
to read other users' direct messages or messages sent to private
channels to which the administrator is not subscribed. There are two
exceptions:
- Organization owners may get access to direct messages via some types of
[data export](https://zulip.com/help/export-your-organization).
- Administrators can change the ownership of a bot. If a bot is subscribed
to a private channel, then an administrator can indirectly get access to
channel messages by taking control of the bot, though the access will be
limited to what the bot can do. (e.g., incoming webhook bots cannot read
messages.)
- Every Zulip user has an API key, available on the settings page.
This API key can be used to do essentially everything the user can
do; for that reason, users should keep their API key safe. Users
can rotate their own API key if it is accidentally compromised.
- To properly remove a user's access to a Zulip team, it does not
suffice to change their password or deactivate their account in a
single sign-on (SSO) system, since neither of those prevents
authenticating with the user's API key or those of bots the user has
created. Instead, you should [deactivate the user's
account](https://zulip.com/help/deactivate-or-reactivate-a-user) via
Zulip's "Organization settings" interface.
- The Zulip mobile apps authenticate to the server by sending the
user's password and retrieving the user's API key; the apps then use
the API key to authenticate all future interactions with the site.
Thus, if a user's phone is lost, in addition to changing passwords,
you should rotate the user's Zulip API key.
- Guest users are like Members, but they do not have automatic access
to public channels.
- Zulip supports several kinds of bots with different capabilities.
- Incoming webhook bots can only send messages into Zulip.
- Outgoing webhook bots and Generic bots can essentially do anything a
non-administrator user can, with a few exceptions (e.g., a bot cannot
log in to the web application, register for mobile push
notifications, or create other bots).
- Bots with the `can_forge_sender` permission can send messages that appear to have been sent by
another user. They also have the ability to see the names of all
channels, including private channels. This is important for implementing
integrations like the Jabber, IRC, and Zephyr mirrors.
These bots cannot be created by Zulip users, including
organization owners. They can only be created on the command
line (via `manage.py change_user_role can_forge_sender`).
## User-uploaded content and user-generated requests
- Zulip supports user-uploaded files. Ideally they should be hosted
from a separate domain from the main Zulip server to protect against
various same-domain attacks (e.g., zulip-user-content.example.com).
We support two ways of hosting them: the basic `LOCAL_UPLOADS_DIR`
file storage backend, where they are stored in a directory on the
Zulip server's filesystem, and the S3 backend, where the files are
stored in Amazon S3. It would not be difficult to add additional
supported backends should there be a need; see
`zerver/lib/upload.py` for the full interface.
For both backends, the URLs used to access uploaded files are long,
random strings, providing one layer of security against unauthorized
users accessing files uploaded in Zulip (an authorized user would
need to share the URL with an unauthorized user in order for the
file to be accessed by the unauthorized user. Of course, any
such authorized user could have just downloaded and sent the file
instead of the URL, so this is arguably pretty good protection.)
However, to help protect against accidental sharing of URLs to
restricted files (e.g., by forwarding a missed-message email or leaks
involving the Referer header), every access to an uploaded file has
access control verified (confirming that the browser is logged into
a Zulip account that has received the uploaded file in question).
- Zulip supports using the [go-camo][go-camo] image proxy to proxy content like
inline image previews, that can be inserted into the Zulip message feed by
other users. This ensures that clients do not make requests to external
servers to fetch images, improving privacy.
- By default, Zulip will provide image previews inline in the body of
messages when a message contains a link to an image. You can
control this using the `INLINE_IMAGE_PREVIEW` setting.
- Zulip may make outgoing HTTP connections to other servers in a
number of cases:
- Outgoing webhook bots (creation of which can be restricted)
- Inline image previews in messages (enabled by default, but can be disabled)
- Inline webpage previews and embeds (must be configured to be enabled)
- Twitter message previews (must be configured to be enabled)
- BigBlueButton and Zoom API requests (must be configured to be enabled)
- Mobile push notifications (must be configured to be enabled)
- Notably, these first 3 features give end users (limited) control to cause
the Zulip server to make HTTP requests on their behalf. Because of this,
Zulip routes all outgoing HTTP requests [through
Smokescreen][smokescreen-setup] to ensure that Zulip cannot be
used to execute [SSRF attacks][ssrf] against other systems on an
internal corporate network. The default Smokescreen configuration
denies access to all non-public IP addresses, including 127.0.0.1.
The Camo image server does not, by default, route its traffic
through Smokescreen, since Camo includes logic to deny access to
private subnets; this can be [overridden][proxy.enable_for_camo].
[go-camo]: https://github.com/cactus/go-camo
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
[smokescreen-setup]: deployment.md#customizing-the-outgoing-http-proxy
[proxy.enable_for_camo]: system-configuration.md#enable_for_camo
## Rate limiting
Zulip has built-in rate limiting of login attempts, all access to the
API, as well as certain other types of actions that may be involved in
abuse. For example, the email confirmation flow, by its nature, needs
to allow sending an email to an email address that isn't associated
with an existing Zulip account. Limiting the ability of users to
trigger such emails helps prevent bad actors from damaging the spam
reputation of a Zulip server by sending confirmation emails to random
email addresses.
The default rate limiting rules for a Zulip server will change as we improve
the product. A server administrator can browse the current rules using
`/home/zulip/deployments/current/scripts/get-django-setting
RATE_LIMITING_RULES`; or with comments by reading
`DEFAULT_RATE_LIMITING_RULES` in `zproject/default_settings.py`.
Server administrators can tweak rate limiting in the following ways in
`/etc/zulip/settings.py`:
- The `RATE_LIMITING` setting can be set to `False` to completely
disable all rate-limiting.
- The `RATE_LIMITING_RULES` setting can be used to override specific
rules. See the comment in the file for more specific details on how
to do it. After changing the setting, we recommend using
`/home/zulip/deployments/current/scripts/get-django-setting
RATE_LIMITING_RULES` to verify your changes. You can then restart
the Zulip server with `scripts/restart-server` to have the new
configuration take effect.
- The `RATE_LIMIT_TOR_TOGETHER` setting can be set to `True` to group all
known exit nodes of [TOR](https://www.torproject.org/) together for purposes
of IP address limiting. Since traffic from a client using TOR is distributed
across its exit nodes, without enabling this setting, TOR can otherwise be
used to avoid IP-based rate limiting. The updated list of TOR exit nodes
is refetched once an hour.
- If a user runs into the rate limit for login attempts, a server
administrator can clear this state using the
`manage.py reset_authentication_attempt_count`
[management command][management-commands].
See also our [API documentation on rate limiting][rate-limit-api].
[management-commands]: ../production/management-commands.md
[rate-limit-api]: https://zulip.com/api/rest-error-handling#rate-limit-exceeded
## Final notes and security response
If you find some aspect of Zulip that seems inconsistent with this
security model, please report it to security@zulip.com so that we can
investigate and coordinate an appropriate security release if needed.
Zulip security announcements will be sent to
zulip-announce@googlegroups.com, so you should subscribe if you are
running Zulip in production.

View File

@@ -304,7 +304,7 @@ value. Also supported is "[S3 Reduced Redundancy][s3-rr]", by setting
What compression method to use when storing backups; defaults to `lz4`, which is
fast but does not compress particularly well. Other options are `lzma`, `zstd`,
and `brotl`; `lzma` provides the best (and slowest) compression, while `zstd`
and `brotli`; `lzma` provides the best (and slowest) compression, while `zstd`
and `brotli` are middling compromises.
#### `missing_dictionaries`

View File

@@ -794,7 +794,7 @@ confirm everything is working correctly.
3. Follow [Debian's instructions to upgrade the OS][bullseye-upgrade].
[bullseye-upgrade]: https://www.debian.org/releases/bullseye/amd64/release-notes/ch-upgrading.html
[bullseye-upgrade]: https://www.debian.org/releases/bullseye/amd64/release-notes.en.txt
When prompted for you how to upgrade configuration
files for services that Zulip manages like Redis, PostgreSQL,

View File

@@ -168,7 +168,7 @@ The file uploads bucket should have a policy of:
```
The file-uploads bucket should not be world-readable. See the
[documentation on the Zulip security model](security-model.md) for
[documentation on the Zulip security model](securing-your-zulip-server.md) for
details on the security model for uploaded files.
However, the avatars bucket is intended to be world-readable, so its

View File

@@ -81,7 +81,7 @@ preparing a new release.
- Email to [zulip-announce](https://groups.google.com/g/zulip-announce)
- Email to [zulip-blog-announce](https://groups.google.com/a/zulip.com/g/zulip-blog-announce)
- Message in [#announce](https://chat.zulip.org/#narrow/channel/1-announce)
- Tweet from [@zulip](https://twitter.com/zulip).
- Tweet from [@zulip](https://x.com/zulip).
- Toot from [fosstodon.org/@zulip](https://fosstodon.org/@zulip)
### Post-release

View File

@@ -48,7 +48,7 @@ to check out your branch.
- [QuickTime](https://support.apple.com/en-in/HT201066)
- [GIPHY](https://giphy.com/apps/giphycapture)
- [CloudApp](https://www.getcloudapp.com)
- [Zight](https://zight.com)
- [Kap](https://getkap.co)
- [Gifski](https://sindresorhus.com/gifski)
- [Gyazo GIF](https://gyazo.com/en)
@@ -57,7 +57,6 @@ to check out your branch.
- [ScreenToGif](https://www.screentogif.com)
- [Gyazo GIF](https://gyazo.com/en)
- [Monosnap](https://monosnap.com)
### Linux

View File

@@ -40,31 +40,32 @@ Generic | Like a normal user account | Automating tasks, bots that listen to all
Incoming webhook | Limited to only sending messages into Zulip | Automated notifications into Zulip
Outgoing webhook | Generic bot that also receives new messages via HTTP post requests | Third party integrations, most custom bots
It's generally best to pick the most restricted bot type that is sufficient
to do the task at hand. Anyone with the bot's API key can do anything the
bot can.
A **generic** bot acts like a normal Zulip user that can only access Zulip via
the API. There's a handful of actions bots can't take, including creating other
bots.
A few more details:
An **outgoing webhook** bot can read direct messages where the bot
is a participant, and channel messages where the bot is
[mentioned](/help/mention-a-user-or-group). When the bot is DM'd or
mentioned, it POSTs the message content to a URL of your choice. The
POST request format can be in a Zulip format or a Slack-compatible
format. This is the preferred bot type for interactive bots built on
top of Zulip Botserver.
* Bots can send messages to any channel that their owner can,
inheriting their owner's [sending permissions](/help/channel-posting-policy).
* Bots can be subscribed to channels, and their role can be modified if
they need to have permission to do administrative actions.
* [Channel permissions](/help/channel-permissions) are the same for bots
as for other users. Therefore, for private channels with protected
history, a bot can only access messages sent after it was subscribed
to the channel.
* **Generic**: A generic bot is like a normal Zulip user account that
cannot log in via a browser. Note that if you truly want to
impersonate yourself (e.g., write messages that come from your Zulip
account), you'll need to use your **personal API key**.
* **Outgoing webhook**: The bot can read direct messages where the bot
is a participant, and channel messages where the bot is
[mentioned](/help/mention-a-user-or-group). When the bot is DM'd or
mentioned, it POSTs the message content to a URL of your choice. The
POST request format can be in a Zulip format or a Slack-compatible
format. This is the preferred bot type for interactive bots built on
top of Zulip Botserver.
Use the most limited bot type that supports your integration. Anyone with the
bot's API key can do anything the bot can, so giving bots unnecessary
permissions can expose your organization to unnecessary risk.
## Channel permissions for bots
Bots can be subscribed to channels, and assigned [channel
permissions](/help/channel-permissions) just like human users. In private
channels with protected history, a bot can only access messages sent after it
was subscribed to the channel.
Bots can send messages to any channel that their owner can, inheriting their
owner's [sending permissions](/help/channel-posting-policy). You can give a bot
channel management permissions, just like you would for a human user.
## Adding bots
@@ -73,6 +74,20 @@ Zulip organization, but administrators can
[restrict bot creation](/help/restrict-bot-creation). Any bot that is added
is visible and available for anyone to use.
## Integrations that act on behalf of users
If you want an integration to impersonate you (e.g., write messages that come
from your Zulip account), use your [personal API key](/api/api-keys), rather
than a bot's API key. You won't need to create a bot.
If you need a bot to send messages on behalf of multiple users, ask [Zulip
support](mailto:support@zulip.com) or your server administrator to run the
`manage.py change_user_role can_forge_sender` command to give a bot
permission to send messages as users in your organization. Bots with the
`can_forge_sender` permission can also see the names of all channels,
including private channels. This is important for implementing integrations
like the Jabber and IRC mirrors.
## Related articles
* [Integrations overview](/help/integrations-overview)

View File

@@ -14,8 +14,14 @@ account.
{settings_tab|account-and-privacy}
1. Under **Account**, click on the password field (it should look like `********`).
1. Under **Account**, click **Change your password**.
1. Enter your old password and your new password, and click **Change**.
{end_tabs}
## Related articles
* [Logging in](/help/logging-in)
* [Logging out](/help/logging-out)

View File

@@ -69,6 +69,12 @@ for your organization.
[community-norms]: https://zulip.com/development-community/#community-norms
[development-community-channels]: https://zulip.com/development-community/#channels-for-zulip-users-and-administrators
## Security
If you believe you've identified a security issue, please report it to Zulip's
security team at [security@zulip.com](mailto:security@zulip.com) as soon as
possible, so that we can address it and make a responsible disclosure.
## Related articles
* [Zulip Cloud billing](/help/zulip-cloud-billing)

View File

@@ -2,7 +2,10 @@
**Direct messages (DMs)** are conversations with other users that happen outside
of a [channel](/help/introduction-to-channels). They are convenient for 1:1 and
small group conversations.
small group conversations. Direct messages are private to conversation participants. Administrators may be
able to [export](/help/export-your-organization) your DMs in a corporate
organization, or [with your
permission](/help/export-your-organization#configure-whether-administrators-can-export-your-private-data).
If you find yourself frequently conversing with the same person or group, it
often works best to [create a private channel](/help/create-a-channel) for your

View File

@@ -737,7 +737,7 @@
</tr>
<tr>
<td class="comparison-table-feature">
<a href="https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#plug-and-play-sso-google-github-gitlab">SSO with Microsoft Entra ID</a>
<a href="https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#microsoft-entra-id">SSO with Microsoft Entra ID</a>
</td>
<td class="comparison-value-negative cloud-cell"><i class="icon icon-x"></i></td>
<td class="comparison-value-positive cloud-cell"><i class="icon icon-check"></i></td>

View File

@@ -4,9 +4,11 @@ priority.
## Security basics
- All Zulip clients (web, mobile, desktop, terminal, and integrations)
require TLS encryption and authentication over HTTPS for all data
transmission between clients and the server, both on LAN and the Internet.
- All Zulip clients (web, mobile, desktop, terminal, and integrations) require
TLS encryption and authentication over HTTPS for all data transmission between
clients and the server, both on LAN and the Internet. By default, all Zulip
services talk to each other either via a localhost connection or using an
encrypted SSL connection.
- All Zulip Cloud customer data is encrypted at rest. Self-hosted Zulip can be
configured for encryption at rest via your hosting provider, or by setting up
hardware and software disk encryption of the database and other data storage
@@ -20,6 +22,8 @@ priority.
[deployed on multiple servers](https://zulip.readthedocs.io/en/latest/production/deployment.html),
all connections between parts of the Zulip infrastructure can be secured
with TLS or SSH.
- Zulip requires CSRF tokens in all interactions with the web API to
prevent CSRF attacks.
- Message content can be
[excluded from mobile push notifications][redact-content],
to avoid displaying message content on locked mobile screens, and to

View File

@@ -576,12 +576,6 @@ export function initialize() {
});
$("textarea#compose-textarea").on("focus", () => {
// To shortcut a delay otherwise introduced when the topic
// input is blurred, we immediately update the topic's
// displayed text and compose-area placeholder when the
// compose textarea is focused.
const $input = $("input#stream_message_recipient_topic");
compose_recipient.update_topic_displayed_text($input.val());
compose_recipient.update_compose_area_placeholder_text();
compose_fade.do_update_all();
if (narrow_state.narrowed_by_reply()) {
@@ -611,25 +605,20 @@ export function initialize() {
compose_validate.validate_and_update_send_button_status();
});
// To track delayed effects originating from the "blur" event
// and its use of setTimeout, we need to set up a variable to
// reference the timeout's ID across events.
let recipient_focused_timeout;
$("input#stream_message_recipient_topic").on("focus", () => {
// We don't want the `recently-focused` class removed via
// a setTimeout from the "blur" event, if we're suddenly
// focused again.
clearTimeout(recipient_focused_timeout);
const $compose_recipient = $("#compose-recipient");
const $input = $("input#stream_message_recipient_topic");
compose_recipient.update_topic_displayed_text($input.val(), true);
compose_recipient.update_compose_area_placeholder_text();
// When the topic input is focused, we no longer treat
// the recipient row as low attention, as we assume the user
// is doing something that requires keeping attention called
// to the recipient row.
// to the recipient row
compose_recipient.set_high_attention_recipient_row();
$compose_recipient.addClass("recently-focused");
$("input#stream_message_recipient_topic").one("blur", () => {
compose_recipient.update_topic_displayed_text($input.val());
compose_recipient.update_compose_area_placeholder_text();
});
});
$("input#stream_message_recipient_topic").on("input", () => {
@@ -638,41 +627,14 @@ export function initialize() {
});
$("#private_message_recipient").on("focus", () => {
// We don't want the `.recently-focused` class removed via
// setTimeout from the "blur" event, if we're suddenly
// focused again.
clearTimeout(recipient_focused_timeout);
const $compose_recipient = $("#compose-recipient");
// When the DM input is focused, we no longer treat
// the recipient row as low attention, as we assume the user
// is doing something that requires keeping attention called
// to the recipient row
compose_recipient.set_high_attention_recipient_row();
$compose_recipient.addClass("recently-focused");
});
$("input#stream_message_recipient_topic, #private_message_recipient").on("blur", () => {
const $compose_recipient = $("#compose-recipient");
const $input = $("input#stream_message_recipient_topic");
// To correct for an edge case when clearing the topic box
// via the left sidebar, we do the following actions after a
// delay; these will not have an effect for DMs, and so can
// safely be referenced here. Note, too, that if focus shifts
// immediately from the topic box to the compose textarea,
// we update these things immediately so that no delay is
// apparent on the topic's displayed text or the placeholder
// in the empty compose textarea.
// Also, in case a user quickly opens and closes the compose
// box, we need to clear a previously set timeout before
// setting a new one. Otherwise, the compose box can open
// in a strange state displaying *general chat* and italicizing
// the topic input.
clearTimeout(recipient_focused_timeout);
recipient_focused_timeout = setTimeout(() => {
compose_recipient.update_topic_displayed_text($input.val());
compose_recipient.update_compose_area_placeholder_text();
$compose_recipient.removeClass("recently-focused");
}, 500);
compose_recipient.update_recipient_row_attention_level();
});

View File

@@ -1247,10 +1247,9 @@ textarea.new_message_textarea {
interactions (e.g., Shift-Tabbing from the compose textarea
to the topic box) show instant changes, so we don't need to
accommodate them here, which we prevent by applying the
transitions only when focus isn't within the recipient row,
or hasn't recently been within the topic box. */
transitions only when focus isn't within the recipient row. */
#compose.compose-box-open {
.low-attention-recipient-row:not(.recently-focused, :focus-within) {
.low-attention-recipient-row:hover:not(:focus-within) {
#compose_select_recipient_widget,
#compose_recipient_box,
#compose-direct-recipient .pill-container {

View File

@@ -243,7 +243,7 @@ AUTH_LDAP_USER_ATTR_MAP = {
#
## A stable unique identifier for a user allows Zulip to
## automatically handle email address changes.
## See https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#identifying-user-accounts-via-a-unique-ldap-attribute
## See https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#synchronizing-email-addresses
# "unique_account_id": "objectSid",
##
## Profile pictures can be pulled from the LDAP "thumbnailPhoto"/"jpegPhoto" field.
@@ -580,7 +580,7 @@ SOCIAL_AUTH_SAML_SUPPORT_CONTACT = {
## into Zulip or to fetch users' API keys. The JWT secret key and
## algorithm must be configured here.
##
## See https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#jwt
## See https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#json-web-tokens-jwt
# JWT_AUTH_KEYS = {
# # Subdomain for which this JWT configuration will apply.
# "zulip": {