Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(capture): check token shape before team resolution too #14439

Merged
merged 3 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions posthog/api/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
TOKEN_SHAPE_INVALID_COUNTER = Counter(
"capture_token_shape_invalid_total",
"Events (soon to be) dropped due to an invalid token shape, per reason.",
labelnames=["reason"],
labelnames=["stage", "reason"],
)


Expand Down Expand Up @@ -193,7 +193,7 @@ def _get_sent_at(data, request) -> Tuple[Optional[datetime], Any]:
)


def _check_token_shape(token: str) -> Optional[str]:
def _check_token_shape(token: Optional[str]) -> Optional[str]:
if not token:
return "empty"
if len(token) > 64:
Expand Down Expand Up @@ -299,6 +299,16 @@ def get_event(request):
with start_span(op="request.authenticate"):
token = get_token(data, request)

try:
invalid_token_reason = _check_token_shape(token)
except Exception as e:
invalid_token_reason = "exception"
logger.warning("capture_token_shape_exception", token=token, reason="exception", exception=e)

if invalid_token_reason:
# TODO: start rejecting requests here if the after_resolution contexts are empty (no false-positives)
TOKEN_SHAPE_INVALID_COUNTER.labels(stage="before_resolution", reason=invalid_token_reason).inc()

if not token:
return cors_response(
request,
Expand Down Expand Up @@ -326,16 +336,10 @@ def get_event(request):
if db_error:
send_events_to_dead_letter_queue = True

try:
invalid_token_reason = _check_token_shape(token)
if invalid_token_reason:
# TODO: check the capture_token_shape_invalid_total metric for false positives,
# then move higher and refuse requests
TOKEN_SHAPE_INVALID_COUNTER.labels(reason=invalid_token_reason).inc()
logger.warning("capture_token_shape_invalid", token=token, reason=invalid_token_reason)
except Exception as e:
TOKEN_SHAPE_INVALID_COUNTER.labels(reason="exception").inc()
logger.warning("capture_token_shape_invalid", token=token, reason="exception", exception=e)
if invalid_token_reason:
# TODO: remove after we have proven we don't have false-positives
TOKEN_SHAPE_INVALID_COUNTER.labels(stage="after_resolution", reason=invalid_token_reason).inc()
logger.warning("capture_token_shape_false_positive", token=token, reason=invalid_token_reason)

team_id = ingestion_context.team_id if ingestion_context else None
structlog.contextvars.bind_contextvars(team_id=team_id)
Expand Down
4 changes: 2 additions & 2 deletions posthog/queries/funnels/test/__snapshots__/test_funnel.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,8 @@
HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id
WHERE team_id = 2
AND event IN ['$autocapture', 'user signed up', '$autocapture']
AND toTimeZone(timestamp, 'UTC') >= toDateTime('2023-02-20 00:00:00', 'UTC')
AND toTimeZone(timestamp, 'UTC') <= toDateTime('2023-02-27 23:59:59', 'UTC')
AND toTimeZone(timestamp, 'UTC') >= toDateTime('2023-02-21 00:00:00', 'UTC')
AND toTimeZone(timestamp, 'UTC') <= toDateTime('2023-02-28 23:59:59', 'UTC')
AND (step_0 = 1
OR step_1 = 1) ))
WHERE step_0 = 1 ))
Expand Down