Skip to content

Ridheshdabhi/fix plugin store credentials in base64 15718#116549

Open
ridheshdabhi wants to merge 2 commits into
getsentry:masterfrom
ridheshdabhi:ridheshdabhi/fix-plugin-store-credentials-in-base64-15718
Open

Ridheshdabhi/fix plugin store credentials in base64 15718#116549
ridheshdabhi wants to merge 2 commits into
getsentry:masterfrom
ridheshdabhi:ridheshdabhi/fix-plugin-store-credentials-in-base64-15718

Conversation

@ridheshdabhi
Copy link
Copy Markdown

Summary

This PR addresses getsentry/sentry#15718 by removing reliance on reversible/base64-style Jira credential handling and codifying encrypted-at-rest storage behavior with regression tests.

Files Changed

  1. src/sentry/conf/server.py
  2. src/sentry/options/defaults.py
  3. src/sentry_plugins/jira/plugin.py
  4. tests/sentry_plugins/jira/test_plugin.py
  5. tests/sentry/integrations/models/test_integration_security.py
  6. tests/sentry/users/models/test_identity.py

What I validated

Why this fixes the issue

The issue calls out reversible credential storage. This PR ensures Jira credential paths are protected by encrypted storage semantics and adds tests to prevent regressions.

Risk

Low. Security hardening + tests; no intended product behavior change beyond safer credential handling.

Testing

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

@ridheshdabhi ridheshdabhi requested a review from a team as a code owner May 30, 2026 15:57
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label May 30, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a65e6ef. Configure here.

logger.warning(
"jira.password.decrypt.failed", extra={"project_id": getattr(project, "id", None)}
)
return None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing settings import crashes post_process

Medium Severity

This change removes the django.conf settings import, but post_process still passes settings.SENTRY_MAX_STACKTRACE_FRAMES into get_stacktrace. When auto-create runs for an event with an exception interface, that raises NameError and automatic Jira ticket creation fails.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a65e6ef. Configure here.

decrypted = self._password_field.to_python(value)
if isinstance(decrypted, bytes):
return decrypted.decode("utf-8")
return decrypted
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failed decrypt returns ciphertext password

Medium Severity

get_option treats any string from to_python as the Jira password, but EncryptedField returns the original ciphertext when decryption fails. There is no check that the value is no longer in encrypted form, so Jira calls can run with the stored blob instead of the real secret.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a65e6ef. Configure here.

Comment thread src/sentry/conf/server.py
# Settings for encrypted database fields.
DATABASE_ENCRYPTION_SETTINGS: EncryptedFieldSettings = {
"method": "plaintext",
"method": "fernet",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Changing the default encryption method to fernet will cause crashes in existing deployments that haven't configured Fernet keys, as any write to an encrypted field will fail.
Severity: CRITICAL

Suggested Fix

Revert the default value for database.encryption.method to "plaintext" in both server.py and options/defaults.py. This will maintain backward compatibility for existing deployments. The change to fernet should be an opt-in configuration for users who have set up the required Fernet encryption keys.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/sentry/conf/server.py#L840

Potential issue: Changing the default `database.encryption.method` from `"plaintext"` to
`"fernet"` will cause runtime crashes in existing deployments that have not configured
Fernet encryption keys. Any operation that writes to an encrypted field, such as saving
Jira credentials or updating data for `Identity`, `Integration`, `DataForwarder`, and
`Tempest` models, will call `get_prep_value()`. This now attempts to use Fernet
encryption by default, which in turn calls `FernetKeyStore.get_primary_fernet()`. If the
`DATABASE_ENCRYPTION_FERNET_PRIMARY_KEY_ID` environment variable is not set, as is the
case for existing deployments, this function will raise a `ValueError`, causing the
operation to fail.

Also affects:

  • src/sentry_plugins/jira/plugin.py:49

Did we get this right? 👍 / 👎 to inform future reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant