fix: refuse to write a sensitive variable that would clear its value - #450
Draft
NickJosevski wants to merge 1 commit into
Draft
fix: refuse to write a sensitive variable that would clear its value#450NickJosevski wants to merge 1 commit into
NickJosevski wants to merge 1 commit into
Conversation
The server matches a variable without an ID by name, so writing a sensitive variable with an empty value and no ID replaced the stored secret with an empty string. Nothing errored and the loss was invisible on read, because a sensitive value is never returned. Both Update paths now reject that payload. Sending an ID, or an explicit value, is unaffected. Fixes #449 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #449.
A sensitive variable written with an empty
Valueand noIdhad its stored secret replaced with an empty string. Nothing errored, and the loss was undetectable on read because the server never returns a sensitive value. A caller who rebuilds a variable set instead of round-tripping the objects fromGetAllproduces exactly that payload.Both
Updatepaths now reject it. Everything else is unchanged: sending theIdkeeps the existing value, and sending an explicit value sets it.What the server actually does
Measured against a live 2026.x instance, using a runbook that printed
${#VALUE}so masking could not hide the result. Starting value 18 characters:IdsentValuesent""null"newvalue123"""null"newvalue123"The
Idis the sole determinant.nulland""are indistinguishable.That is why this doesn't take #261's approach of changing
Valueto*string— rows 4 and 5 show sendingnullwipes the secret just the same, so it would be a breaking change to every caller ofVariable.Valuethat fixes nothing. #261 also bundles GitHub credential support that has since landed independently ascredentials.GitHubApp.Verified live
Six flows through the client, before cleanup:
Case 5 is newly rejected: creating a sensitive variable with no value. That was already a no-op on the server and is indistinguishable from case 2, which is the destructive one.
Test fixtures were removed afterwards.
pkg/variableshas the same failures before and after —TestLibraryVariableSetServiceDeleteAllfails on both, being a destructive integration test that cannot delete variable sets in use by projects on the instance.🤖 Generated with Claude Code