Bitwarden

bitwarden.com
Bitwarden

Fully-featured, open source password manager with cloud-sync. Bitwarden is easy-to-use with a clean UI and client apps for desktop, web and mobile. See also Vaultwarden, a self-hosted, Rust implementation of the Bitwarden server and compatible with upstream Bitwarden clients.

Open Source

Bitwarden Privacy Policy

Privacy Policy Summary

  • The service provider makes no warranty regarding uninterrupted, timely, secure or error-free service
  • The service does not guarantee that software errors will be corrected
  • This service prohibits users from attempting to gain unauthorized access to other computer systems
  • This service gives your personal data to third parties involved in its operation
  • The court of law governing the terms is in California, USA
  • Some personal data may be kept for business interests or legal obligations
  • Information is provided about what kind of information they collect
  • Information is provided about how they collect personal data
  • Information is provided about how your personal data is used
  • Users are responsible for any risks, damages, or losses they may incur by downloading materials
  • The service is provided 'as is' and to be used at the users' sole risk
  • Features of the website are made available under a free software license (AGPL) v3.0
  • The terms for this service are easy to read
  • You authorise the service to charge a credit card supplied on re-occurring basis
  • You are entitled to a refund if certain thresholds or standards are not met by the service
  • Promises will be kept after a merger or acquisition
  • You are tracked via web beacons, tracking pixels, browser fingerprinting, and/or device fingerprinting
  • A list of all cookies set by the website is provided
  • The service provides two factor authentification for your account
  • Information is provided about how your personal data is collected
  • This service claims User-generated content is encrypted, and they can not decrypt it

Score

B

Documents

Domains Covered by Policy

  • bitwarden.com
  • bitwarden.eu
  • passwordless.dev

About the Data

This data is kindly provided by tosdr.org. Read full report at: #1348

Bitwarden Source Code

Author

bitwarden

Description

Bitwarden infrastructure/backend (API, database, Docker, etc).

#api#aspnet#aspnetcore#bitwarden#csharp#docker#dotnet#dotnet-core#signalr#sql#sql-server

Homepage

https://bitwarden.com

Repository

  • LicenseOther
  • Created23 Nov 15
  • Primary languageC#
  • Size67,358 KB
  • Stars20,244
  • Forks1,784
  • Watchers20,244

Language Usage

Language Usage

Project Health

  • Last commit15 hours ago
  • Open issues246
  • Latest releasev2026.9.2

Top Contributors

Recent Commits

  • cyprain-okeke(07 Oct 26)

    [PM-44226] feat: add PamSeatMinimum column to Organization (#8521) Each organization's Privileged Controls seat minimum is locked in at its first purchase and must not follow later changes to the pricing-service default, so it has to live on the organization row. This adds a nullable INT column across both ORM tracks, mirroring the PM-40097 PamSeats change: entity property, SSDT table/view/Organization_Create/Organization_Update/ Organization_ReadManyByIds, an idempotent dated MSSQL migration that refreshes dependent views, and generated EF migrations for MySQL, Postgres and SQLite. Schema only. Nothing reads or writes the column yet: saving it belongs to PM-40117 and PM-43247, checking it to PM-40114. Existing rows stay NULL and sproc parameters default to NULL, so behavior is unchanged.

  • Justin Baur(07 Oct 26)

    [PM-41442] refactor: Migrate Admin Console to the SDK IFeatureService (#8509) * [PM-41442] refactor: Migrate Admin Console to the SDK IFeatureService * Fully qualify SDK feature types instead of aliasing * Substitute the SDK IFeatureService in SCIM user integration tests PostUserCommand now resolves Bitwarden.Server.Sdk.Features.IFeatureService, so substituting the legacy interface no longer reaches it and the flag-on branch of Post_Success went unexercised.

  • Oscar Hinton(07 Oct 26)

    [PAM-190] PAM access audit: API (#8507)

  • Nick Krantz(06 Oct 26)

    refactor: remove unused PM22136_SdkCipherEncryption feature flag (#8465) Remove the pm-22136-sdk-cipher-encryption feature flag as it is no longer referenced anywhere in the codebase.

  • Nick Krantz(06 Oct 26)

    [PM-31626] chore: Remove autofill button view login screen flag (#8495) The pm-30521-autofill-button-view-login-screen feature flag is no longer needed and can be removed from the server constants.

  • Kyle Denney(06 Oct 26)

    [PM-44448] fix: Keep the trial when redeeming the annual upgrade offer (#8519) * [PM-44448] fix: Keep the trial when rebuilding subscription schedule phases Redeeming the annual billing offer during a free trial created a schedule whose current phase omitted the trial, so Stripe ended the trial on the spot and invoiced a full month that was never credited once the annual phase began. Every schedule phase rewrite now carries the source phase's trial end, so a trialing subscription stays in trial through redemption and later seat or tax updates, and moves to annual billing at trial end. * [PM-44448] fix: Show the pending annual upgrade to trialing organizations Redeeming the annual offer during a trial now keeps the subscription trialing, with the annual phase starting at the trial end. The pending upgrade query only accepted active subscriptions, so these organizations saw no notice of the upcoming switch to annual billing. * [PM-44448] fix: Keep the trial when rebuilding price-increase schedule phases The seat and storage update and the churn offer redemption rebuild the live phase of a price-increase schedule without its trial end. These schedules are created for organizations on legacy plans, so they are not expected on a trialing subscription, but copying the trial end keeps every organization phase rebuild consistent with the others on this branch.

  • Rui Tomé(06 Oct 26)

    [PM-42938] fix: validate collection access when creating a group (#8374) * [PM-42938] Extract group collection access validation into a validator * [PM-42938] Validate collection access when creating a group * [PM-42938] Use CombGuid.Generate instead of deprecated GenerateComb * [PM-42938] Trim integration tests to the happy path * [PM-42938] Simplify comments * [PM-42938] Remove redundant test comments * [PM-42938] Return typed errors from GroupCollectionAccessValidator

  • Jared McCannon(06 Oct 26)

    [PM-42993] - Fix Bulk Collection Cipher Save (#8415) * Blocking a user from making changes to ciphers that are only in the default cipher collection. * Added fix to allow for ciphers to be edited when allowed when cipher is in both shared and default collection. also allow for cipher to be removed from shared collection when also in default collection. * Allow already shared ciphers to continue to be shared if they have access. * added test to check that a user could remove a cipher from their own default collection * removing local function. * fixed up if statements and tests

  • renovate[bot](06 Oct 26)

    [deps] DbOps: Update linq2db to v6.5.0 and linq2db.EntityFrameworkCore to v8.8.0 (#6767) * [deps]: Update linq2db to v6 * fix: use Microsoft.EntityFrameworkCore for async query methods removed in linq2db 6.x * fix: replace LinqToDB with Microsoft.EntityFrameworkCore for SingleAsync in IdentityApplicationFactory * fix: replace LinqToDB with Microsoft.EntityFrameworkCore for FirstAsync, fix import ordering * fix: bump linq2db.EntityFrameworkCore to 8.5.0 for compatibility with linq2db 6.x * trigger review * fix: add bracket pinning for linq2db version * [deps] Update linq2db to 6.5.0 and linq2db.EntityFrameworkCore to 8.8.0 linq2db 6.4.0 fixed SQLite provider detection in single-file publishes (linq2db/linq2db#5489). Our published images are single-file, so on 5.4.1 every BulkCopyAsync against SQLite failed with "Cannot load assembly System.Data.SQLite", breaking vault import and org-member login on self-hosted SQLite (PM-43804, PM-34828, PM-35184). linq2db.EntityFrameworkCore 8.8.0 requires linq2db 6.5.0 and still targets EF Core 8.x, so the two move together. Lock files regenerated; the only version changes are these two packages plus the new transitive linq2db.Analyzers 6.5.0. Root cause identified by @jussikuosa in #8373. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Co-authored-by: Jussi Kuosa <[email protected]> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: rkac-bw <[email protected]> Co-authored-by: Robert Y <[email protected]> Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]> Co-authored-by: Jussi Kuosa <[email protected]>

  • Justin Baur(06 Oct 26)

    [PM-41442] refactor: Migrate Vault to the SDK IFeatureService (#8513)

  • Brandon Treston(06 Oct 26)

    [PM-43734] Don't re-enable sends for excluded roles/members (#8469) * don't re-enable sends for excluded roles/members * update logging and tests * clean up * add event to provider log * PR feedback, update migration

  • Stephon Brown(06 Oct 26)

    [PM-40418] feat: add organization plan-change preview endpoint (#8457) * feat(subscriptions): add EnumMemberParameter query binder Add an IParsable<T> wrapper that binds an enum query parameter from its EnumMemberAttribute value (case-insensitive); unrecognized values fail binding with a 400. Lets the preview endpoints accept tier/cadence as their EnumMember string values. * feat(invoicing): add organization plan-change invoice preview query Add IGetOrganizationPlanChangePreviewQuery, which builds the InvoicePreview cart for an organization plan change: prorated against the live subscription (Subscription + AlwaysInvoice), or full-price for an org with no subscription (e.g. Free). Tax is estimated from a required country/postal code, so no stored Stripe customer is needed. * refactor(subscriptions): split shared endpoint handler into per-endpoint handlers Replace the single OrganizationSubscriptionEndpointsHandler with one handler class per endpoint (GetOrganizationSubscriptionPreviewHandler), keeping each endpoint open for extension without a shared handler accumulating a dependency per route. * feat(subscriptions): add organization plan-change preview endpoint Add GET .../billing/subscription/plan-change/preview, returning the plan-change InvoicePreview cart from IGetOrganizationPlanChangePreviewQuery. Binds tier/cadence as EnumMember strings plus a required country/postal code, restricts to standalone organization owners, and marks the group no-store. * test(invoicing): capture preview options inline instead of via StrongBox helper Replace the StrongBox holder and CaptureOptionsFor helper with an inline Arg.Do capture stubbed per-test in Arrange, and verify the target tier/cadence explicitly via Received rather than as a hidden stub matcher. * fix(invoicing): return 400 instead of 500 for unsupported tier and SM-incompatible target Move the tier->PlanType mapping off the domain model into a private query method that throws BadRequestException for unsupported tiers (e.g. premium), and reject an SM-enabled org targeting a plan without Secrets Manager up front. Both were client-controlled query values that fell through to NullReferenceException/InvalidOperationException and mapped to 500. Also resolve the billing address before the Stripe call so an invalid address fails fast. * fix(invoicing): return 400/404 instead of 500 for plan downgrade and missing Stripe subscription Reject a downgrade (currentPlan.UpgradeSortOrder > target) up front with BadRequestException before building the change set, mirroring UpgradeOrganizationPlanVNextCommand, so a Teams/Enterprise -> Families preview no longer quotes the flat Families price at the current seat count. Catch a resource_missing StripeException when the org's subscription no longer exists and throw NotFoundException (404), matching GetSubscriptionPreviewQuery, instead of a 500. * refactor(invoicing): resolve billing address before Secrets Manager check and reorganize query methods * style(billing): run dotnet format on plan-change preview files * fix(invoicing): return 400 instead of 500 for an unrecognized tax location Catch Stripe's customer_tax_location_invalid from the invoice preview call and throw BadRequestException with the same message the legacy PreviewOrganizationTaxCommand returns, so a bad country/postal code is a 400 rather than an unhandled 500. * refactor(billing): move org plan-change preview to a POST command Move the endpoint out of Bit.Invoicing into Bit.Subscriptions.Organization as a command, and convert it from GET/query-string to POST/JSON body so it can carry a tax id. Folds in tax-id support (request value with an on-file fallback), the 400/404/409 error split (caller-fixable -> 400, missing input -> 404, data or Stripe state out of sync -> 409 with a logged organization id), same-tier and Families+monthly guards, real enum request fields, and a post-trial amount preview for trialing subscriptions via trial_end=now. Builds the preview options in a single initializer. * test(billing): cover the org plan-change preview command and binding Adds command tests (paid proration by line id, Free full-price purchase incl. Secrets Manager and flat->seat repricing, Teams/Enterprise x Monthly/Annually, same-tier/downgrade/unsupported-tier/Families-monthly rejects, 409s for out-of-sync data and subscription status, tax-location and tax-id 400s, on-file vs request tax id, trialing trial_end=now), a handler NotFound/happy-path test, and an endpoint request-binding test that sends real JSON through the POST route. * docs(billing): document the plan-change preview surface and error semantics Describes the POST/body/tax-id endpoint, the Stripe-boundary note for reading via IStripeAdapter, the Core-debt tables, and the full 400/404/409 error split (unrecognized tier/cadence, premium tier, Families+monthly, same-tier incl. cadence-only, downgrade, no-SM plan, invalid address; 409s for out-of-sync data; 404 for a missing org). Corrects the AlwaysInvoice rationale (matches the real upgrade's immediate charge) and the Free-only full-price note. * style(billing): restore UTF-8 BOM on plan-change preview files * fix(billing): require tier/cadence, ignore blank tax ids, and set classic billing mode on preview request * fix: run dotnet format * fix(billing): set preview currency for free orgs and skip unusable tax ids A free-org preview has no Stripe customer, so set Currency=usd explicitly. Skip a tax id whose value is blank or whose Stripe code can't be derived so a partial taxId no longer reaches TaxService and returns a 500. Adds tests for classic billing mode, a blank tax-id value, and an omitted tier returning 400 at binding. * fix(billing): drop no-op proration behavior from the free-org preview The Free/no-subscription branch sets no Subscription, so ProrationBehavior has nothing to prorate against; keep only BillingMode = Classic, matching the sibling purchase preview. Reverts the test to assert ProrationBehavior stays null. * fix(billing): only set billing mode and currency on the subscription-less preview Stripe rejects subscription_details.billing_mode alongside an existing subscription, and sources currency from it. The paid plan-change path sets Subscription, so it must send neither; only the customer-less purchase preview needs them. Consolidate both into one no-subscription block instead of duplicating billing mode across branch builders and setting currency separately. * test(billing): cover an underivable tax-id code producing no tax id A tax id with a value Stripe can't resolve to a tax-code type is dropped rather than sent with a null type. * test(billing): cover past-due previews, free-org tax ids, and missing cadence * fix(billing): fall back to the submitted tax-id code when it can't be derived Match the legacy tax preview: when ITaxService can't derive the Stripe tax-id type from the value, use the code submitted with the request, logging a warning that names only the country and that code. The seat-count conflict logs now say which seat count is missing (Password Manager vs Secrets Manager). * docs(billing): correct preview readme claims against the shipped behavior A missing or unrecognized tier/cadence fails JSON binding (required enums), not the command; add the tax-id 400 and fallback, and the trialing trial_end=now behavior; scope the StandaloneOrganizationOwnerRequirement note to the organization-scoped endpoints; and mark both renewal-preview subscriber paths wired in Bit.Invoicing. * fix(billing): validate the plan-change tax id like the purchase preview Switch the request to the library's BillingAddressSelections DTO (nullable fields) so a missing country or postal code is validated in the command with a keyed message instead of failing JSON binding. Mirror the purchase preview's tax-id handling: a present-but-partial tax id (blank code or value) is a 400, an absent one resolves to no tax id, and the request tax id maps to a TaxID so it shares the on-file fallback. Adds a precedence test (request tax id wins over on-file). * docs(billing): clarify the plan-change preview's Stripe-boundary end state The ideal end state is that these Stripe calls move to a lower-level library, not that all Stripe access flows through Bit.Invoicing (which is only one of the libraries that read Stripe). * docs(billing): fix two readme debt items on the preview libraries Align the Invoicing Stripe-boundary end state with the org preview readme (Stripe calls should move to a lower-level library, not flow through Invoicing), and drop BillingAddress from the Subscriptions.Organization Core-debt table since the request now uses the library's BillingAddressSelections and only TaxID is still referenced from Bit.Core.Billing.Payment.Models.

  • Nik Gilmore(05 Oct 26)

    PM-37176: Add collection permission checks to create cipher endpoint. (#8482)

  • SmithThe4th(05 Oct 26)

    [PM-42940] fix: prevent custom-role collection bypass on GetAdmin cipher endpoint (#8472) * [PM-42940] fix: prevent custom-role collection bypass on GetAdmin cipher endpoint * [PM-42940] fix: preserve provider read access on GetAdmin cipher endpoint Switching GetAdmin's authorization to CanEditCipherAsAdminAsync closed the DeleteAnyCollection bypass but incidentally denied provider users, since that check starts from ICurrentContext.GetOrganization, which is null for a provider with no direct org membership. * [PM-42940] fix: use HasValue-style null guard in GetAdmin for analyzer compatibility The is-not-{OrganizationId: not null} pattern is logically equivalent but tripped a static analysis false positive claiming OrganizationId.Value could be null despite the preceding short-circuit guard. * [PM-42940] fix: align GetAdmin authorization with organization-details list endpoint Switching to CanAccessAllCiphersAsync closes the DeleteAnyCollection bypass, restores provider read access and restricted-Owner/Admin access that a prior edit-scoped check had incidentally denied, and removes an unnecessary per-request org-wide cipher query. Adds regression coverage for each branch of the check. * [PM-42940] fix: gate GetAdmin on EditAnyCollection instead of CanAccessAllCiphersAsync CanAccessAllCiphersAsync granted single-item admin view to AccessImportExport- and AccessReports-only custom roles, which never had it before. EditAnyCollection is ViewAllCollections without the DeleteAnyCollection grant that caused VULN-971, so Owner, Admin, provider and EditAnyCollection access is unchanged, including for restricted Owners/Admins, with no repository query. * [PM-42940] fix: remove unused ViewAllCollections from ICurrentContext GetAdmin was its last caller; leaving the DeleteAnyCollection-inclusive predicate available invites it being reached for again. * [PM-42940] refactor: authorize GetAdmin through CipherOrganizationAuthorizationHandler Replaces the deprecated ICurrentContext.EditAnyCollection call with an organization-scoped authorization handler, giving the remaining org-level helpers in CiphersController a place to migrate to. Access is unchanged: owners, admins, custom users with EditAnyCollection, and providers.

  • Brandon Treston(05 Oct 26)

    [PM-43787] Fix user supplied data protection sentinel in account recovery (#8438) * fix user supplied data protection sentinel in account recovery request bricking member accounts * clean up comments * fix tests * dont re-protect broken data * fix tests, add more tests * clean up error handling * clean up

  • Brandon Treston(05 Oct 26)

    remove guid from device approval email (#8487)

  • Jake Fink(05 Oct 26)

    [PM-26913] Remove pm-23995-no-logout-on-kdf-change flagged logic (#8424) Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>

  • github-actions[bot](05 Oct 26)

    Bumped version to 2026.10.0 (#8505) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

  • renovate[bot](05 Oct 26)

    [deps]: Update codecov/codecov-action action to v7 (#8029) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

  • Oscar Hinton(05 Oct 26)

    [PAM-188] Cipher Leases: API and commercial gate (#8494) * [PAM-188] Cipher Leases: API and commercial gate Bundle A4 of the pam/uat -> main extraction (PAM-173). Replaces the pass-through UnrestrictedCipherLeaseGate with the commercial CipherLeaseGate and fills in the cipher-lease endpoints scaffolded in #8105. - CipherLeaseGate, registered with a plain AddScoped so it overrides the Core default; Core grants InternalsVisibleTo Pam so only the Pam library can mint a FullCipherAccess witness. - ICipherLeaseGate.EnsureCanMutateAsync, the write-side decision. Its Vault call sites come with B3. - AccessPreCheckQuery, GetCipherAccessStateQuery and ListRuleBypassableCiphersQuery behind the cipher-lease and access-rule endpoints. Content matches pam/uat except for omissions: audit, notification and rotation registrations, and the access-rule delete's acting-user argument, which arrive with their own bundles. * [PAM-188] Trim cipher lease comments to behaviour Removes historical references, justifications and repeated explanations; documents the approved request on IGetCipherAccessStateQuery and CipherAccessState. * [PAM-188] Address review: bulk-mutate licensing and shared gating resolver - EnsureCanMutateManyAsync ignores leases in organizations where the caller is no longer licensed, matching the single-cipher path. Licensing is read off the lease, so callers passing ciphers without an organization are still covered. - Extract IGatingCollectionResolver so CipherLeaseGate and ListRuleBypassableCiphersQuery share one definition of an organization's gating collections. - Use Assert.NotNull's return value in AccessPreCheckResponseModelTests. * [PAM-188] Decide bulk-mutate gating in memory EnsureCanMutateManyAsync resolved the governing rule per cipher, costing two or more sequential queries per item. It now loads the caller's collections and mappings once and applies GetGatedCipherIds, sharing the loader with the self-loading AuthorizeReadManyAsync, and reads leases only when the batch contains a gated cipher. The decision is unchanged: ResolveAsync's null/non-null result does not depend on access signals.

  • renovate[bot](02 Oct 26)

    [deps] DbOps: Update Npgsql.EntityFrameworkCore.PostgreSQL to v8.0.11 (#6321) * [deps] DbOps: Update Npgsql.EntityFrameworkCore.PostgreSQL to v8.0.11 * [deps] Bump EF Core to 8.0.11 to match Npgsql provider 8.0.11 Npgsql.EntityFrameworkCore.PostgreSQL 8.0.11 requires Microsoft.EntityFrameworkCore.Relational >= 8.0.11, but the repo pinned 8.0.8, which failed restore with NU1605 (warnings as errors). Bump the EF Core Relational/SqlServer/Sqlite/Design pins and the dotnet-ef tool to 8.0.11 and regenerate the lockfiles. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Mark Kincaid <[email protected]> Co-authored-by: Claude Sonnet 5.5 <[email protected]> Co-authored-by: rkac-bw <[email protected]>

  • Jordan Aasen(02 Oct 26)

    [PM-43029] fix: apply Restrict item deletion policy to attachment paths (#8422) * [VULN-982] fix: enforce Restrict item deletion policy on attachments CipherService.DeleteAttachmentAsync guarded on UserCanEditAsync while its three sibling paths (DeleteAsync, SoftDeleteAsync, RestoreAsync) guard on UserCanDeleteAsync. Only the latter consults NormalCipherPermissions.CanDelete, which is where LimitItemDeletion is implemented, so an Edit-only member of an org with the policy enabled could permanently delete attachments on any item they could edit, even though the same server refused to let them delete the item itself. Attachment deletion does not go to Trash, so this was unrecoverable. Route the attachment-delete path through UserCanDeleteAsync so all four operations share one predicate. This widens the parameter to CipherDetails; the non-admin controller path already had one, and the admin path now uses GetByIdAsyncAdmin and wraps it the same way DeleteAdmin/PutDeleteAdmin do. The legacy `attachments` map on PUT /ciphers/{id} was a second, quieter path to the same destruction: it wrote Key = null for every id in the map with no check that the attachment was a modern keyed one, destroying the only server-side copy of the per-file encryption key and leaving the blob listed but permanently undecryptable. Because that is an edit, the policy never applied to it. Only apply the legacy map to attachments that have no Key, and validate its file names as encrypted strings to match Attachments2. * remove warning disable * fix: keep the org admin attachment write-back on a plain Cipher Routing the admin attachment-delete path through CipherDetails changed the runtime type reaching the orgAdmin branch of the private DeleteAttachmentAsync, which calls ReplaceAsync(Cipher) -> Cipher_Update. Dapper builds stored procedure parameters from the runtime type, so a CipherDetails would have sent FolderId, Favorite, Edit, ViewPassword, Manage, ArchivedDate and OrganizationUseTotp, none of which Cipher_Update declares. Clone to a plain Cipher in that branch so the hazard is fixed where it lives rather than at one call site, and assert the runtime type in a test that fails against the previous code. Cipher_Update also writes [Archives] = @Archives, and the CipherDetails copy constructor does not copy Archives, so carry it across at the call site. The two EF CipherOrganizationDetails queries did not select Archives either, which would have nulled the column on that provider; the Dapper sproc already returned it via C.*, so this brings the two into line. * refactor: filter legacy attachment validation with Where * test: cover the admin attachment Archives carry-across The service test asserts CipherService preserves whatever Archives it is handed, but nothing covered the controller line that puts the value there. Deleting that initializer left the whole Api.Test suite green while Cipher_Update would write [Archives] = NULL, discarding every member's archive state for the item. Add a DeleteAttachmentAdmin case that stubs the admin getter with a non-null Archives and asserts the CipherDetails handed to ICipherService carries it. Confirmed to fail when the initializer is removed. * fix: gate the admin attachment-delete route on the delete permission DeleteAttachmentAdmin passes orgAdmin: true, which short-circuits UserCanDeleteAsync in the service, so the controller gate was the whole authorization for that route. It used CanEditCipherAsAdminAsync, which filters on c.Edit && c.ViewPassword and never consults NormalCipherPermissions.CanDelete — leaving LimitItemDeletion bypassable through the admin variant of the same operation this PR restricts on the member route. For an org with AllowAdminAccessToAllCollectionItems disabled and LimitItemDeletion enabled, an Owner or Admin holding Edit but not Manage on a cipher is refused by DELETE /ciphers/{id}/admin but was accepted by DELETE /ciphers/{id}/attachment/{attachmentId}/admin. Switch to CanDeleteOrRestoreCipherAsAdminAsync, which every other admin delete/restore route already uses, and add the Owner/Admin-without-Manage case that fails against the previous gate.

  • Kyle Denney(02 Oct 26)

    [PM-41284] feat: Mark Stripe subscription schedules with their managing system (#8478) * [PM-41284] refactor: Move schedule ownership enum and mapper out of Organizations * [PM-41284] feat: Classify subscription schedules by managing system * [PM-41284] feat: Add Stripe subscription schedule adapter that marks created schedules * [PM-41284] refactor: Route Stripe schedule operations through the schedule adapter * [PM-41284] feat: Mark price increase schedules with their managing system * [PM-41284] feat: Mark annual upgrade schedules with their managing system * [PM-41284] chore: Describe legacy personal schedules in repricing test comment * [PM-41284] chore: Address final review feedback * [PM-41284] refactor: Add interface for Stripe subscription schedule adapter Every other class in Billing/Services/Implementations sits behind an interface in Billing/Services. Matching that keeps the adapter consistent with its siblings and lets consumers substitute it in tests, which the concrete class with non-virtual methods does not allow. * cleanup * [PM-41284] refactor: Use shared phase discount builder for annual upgrade schedules ReusedPhaseDiscounts duplicated DiscountExtensions.BuildCurrentPhaseDiscounts. * [PM-41284] refactor: Replace subscription schedule adapter with a schedule creator The second adapter layer duplicated four IStripeAdapter methods behind forwarders and needed Stripe's SubscriptionScheduleService registered in DI, which nothing else does. Raw create returns to IStripeAdapter, and the create-then-configure logic moves into SubscriptionScheduleCreator, which depends on IStripeAdapter. * [PM-41284] feat: Classify unrecognized managing-system markers separately from foreign schedules An empty or unknown managing_system value was classified as Foreign, making it indistinguishable from a hand-made Dashboard schedule and leaving it unlogged. It now maps to Unrecognized, which callers leave alone as before but log with the raw value. * [PM-41284] test: Cover seat changes on schedules marked only by managing system Existing tests only used the legacy phase markers. Adds a business price-increase schedule, whose upcoming phase takes the new seat count, and a personal one, which is left alone while the subscription is updated. * [PM-41284] test: Cover seat changes on annual upgrade schedules marked only by managing system Redemption now marks new annual upgrade schedules only with schedule-level managing_system metadata, but every annual upgrade consumer test used the legacy phase marker.

  • DanielD(02 Oct 26)

    QA-2596/fix-for-unexpected-error-occurred-sqlDateTime-overflow (#8500) * QA-2596/fix-for-unexpected-error-occurred-sqlDateTime-overflow * QA-2596/remove-comment-and-add-const

  • Justin Baur(02 Oct 26)

    [PM-34546] refactor: Pin the push notification wire format and carry routing on the envelope (#8254) * [PM-34546] test: Assert MessagePack wire shape is identical across push ingress paths The Azure Queue and POST /send ingress paths disagree on JSON conventions: the queue writes PascalCase with nulls omitted, /send writes camelCase with explicit nulls. Both funnel through HubHelpers, which deserializes case insensitively into the same CLR types, so the MessagePack frame SignalR puts on the wire is derived from those types rather than from the ingress JSON. Nothing asserted that. These tests drive the same notification through both paths, then encode the captured hub invocation with the service's own registered hub protocol so Startup stays the only definition of the wire format. Each case pins the decoded frame for readability and the frame bytes for exactness -- the decoded form cannot distinguish a timestamp extension from an ISO string, which is precisely what a future move to forwarding raw JSON would change. Cases cover both hubs, every nullable kind in its null and non-null form, and DateTime values landing in each timestamp format production can produce. * [PM-34546] test: Consolidate push notification wire format tests Three test files covered overlapping slices of the same contract: AzureQueuePipelineTests and PostSendEndpointTests each pinned one ingress format and its routing, and MessagePackWireShapeTests pinned the frame clients receive. None of them separated what an engine currently produces from what the service must still accept. Replace all three with one file over two lists. A scenario is a logical notification plus the single destination and MessagePack frame it must produce; a case is one accepted payload format tagged with the ingress it arrives on. Two tests assert each engine's current output is a listed format, and a third delivers every listed format through its real ingress -- the queue hosted service or POST /send -- and asserts the destination and frame. That split is what makes a sender format change testable: a format stays listed after the engines stop producing it, so the third test keeps proving the receiver accepts what an un-redeployed sender may still be sending, while only the first two track current output. Frames are pinned as both decoded JSON, which reads well in a failure, and exact bytes, which the decoded form cannot do -- it renders a MessagePack timestamp extension identically to an ISO string. * [PM-34546] fix: Emit one PascalCase payload shape on both push ingresses The two ways a notification reaches the Notifications service disagreed on JSON conventions: AzureQueuePushEngine wrote PascalCase and omitted null-valued properties, while NotificationsApiPushEngine posted camelCase through JsonContent's web defaults. HubHelpers deserializes case insensitively into the same CLR types, so this never reached clients, but it meant two payload shapes to reason about for one contract. Write null-valued properties on the queue, and give NotificationsApiPushEngine PascalCase via a serializer options parameter on BaseIdentityClientService.SendAsync. That parameter defaults to the previous web conventions, so the other four subclasses are unaffected. Both engines now emit byte-identical payloads. List the new formats as accepted cases and keep the superseded ones, regrouping by status rather than by ingress. The wire format tests show the change is invisible to clients: all 38 accepted formats still route to the same destination and serialize to the same MessagePack frame, since the frame is derived from the CLR types rather than the ingress JSON. Deployment order is safe either way here -- HubHelpers has always been case insensitive, so an un-upgraded Notifications service already accepts PascalCase. The superseded cases cover the reverse: a new service still receiving camelCase from an older Api. Retire them one release on, once no deployed sender can produce either. * [PM-34546] feat: Carry push notification routing on the envelope The Notifications service worked out where a notification was bound by inspecting its payload: a user id here, an organization id there, an installation id and client type somewhere else depending on the push type. The senders knew the answer all along -- PushNotification<T> carries Target, TargetId and ClientType -- and threw it away at serialization. The relay ingress has always sent all three; the queue and endpoint ingresses now do too. Nothing reads them yet. Unmapped JSON is ignored, so this is inert on the receiving side and safe in either deployment order. A release from now, when no sender can be running that omits them, the receiver can route off the envelope and the payload-inspection switch can go in one change, with no compatibility branch ever existing. The receiving type is narrowed rather than shared with the sender, because the routing fields exist to reach the right connections and are no business of clients: leaving them undeclared drops them. Every frame is byte identical to before, which the wire format tests assert -- the point of pinning them. The send envelope requires all of its properties, so an engine cannot forget to carry one across, and a property added later is a compile error at both call sites rather than a silently defaulted field on the wire. Also corrects the two engines' class docs, which named the wrong transport, the wrong hosting mode and the wrong receiver, and described these engines as non-mobile when they filter nothing and reach mobile clients like any other; and drops two now-unused IHubClients properties from the test factory, whose only caller went away with PostSendEndpointTests. * Comment the drain loop flagged by code quality * Report base64-encoded queue messages, and let tests queue bytes Dequeuing accepts either a plain or a base64-encoded message, and has since before the Azure SDK stopped encoding by default. Nothing writes base64 to this queue now, so the decode is tolerance for a sender that no longer exists -- but that is an argument from deployment timing, not evidence, and the next step for this loop is to deserialize the message body as bytes, which would accept only plain text. So: say when a decode happened. CoreHelpers.DecodeMessageText is inlined at this one call site to put the warning on the successful-decode path rather than inferring it from a comparison, and the catch narrows to FormatException. The other two callers keep the helper. If the warning never fires, the tolerance can be dropped on evidence. The tests pin the tolerance before anything changes: every queue format is delivered base64-encoded and asserted to reach the same destination with the same frame, which fails if a future reader takes the body without decoding -- verified by simulating exactly that. Two more assert the warning fires for base64 and stays quiet for plain text, so the signal the removal decision rests on is known to work. ChannelQueueClient now carries a BinaryData body rather than a string, so a test can queue exact bytes and both MessageText and Body come from them, as they do on a queue applying no encoding of its own. That is the harness the bytes-based reader needs; it can change without the fake changing with it. Notifications.Test takes Microsoft.Extensions.Diagnostics.Testing for FakeLogCollector, pinned to the version Core.Test already uses. * Keep the inlined base64 decode behaving as CoreHelpers did The inlined copy caught only FormatException, which is the only exception the decode can raise for a message that is not base64 -- but narrowing it made this commit a behaviour change on top of an inlining, and the point of inlining was to report a successful decode, nothing else. Catch everything, as the helper does, and leave changing it to the commit that removes the decode altogether. * Apply batched suggestions from code review Co-authored-by: Derek Nance <[email protected]> * Finish rename --------- Co-authored-by: Derek Nance <[email protected]>

  • renovate[bot](01 Oct 26)

    [PM-38709] deps: Update YamlDotNet to v18 (#7778) Bump YamlDotNet from 11.2.1 to 18.1.0. Implement the members added to ITypeInspector and IPropertyDescriptor in Setup's YamlComments.cs and pass ObjectSerializer through the comments visitor. Add Context tests that cover config.yml serialization, loading, and round trips. Co-authored-by: Derek Nance <[email protected]>

  • Leslie Tilton(01 Oct 26)

    [PM-43785] Login only organization cipher fetch for Access Intelligence (#8443) * feat: add Login-only org cipher stored procedure and repository method * feat: add GetManyLoginCipherOrganizationDetailsAsync repository method * feat: add GET /ciphers/organization-details/logins endpoint * test: add tests for GetOrganizationLoginCiphers query, repository, and controller endpoint * fix: exclude instead of include comment * style: Apply SQL keyword formatting and comment constant in ReadLoginsByOrganizationId * Update migration script * Remove order by revision date in CipherOrganizationDetails_ReadLoginsByOrganizationId

  • Bernd Schoolmann(01 Oct 26)

    Add pm-44303-emergency-access-sdk-api flag (#8493)

  • Leslie Tilton(01 Oct 26)

    [PM-43938] Collection endpoint for Access Intelligence Needs (#8425) * feat: Add organization collection sql statements * Fix create sql procedure * feat: Add GetManyOrganizationCollectionsWithPermissionsAsync repository method * feat: Add ReadOrganizationDetails collection authorization operation and handler * feat: Add GetOrganizationCollectionsWithDetails endpoint to CollectionsController * test: Add unit tests for authorization and endpoint * Format * refactor: Use [Authorize<AccessReportsRequirement>] for organization collections endpoint * refactor: Rename collections access endpoint to GET access / GetAllWithAccess * perf: Replace O(n²) group/user lookup with ToLookup in GetManyOrganizationCollectionsWithPermissionsAsync * fix: Use CREATE OR ALTER in migration script for Collection_ReadOrganizationCollectionsWithPermissions * fix: Add explicit type filter to CollectionAdminDetailsQuery.ByOrganizationIdAllTypes * test: Add integration tests for GetManyOrganizationCollectionsWithPermissionsAsync and GET collections/access * style: Convert if/else to ternary in GetManyOrganizationCollectionsWithPermissionsAsync * Update migration script * fix: combine dual-type collection query into single IN (0,1) SELECT * fix test cases * style: apply SQL formatting guidelines to stored procedure

  • DanielD(01 Oct 26)

    QA-2572/ClaimedDomainOrgScenes (#8488) * QA-2572/ClaimedDomainOrgScenes * QA-2572/Fix-Linter-failure

Bitwarden Security

5.7/10

Repo Security Summary

Updated 24 Aug 26

  • Code-Review10/10
  • Maintained10/10
  • Security-Policy10/10
  • CII-Best-Practices0/10
  • Dangerous-Workflow10/10
  • Token-Permissions0/10
  • License9/10
  • Branch-Protection4/10
  • Signed-Releases0/10
  • Binary-Artifacts10/10
  • Packaging10/10
  • Fuzzing0/10
  • Pinned-Dependencies2/10
  • SAST0/10

Bitwarden Website

Website

Best Password Manager for Business, Enterprise & Personal | Bitwarden | Bitwarden

Bitwarden is the trusted, open source password manager for individuals, teams, and enterprises. Securely store, share, and manage passwords, passkeys, and secrets. Free to start.

Redirects

Does not redirect

Security Checks

All 65 security checks passed

Server Details

  • IP Address151.101.193.91
  • LocationSan Francisco,California,United States of America,NA
  • ISPFastly Inc.
  • ASNAS54113

Associated Countries

  • USUS
  • CACA

Safety Score

Website marked as safe

100%

Blacklist Check

bitwarden.com was found on 0 blacklists

  • AntiSocial Blacklist
  • Artists Against 419
  • Badbitcoin
  • Bambenek Consulting
  • CERT Polska
  • CoinBlockerLists
  • CRDF
  • CryptoScamDB
  • EtherAddressLookup
  • EtherScamDB
  • Fake Website Buster
  • MetaMask EthPhishing
  • NABP Not Recommended Sites
  • OpenPhish
  • PetScams
  • PhishFeed
  • PhishFort
  • Phishing.Database
  • PhishStats
  • PhishTank
  • Phishunt
  • RPiList Not Serious
  • Scam.Directory
  • SecureReload Phishing List
  • Spam404
  • StopGunScams
  • Suspicious Hosting IP
  • ThreatFox
  • ThreatLog
  • TweetFeed
  • URLhaus
  • ViriBack C2 Tracker

Website Preview

Website preview

Bitwarden Android App

APK Info

De-Googled Compatibility

Native3.94/ 477 ratings
microG3.99/ 496 ratings
  • GrapheneOSNative3.9 / 4(36)
  • CalyxOSmicroG4.0 / 4(12)
  • e OSmicroG4.0 / 4(11)
  • iodeOSmicroG4.0 / 4(9)
  • LineageOSmicroG4.0 / 4(9)
  • crDroidmicroG4.0 / 4(8)

Tested on Android 10–17 · Updated 04 Oct 26 · View on Plexus →

Trackers

  • HockeyApp
  • Google Analytics
  • Google Firebase Analytics
  • Google Tag Manager

Permissions

  • Access Network State
  • Access Wifi State
  • Camera
  • Internet
  • Nfc
  • System Alert Window
  • Use Fingerprint
  • Wake Lock
  • Write External Storage
  • Receive
  • Write Use App Feature Survey
  • C2d Message

Bitwarden iOS App

App Info

Bitwarden Password Manager

Recognized as best password manager by PCMag, The Verge, CNET, G2, and more! SECURE YOUR DIGITAL LIFE Secure your digital life and protect against data breaches by generating and saving unique, strong passwords for every account. Maintain everything in an end-to-end encrypted password vault that only you can access. ACCESS YOUR DATA, ANYWHERE, ANYTIME, ON ANY DEVICE Easily manage, store, secure, and share unlimited passwords and passkeys across unlimited devices without restrictions. EVERYONE SHOULD HAVE THE TOOLS TO STAY SAFE ONLINE Utilize Bitwarden for free with no ads and or selling data. Bitwarden believes everyone should have the ability to stay safe online. Premium plans offer access to advanced features. EMPOWER YOUR TEAMS WITH BITWARDEN Plans for Teams and Enterprise come with professional business features. Some examples include SSO integration, self-hosting, directory integration and SCIM provisioning, global policies, API access, event logs, and more. Use Bitwarden to secure your workforce and share sensitive information with colleagues. More reasons to choose Bitwarden: World-Class Encryption Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashing, and PBKDF2 SHA-256) so your data stays secure and private. 3rd-party Audits Bitwarden regularly conducts comprehensive third-party security audits with notable security firms. These annual audits include source code assessments and penetration testing across Bitwarden IPs, servers, and web applications. Advanced 2FA Secure your login with a third-party authenticator, emailed codes, or FIDO2 WebAuthn credentials such as a hardware security key or passkey. Bitwarden Send Transmit data directly to others while maintaining end-to-end encrypted security and limiting exposure. Built-in Generator Create long, complex, and distinct passwords and unique usernames for every site you visit. Integrate with email alias providers for additional privacy. Global Translations Bitwarden translations exist for more than 60 languages, translated by the global community though Crowdin. Cross-Platform Applications Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more.

Rating

Rated 4.76 out of 5 stars by 33,694 users

Version Info

  • Current Version2026.9.1
  • Last Updated02 Oct 26
  • First Released02 Sept 16
  • Minimum iOS Version15.0
  • Device Models Supported131

App Details

  • IPA Size112.19 Mb
  • PriceFree (USD)
  • Age Advisory4+
  • Supported Languages59
  • DeveloperBitwarden Inc
  • Bundle IDcom.8bit.bitwarden

Screenshots

  • App screenshot
  • App screenshot
  • App screenshot
  • App screenshot
  • App screenshot
  • App screenshot
  • App screenshot
  • App screenshot

Bitwarden Docker

Container Info

bitwardenrs

This is a Bitwarden server API implementation written in Rust compatible with upstream Bitwarden clients*, perfect for self-hosted deployment where running the official resource-heavy service might not be ideal..

#Other#Tools

View on DockerHub

bitwardenrs/server:latest

Run Command

docker run -d \
  -p 80/tcp \
  -v /portainer/Files/AppData/Config/Bitwarden-rs:/config \
  --restart=unless-stopped \
  bitwardenrs/server:latest

Compose File

version: 3.8
services:
  bitwarden-rs:
    image: "bitwardenrs/server:latest"
    ports:
      - 80/tcp
    volumes:
      - "/portainer/Files/AppData/Config/Bitwarden-rs:/config"
    restart: unless-stopped

Port List

  • 80/tcp

Volume Mounting

  • Container PathHost Bind
  • /config/portainer/Files/AppData/Config/Bitwarden-rs

Bitwarden Reviews

More Password Managers

About the Data: Bitwarden

Change History

  • Amended (androidApp, subreddit)
  • Amended (iosApp)
  • Amended (description) by @baddate #108
  • Renamed previously: BitWarden from Essentials › Password Managers by @jamescridland #90

Edit Bitwarden Data

You can edit Bitwarden's entry in this section of awesome-privacy.yml by submitting a PR to our GitHub repo.
Note that some of the information shown above has been aggregated from external sources, a list of these can be found data documentation.

Origin Data

Modify Data

API

You can access Bitwarden's data programmatically via our API. Simply make a GET request to:

https://api.awesome-privacy.xyz/v1/services/bitwarden

The REST API is free, no-auth and CORS-enabled. To learn more, view the API Docs or read the API Usage Guide.

Share Bitwarden

Help your friends compare Password Managers, and pick privacy-respecting software and services.
Share Bitwarden and Awesome Privacy with your network!