2020-07-02 03:40:54 +02:00
|
|
|
from typing import TYPE_CHECKING, Optional
|
|
|
|
|
2020-07-02 02:20:55 +02:00
|
|
|
import sentry_sdk
|
|
|
|
from sentry_sdk.integrations import Integration
|
|
|
|
from sentry_sdk.integrations.django import DjangoIntegration
|
sentry: Ignore all SuspiciousOperation loggers.
django.security.DisallowedHost is only one of a set of exceptions that
are "SuspiciousOperation" exceptions; all return a 400 to the user
when they bubble up[1]; all of them are uninteresting to Sentry.
While they may, in bulk, show a mis-configuration of some sort of the
application, such a failure should be detected via the increase in
400's, not via these, which are uninteresting individually.
While all of these are subclasses of SuspiciousOperation, we enumerate
them explicitly for a number of reasons:
- There is no one logger we can ignore that captures all of them.
Each of the errors uses its own logger, and django does not supply
a `django.security` logger that all of them feed into.
- Nor can we catch this by examining the exception object. The
SuspiciousOperation exception is raised too early in the stack for
us to catch the exception by way of middleware and check
`isinstance`. But at the Sentry level, in `add_context`, it is no
longer an exception but a log entry, and as such we have no
`isinstance` that can be applied; we only know the logger name.
- Finally, there is the semantic argument that while we have decided
to ignore this set of security warnings, we _may_ wish to log new
ones that may be added at some point in the future. It is better
to opt into those ignores than to blanket ignore all messages from
the security logger.
This moves the DisallowedHost `ignore_logger` to be adjacent to its
kin, and not on the middleware that may trigger it. Consistency is
more important than locality in this case.
Of these, the DisallowedHost logger if left as the only one that is
explicitly ignored in the LOGGING configuration in
`computed_settings.py`; it is by far the most frequent, and the least
likely to be malicious or impactful (unlike, say, RequestDataTooBig).
[1] https://docs.djangoproject.com/en/3.0/ref/exceptions/#suspiciousoperation
2020-08-12 04:06:04 +02:00
|
|
|
from sentry_sdk.integrations.logging import ignore_logger
|
2020-07-02 02:20:55 +02:00
|
|
|
from sentry_sdk.integrations.redis import RedisIntegration
|
|
|
|
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
2020-07-02 03:40:54 +02:00
|
|
|
from sentry_sdk.utils import capture_internal_exceptions
|
2020-07-02 02:20:55 +02:00
|
|
|
|
2020-07-28 02:09:57 +02:00
|
|
|
from version import ZULIP_VERSION
|
|
|
|
|
2020-07-02 02:20:55 +02:00
|
|
|
from .config import PRODUCTION
|
|
|
|
|
2020-07-02 03:40:54 +02:00
|
|
|
if TYPE_CHECKING:
|
|
|
|
from sentry_sdk._types import Event, Hint
|
|
|
|
|
2020-08-08 04:36:12 +02:00
|
|
|
def add_context(event: 'Event', hint: 'Hint') -> Optional['Event']:
|
|
|
|
if "exc_info" in hint:
|
|
|
|
_, exc_value, _ = hint["exc_info"]
|
|
|
|
# Ignore GeneratorExit, KeyboardInterrupt, and SystemExit exceptions
|
|
|
|
if not isinstance(exc_value, Exception):
|
|
|
|
return None
|
2020-07-02 03:40:54 +02:00
|
|
|
from zerver.models import get_user_profile_by_id
|
|
|
|
with capture_internal_exceptions():
|
|
|
|
user_info = event.get("user", {})
|
|
|
|
if user_info.get("id"):
|
|
|
|
user_profile = get_user_profile_by_id(user_info["id"])
|
|
|
|
user_info["realm"] = user_profile.realm.string_id or 'root'
|
2020-07-28 03:13:14 +02:00
|
|
|
user_info["role"] = user_profile.get_role_name()
|
2020-07-02 03:40:54 +02:00
|
|
|
return event
|
2020-07-02 02:20:55 +02:00
|
|
|
|
|
|
|
def setup_sentry(dsn: Optional[str], *integrations: Integration) -> None:
|
|
|
|
if not dsn:
|
|
|
|
return
|
|
|
|
sentry_sdk.init(
|
|
|
|
dsn=dsn,
|
|
|
|
environment="production" if PRODUCTION else "development",
|
2020-07-28 02:09:57 +02:00
|
|
|
release=ZULIP_VERSION,
|
2020-07-02 02:20:55 +02:00
|
|
|
integrations=[
|
|
|
|
DjangoIntegration(),
|
|
|
|
RedisIntegration(),
|
|
|
|
SqlalchemyIntegration(),
|
|
|
|
*integrations,
|
|
|
|
],
|
2020-07-02 03:40:54 +02:00
|
|
|
before_send=add_context,
|
2020-07-02 02:20:55 +02:00
|
|
|
)
|
sentry: Ignore all SuspiciousOperation loggers.
django.security.DisallowedHost is only one of a set of exceptions that
are "SuspiciousOperation" exceptions; all return a 400 to the user
when they bubble up[1]; all of them are uninteresting to Sentry.
While they may, in bulk, show a mis-configuration of some sort of the
application, such a failure should be detected via the increase in
400's, not via these, which are uninteresting individually.
While all of these are subclasses of SuspiciousOperation, we enumerate
them explicitly for a number of reasons:
- There is no one logger we can ignore that captures all of them.
Each of the errors uses its own logger, and django does not supply
a `django.security` logger that all of them feed into.
- Nor can we catch this by examining the exception object. The
SuspiciousOperation exception is raised too early in the stack for
us to catch the exception by way of middleware and check
`isinstance`. But at the Sentry level, in `add_context`, it is no
longer an exception but a log entry, and as such we have no
`isinstance` that can be applied; we only know the logger name.
- Finally, there is the semantic argument that while we have decided
to ignore this set of security warnings, we _may_ wish to log new
ones that may be added at some point in the future. It is better
to opt into those ignores than to blanket ignore all messages from
the security logger.
This moves the DisallowedHost `ignore_logger` to be adjacent to its
kin, and not on the middleware that may trigger it. Consistency is
more important than locality in this case.
Of these, the DisallowedHost logger if left as the only one that is
explicitly ignored in the LOGGING configuration in
`computed_settings.py`; it is by far the most frequent, and the least
likely to be malicious or impactful (unlike, say, RequestDataTooBig).
[1] https://docs.djangoproject.com/en/3.0/ref/exceptions/#suspiciousoperation
2020-08-12 04:06:04 +02:00
|
|
|
|
|
|
|
# Ignore all of the loggers from django.security that are for user
|
|
|
|
# errors; see https://docs.djangoproject.com/en/3.0/ref/exceptions/#suspiciousoperation
|
|
|
|
ignore_logger("django.security.DisallowedHost")
|
|
|
|
ignore_logger("django.security.DisallowedModelAdminLookup")
|
|
|
|
ignore_logger("django.security.DisallowedModelAdminToField")
|
|
|
|
ignore_logger("django.security.DisallowedRedirect")
|
|
|
|
ignore_logger("django.security.InvalidSessionKey")
|
|
|
|
ignore_logger("django.security.RequestDataTooBig")
|
|
|
|
ignore_logger("django.security.SuspiciousFileOperation")
|
|
|
|
ignore_logger("django.security.SuspiciousMultipartForm")
|
|
|
|
ignore_logger("django.security.SuspiciousSession")
|
|
|
|
ignore_logger("django.security.TooManyFieldsSent")
|