bcquality/community/knowledge/security/guarded-text-credential-seam-is-legitimate-when-secrettext-cannot-flow-end-to-end.md

2.6 KiB

bc-version domain keywords technologies countries application-area
23..
security
secrettext
text-seam
interface
nondebuggable
unwrap
lc0043
pragma
half-conversion
test-double
al
w1
all

A guarded Text credential seam is legitimate when SecretText cannot flow end to end

Contributions welcome — open a PR to refine or extend this article.

Description

SecretText can only protect a credential along a path where every API accepts it. Some seams are typed Text by design: an injectable interface whose test double asserts where the credential travels (header versus body), or a legacy consumer that takes Text. Retyping such a seam to SecretText does not complete the conversion — the value must become Text again at the seam, and SecretText.Unwrap() is on-premises only (see nondebuggable-required-when-unwrapping-secrettext.md). A cloud app therefore cannot convert this path end to end, and a partial conversion is worse than none: it either does not build for the cloud target or destroys the test that pinned the credential's placement. An analyzer such as LinterCop LC0043 flags the Text seam; the rule is right in general and wrong at exactly this location.

Best Practice

When a Text seam cannot be removed, keep it Text and guard it instead: mark every procedure that touches the plain value [NonDebuggable], keep the plain-text path as short as possible, store the value encrypted at rest (IsolatedStorage with SetEncrypted), and suppress the analyzer with a #pragma scoped to the exact statements, restored immediately, with a comment naming the seam that justifies it. Prefer removing the seam when the callee has a SecretText-aware API (HttpHeaders.Add, HttpContent.WriteFrom, SetSecretRequestUri — see secrettext-with-httpclient.md); the guarded Text seam is the fallback, not the default.

See sample: guarded-text-credential-seam-is-legitimate-when-secrettext-cannot-flow-end-to-end.good.al.

Anti Pattern

A review finding that demands SecretText on a guarded Text seam without checking whether the value can stay SecretText up to the sink. Acting on it produces the half conversion: a SecretText parameter that is immediately Unwrap()-ed to call the Text seam, or a seam retyped to SecretText whose test double can no longer assert the credential's placement. Signals to detect the half conversion: Unwrap() in a cloud-targeted app, or a SecretText parameter converted back to Text within the same procedure.

See sample: guarded-text-credential-seam-is-legitimate-when-secrettext-cannot-flow-end-to-end.bad.al.