diff --git a/changelog.d/12091.misc b/changelog.d/12091.misc
new file mode 100644
index 0000000000..def44987b4
--- /dev/null
+++ b/changelog.d/12091.misc
@@ -0,0 +1 @@
+Refuse to start if registration is enabled without email, captcha, or token-based verification unless new config flag `enable_registration_without_verification` is set.
diff --git a/demo/start.sh b/demo/start.sh
index 55e69685e3..5a9972d24c 100755
--- a/demo/start.sh
+++ b/demo/start.sh
@@ -38,6 +38,7 @@ for port in 8080 8081 8082; do
printf '\n\n# Customisation made by demo/start.sh\n\n'
echo "public_baseurl: http://localhost:$port/"
echo 'enable_registration: true'
+ echo 'enable_registration_without_verification: true'
echo ''
# Warning, this heredoc depends on the interaction of tabs and spaces.
diff --git a/docs/sample_config.yaml b/docs/sample_config.yaml
index 9c2359ed8e..a21b48ab2e 100644
--- a/docs/sample_config.yaml
+++ b/docs/sample_config.yaml
@@ -1218,10 +1218,18 @@ oembed:
# Registration can be rate-limited using the parameters in the "Ratelimiting"
# section of this file.
-# Enable registration for new users.
+# Enable registration for new users. Defaults to 'false'. It is highly recommended that if you enable registration,
+# you use either captcha, email, or token-based verification to verify that new users are not bots. In order to enable registration
+# without any verification, you must also set `enable_registration_without_verification`, found below.
#
#enable_registration: false
+# Enable registration without email or captcha verification. Note: this option is *not* recommended,
+# as registration without verification is a known vector for spam and abuse. Defaults to false. Has no effect
+# unless `enable_registration` is also enabled.
+#
+#enable_registration_without_verification: true
+
# Time that a user's session remains valid for, after they log in.
#
# Note that this is not currently compatible with guest logins.
diff --git a/docs/upgrade.md b/docs/upgrade.md
index f039710520..062e823333 100644
--- a/docs/upgrade.md
+++ b/docs/upgrade.md
@@ -108,6 +108,12 @@ for more information and instructions on how to fix a database with incorrect va
# Upgrading to v1.55.0
+## Open registration without verification is now disabled by default
+
+Synapse will refuse to start if registration is enabled without email, captcha, or token-based verification unless the new config
+flag `enable_registration_without_verification` is set to "true".
+
+
## `synctl` script has been moved
The `synctl` script
diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py
index ad2b7c9515..0f75e7b9d4 100644
--- a/synapse/app/homeserver.py
+++ b/synapse/app/homeserver.py
@@ -351,6 +351,23 @@ def setup(config_options: List[str]) -> SynapseHomeServer:
if config.server.gc_seconds:
synapse.metrics.MIN_TIME_BETWEEN_GCS = config.server.gc_seconds
+ if (
+ config.registration.enable_registration
+ and not config.registration.enable_registration_without_verification
+ ):
+ if (
+ not config.captcha.enable_registration_captcha
+ and not config.registration.registrations_require_3pid
+ and not config.registration.registration_requires_token
+ ):
+
+ raise ConfigError(
+ "You have enabled open registration without any verification. This is a known vector for "
+ "spam and abuse. If you would like to allow public registration, please consider adding email, "
+ "captcha, or token-based verification. Otherwise this check can be removed by setting the "
+ "`enable_registration_without_verification` config option to `true`."
+ )
+
hs = SynapseHomeServer(
config.server.server_name,
config=config,
diff --git a/synapse/config/registration.py b/synapse/config/registration.py
index ea9b50fe97..40fb329a7f 100644
--- a/synapse/config/registration.py
+++ b/synapse/config/registration.py
@@ -33,6 +33,10 @@ class RegistrationConfig(Config):
str(config["disable_registration"])
)
+ self.enable_registration_without_verification = strtobool(
+ str(config.get("enable_registration_without_verification", False))
+ )
+
self.registrations_require_3pid = config.get("registrations_require_3pid", [])
self.allowed_local_3pids = config.get("allowed_local_3pids", [])
self.enable_3pid_lookup = config.get("enable_3pid_lookup", True)
@@ -207,10 +211,18 @@ class RegistrationConfig(Config):
# Registration can be rate-limited using the parameters in the "Ratelimiting"
# section of this file.
- # Enable registration for new users.
+ # Enable registration for new users. Defaults to 'false'. It is highly recommended that if you enable registration,
+ # you use either captcha, email, or token-based verification to verify that new users are not bots. In order to enable registration
+ # without any verification, you must also set `enable_registration_without_verification`, found below.
#
#enable_registration: false
+ # Enable registration without email or captcha verification. Note: this option is *not* recommended,
+ # as registration without verification is a known vector for spam and abuse. Defaults to false. Has no effect
+ # unless `enable_registration` is also enabled.
+ #
+ #enable_registration_without_verification: true
+
# Time that a user's session remains valid for, after they log in.
#
# Note that this is not currently compatible with guest logins.
diff --git a/tests/config/test_registration_config.py b/tests/config/test_registration_config.py
index 17a84d20d8..2acdb6ac61 100644
--- a/tests/config/test_registration_config.py
+++ b/tests/config/test_registration_config.py
@@ -11,14 +11,16 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+
+import synapse.app.homeserver
from synapse.config import ConfigError
from synapse.config.homeserver import HomeServerConfig
-from tests.unittest import TestCase
+from tests.config.utils import ConfigFileTestCase
from tests.utils import default_config
-class RegistrationConfigTestCase(TestCase):
+class RegistrationConfigTestCase(ConfigFileTestCase):
def test_session_lifetime_must_not_be_exceeded_by_smaller_lifetimes(self):
"""
session_lifetime should logically be larger than, or at least as large as,
@@ -76,3 +78,19 @@ class RegistrationConfigTestCase(TestCase):
HomeServerConfig().parse_config_dict(
{"session_lifetime": "31m", "refresh_token_lifetime": "31m", **config_dict}
)
+
+ def test_refuse_to_start_if_open_registration_and_no_verification(self):
+ self.generate_config()
+ self.add_lines_to_config(
+ [
+ " ",
+ "enable_registration: true",
+ "registrations_require_3pid: []",
+ "enable_registration_captcha: false",
+ "registration_requires_token: false",
+ ]
+ )
+
+ # Test that allowing open registration without verification raises an error
+ with self.assertRaises(ConfigError):
+ synapse.app.homeserver.setup(["-c", self.config_file])
|