Repository navigation
fix: EXPOSED-1012 Do not include the column value in valueFromDB error messages - #2965
Open
Lee, Hyo jun (devyourown) wants to merge 2 commits into
Open
Lee, Hyo jun (devyourown) wants to merge 2 commits into
Lee, Hyo jun (devyourown) wants to merge 2 commits into
Conversation
…r messages The "Unexpected value" errors thrown by valueFromDB interpolated the raw value into the message, so a value whose toString() exposes sensitive data (e.g. a decrypted secret behind a transform) could end up in logs and stack traces. All such sites now go through a single helper that reports only the expected type and the runtime type of the value, and throw UnexpectedValueTypeException (a subtype of IllegalStateException, so existing catch blocks still work).
This branch has not been deployed
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.
Description
Summary of the change:
valueFromDBerror messages no longer contain the column value itself, only the expected type and the runtime type of the value. The error is now anUnexpectedValueTypeException(a subtype ofIllegalStateException).Detailed description:
ColumnType.ktinterpolated$valueinto the message. If the value'stoString()exposes sensitive data (the ticket's case: a decrypted secret behind aColumnTransformer), the plaintext ends up in logs and stack traces. Because the exception type was a plainIllegalStateException, callers had no safe way to catch it and sanitize the message.UnexpectedValueTypeException(message) : IllegalStateExceptioninexposed-core(org.jetbrains.exposed.v1.exceptions), with KDoc explaining why the value is omitted. Since it extendsIllegalStateException, existingcatch (e: IllegalStateException)blocks keep working.unexpectedValue(expected, value): NothinginColumnType.ktthat builds the message fromexpectedandvalue::class.qualifiedNameonly.error("Unexpected value ... $value ...")sites with the helper. The twoNaNchecks inDecimalColumnTypewere left as they are, because they print the literal textNaN, not the value.exposed-core.api(apiDump) for the new public class.BinaryColumnTypeTeststhat reproduces the leak with abinary(...).transform(...)column whose wrapped type is a data class, and asserts that the message does not contain the plaintext but does contain the runtime type name. The test fails onmainwithUnexpected value Secret(plain=123-45-6789) of type ...Secret.Nothing-returning helper keeps all sites consistent, so the message format can only be changed in one place. The message format isexpected type: <X>, actual type: <qualified name>.A note on the exception type: the ticket asked for a more specific exception than
IllegalStateException, which is why the new class is added. If you would rather not grow the public API for this, I am happy to drop the class and keepIllegalStateException; the message change is independent of it.One observation while writing the test (not changed in this PR): assigning a wrapped Kotlin-side value with
ResultRow.seton atransform-ed column stores it raw, so the nextgetpasses the wrapped object to the inner column'svalueFromDB. That is the path the reproduction uses, and it is likely how the value in the ticket ended up in the message. I left that behaviour as is since it is a separate question.Reproduction credit: Marko Cevrljakovic (@MARKOCEVRLJAKOVIC) (marecevrljakovic on YouTrack) shared a reproduction project on the ticket (https://gist.github.com/MARKOCEVRLJAKOVIC/9fde02311037e98b898b4f7a5c221700), which confirmed the path through
ColumnTransformer. Thank you.AI assistance: I used an LLM (Claude) to explore the codebase, locate the 20 call sites, draft the test scaffold and parts of this description. The design (type-only message, single helper, new exception type) and the code changes were written by me, and I ran all checks locally.
Type of Change
Updates/remove existing public API methods:
Affected databases:
(The change is in
exposed-coreand not dialect-specific. Tests were run locally with H2 only::exposed-tests:test_h2_v21059 tests, 0 failures.)Checklist
Related Issues
EXPOSED-1012: https://youtrack.jetbrains.com/issue/EXPOSED-1012