feat(extractor): recognise crypto Create* factories as owning acquires (recall)#60
Conversation
Closes the recall gap documented by #58: ShareX's DeriveCryptoData leaks TWO crypto disposables — rfcDeriver (`new Rfc2898DeriveBytes`, already caught) and rng = RandomNumberGenerator.Create() (a static factory we missed). IsOwningFactory now recognises a second owning-factory family alongside System.IO.File.Open*/Create*: a System.Security.Cryptography static `Create*` method whose result implements IDisposable (RandomNumberGenerator.Create(), Aes.Create(), SHA256.Create(), RSA.Create(), IncrementalHash.CreateHash(), ...). A local bound to one is an acquire exactly like `new`, so an undisposed one is OWN001. Kept tight for precision: the guard is static + Create-prefixed + the RESULT type implements IDisposable + the declaring type is in System.Security.Cryptography, so an instance `aes.CreateEncryptor()` (not static) and a non-IDisposable `CryptoConfig .CreateFromName()` (returns object) are never mistaken for an owned acquire. Factored the File and crypto namespace checks through a small IsInNamespace helper. Pinned by two FlowLocalsSample cases in the wpf-extractor --flow-locals step: CryptoFactoryLeaks (RandomNumberGenerator.Create() never disposed -> OWN001) and CryptoFactoryDisposed (SHA256.Create() + Dispose -> silent, the control proving the factory result is modelled as an acquire, not a false positive). The sharex-rfc2898 corpus before.cs now catches both leaks; its notes/comment are updated to mark the gap closed. Validated locally: rngLeak -> OWN001, shaClean silent, corpus 8/8. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthrough
ChangesCrypto Factory Ownership Detection
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
| // DeriveCryptoData (RandomNumberGenerator.Create()). | ||
| public void CryptoFactoryLeaks() | ||
| { | ||
| var rngLeak = RandomNumberGenerator.Create(); |
The recall gap (from #58)
The corpus case locked in #58 documented a gap: ShareX's
DeriveCryptoDataleaks two crypto disposables, but we only caught one —rngis anIDisposableacquired via a static factory, which the flow detector didn't recognise (it knewnew, ArrayPoolRent, andSystem.IO.File.Open*/Create*, notX.Create()).The fix
IsOwningFactorynow recognises a second owning-factory family: aSystem.Security.CryptographystaticCreate*method whose result implementsIDisposable—RandomNumberGenerator.Create(),Aes.Create(),SHA256.Create(),RSA.Create(),IncrementalHash.CreateHash(), … A local bound to one is an acquire exactly likenew, so an undisposed one is OWN001.Kept tight for precision — the guard is
static+Create-prefixed + the result implementsIDisposable+ the declaring type is in the crypto namespace, so an instanceaes.CreateEncryptor()(not static) and a non-IDisposableCryptoConfig.CreateFromName()(returnsobject) are never mistaken for an owned acquire. The File and crypto namespace checks are factored through a smallIsInNamespacehelper (the File branch stays equivalent).Pinned in CI
Two
FlowLocalsSample.cscases in thewpf-extractor--flow-localsstep:CryptoFactoryLeaksRandomNumberGenerator.Create(), never disposedCryptoFactoryDisposedSHA256.Create()+Dispose()The
sharex-rfc2898corpusbefore.csnow catches both leaks; its notes/comment are updated to mark the gap closed (the catch count is unchanged — still one case — so--min-recallstays 10). Validated locally:rngLeak→ OWN001,shaCleansilent, corpus 8/8. The extractor source→facts step is validated in CI.🤖 Generated with Claude Code
https://claude.ai/code/session_01Rg8kSk1YT14x7A1vo5zgED
Generated by Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation