February 6, 2023·4 min read·engineeringcockroachdbsecurityauthorizationroles

CockroachDB fixes a login restriction that authorization did not inspect

The global NOSQLLOGIN privilege did not block SQL access in early 22.2 releases. The older role option provides a workaround with different inheritance behavior.

A database can accept a command that records a restriction without enforcing that restriction at the point of access. CockroachDB's global NOSQLLOGIN privilege had that failure in early 22.2 releases. The command to grant the privilege succeeded, but authorization checks did not inspect it correctly. Users that administrators intended to block could still run SQL commands.

The February 6 advisory identifies the affected stable releases as 22.2.0 through 22.2.3 and names 22.2.4 as the corrected maintenance release. It traces the bug's introduction to 22.2.0-alpha.1. The distinction between accepting a permission declaration and enforcing it is the useful subject here, because an inventory of declared grants alone would miss the defect.

I value CockroachDB's decision to make strong transaction isolation the default. Access restrictions need the same directness between declaration and behavior. A permission named NOSQLLOGIN is useful only if the SQL access path actually applies it.

Two syntaxes carry different security semantics

The vulnerable global-privilege form uses GRANT SYSTEM. For an illustrative user named restricted_user, the relevant command has this shape.

GRANT SYSTEM NOSQLLOGIN TO restricted_user;

The advisory's workaround uses the older role-option form. It does not describe that older mechanism as having the same faulty inspection path.

ALTER ROLE restricted_user WITH NOSQLLOGIN;

These forms share a name but differ in inheritance. The advisory explicitly says that the role option does not pass to users who are members of the role. A global privilege can express a restriction through role membership, while the workaround must account for the actual users that need the option. Substituting the syntax on a group role is therefore not a semantically complete replacement for an inherited global restriction.

That difference is central to understanding the mitigation. An administrator may intend one role assignment to restrict several member users. Applying the older option to only the parent role does not establish that its members now have the same access restriction. The workaround needs the non-inherited behavior to remain visible, rather than treating the two statements as spelling variants.

The role-option implementation in 22.2.0 supplies concrete context for the older mechanism. It includes both SQLLOGIN and NOSQLLOGIN in the option set. Setting the latter inserts the named option into system.role_options, while the positive option removes that restriction. The representation is distinct from the global-privilege declaration described by the advisory.

The same implementation rejects unrecognized option names with a syntax error. It normalizes recognized names to uppercase before looking them up, so letter case does not create a separate role option. Those checks establish what declaration the parser understood.

This source also checks conflicting positive and negative role options. That parser and catalog machinery can record a coherent option set, but it does not establish that an independently implemented privilege check reads every applicable restriction. The security report concerns that later enforcement step for the global form.

A negative privilege needs an access-path check

Many permissions describe an action a user may perform. NOSQLLOGIN instead describes an action the system must prevent for an otherwise recognized user. An access check that ignores the restriction can therefore leave an account apparently configured for denial while continuing to accept SQL use. The advisory states that exact consequence without requiring an additional claim about changing table privileges.

The affected user is not necessarily acquiring permission to read every table. The reported failure is that SQL access itself is not blocked as intended. Existing database privileges still determine what the user could do once admitted, unless another issue applies. Keeping that distinction avoids turning a login-restriction defect into an unsupported claim of universal administrator access.

The repair fixes the logic that inspects the global NOSQLLOGIN privilege. That is a server authorization correction. Reissuing the same grant to an affected server cannot by itself make the missing inspection occur, because the stored declaration is not the part identified as faulty. Upgrading to the fixed release repairs the path that must use it.

The release interval also matters. The advisory does not classify every CockroachDB installation as affected regardless of version. It provides a stable-release range and an earlier development introduction point. A precise exposure assessment combines that version range with use of the global restriction, instead of treating the presence of any role option with a similar name as sufficient evidence.

The workaround preserves only its documented behavior

The older role option offers a concrete mitigation while arranging an upgrade. It must be applied with its direct-user semantics understood. That is a more useful instruction than merely recommending that administrators inspect their roles, because it identifies what command changes the enforcement behavior available in the affected versions.

My preference is to keep the workaround's narrower inheritance model explicit in any authorization change. A central role assignment is often chosen precisely to avoid configuring every user separately. Replacing it with a non-inherited option changes that administration model, even when it restores the immediate access restriction for a particular user.

The advisory encourages users on 22.2.0 through 22.2.3 to move to 22.2.4 or later. As of its publication, 22.2.4 is the named release containing the fix. That provides a definite correction target without relying on information about releases that have not yet appeared.

Declared policy and effective policy need separate evidence

This defect illustrates a failure between storing policy and consulting it. The global command expresses an administrator's intent, while the SQL access path determines whether that intent has an effect. Successful execution of the declaration is evidence only of the first step. The advisory exists because the second step failed in the listed versions.

After the correction, the global privilege can participate in the authorization decision it was designed to control. Until then, the documented direct role option provides a different enforcement mechanism with an explicit inheritance limit. Those are the two concrete ways the advisory separates a recorded restriction from a restriction the server will apply.