-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create rule S5344: Passwords should not be stored in plain-text or with a fast hashing algorithm (Part 1) #9278
Conversation
e207cb3
to
e98c967
Compare
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.CSharp/Rules/PasswordsShouldBeStoredCorrectly.cs
Show resolved
Hide resolved
@costin-zaharia-sonarsource I accepted 7 issues, which are as follows:
Let me know if you have any disagreements. |
analyzers/tests/SonarAnalyzer.Test/Rules/PasswordsShouldBeStoredCorrectlyTest.cs
Show resolved
Hide resolved
analyzers/its/expected/ManuallyAddedNoncompliantIssues.CS/S5344-NetFramework48.json
Outdated
Show resolved
Hide resolved
e98c967
to
4e8d69a
Compare
…th a fast hashing algorithm
4e8d69a
to
ccd5c9a
Compare
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 🚀
<p>When bcrypt’s hashing function is used, it is important to select a round count that is high enough to make the function slow enough to prevent | ||
brute force: More than 12 rounds.</p> | ||
<p>For bcrypt’s key derivation function, the number of rounds should likewise be high enough to make the function slow enough to prevent brute force: | ||
More than 4096 rounds <code>(2**12)</code>.<br> This number is not the same coefficient as the first one because it uses a different algorithm.</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"2**12" -> shouldn't this be 2^12
or 2<sup>12</sup>
?
""") | ||
.AddReferences(NuGetMetadataReference.BouncyCastle()) | ||
.Verify(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should cover also:
var x = new Rfc2898DeriveBytes(HardCodedKey, new byte[] { 1 }, 120_000);
x.IterationCount = 1; // Noncompliant
var y = new Rfc2898DeriveBytes(HardCodedKey, new byte[] { 1 }, 120_000);
y.IterationCount = 1; // Noncompliant
void MakeItUnsafe(Rfc2898DeriveBytes password)
{
password.IterationCount = 1; // Noncompliant
}
tracker.AssignedValue(context) is int iterationCount | ||
&& iterationCount < IterationCountThreshold; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tracker.AssignedValue(context) is int iterationCount | |
&& iterationCount < IterationCountThreshold; | |
tracker.AssignedValue(context) is < IterationCountThreshold; |
"Identity v2 uses only 1000 iterations. Consider changing to identity V3.", | ||
propertyTracker.MatchSetter(), | ||
propertyTracker.MatchProperty(new MemberDescriptor(KnownType.Microsoft_AspNetCore_Identity_PasswordsHasherOptions, "CompatibilityMode")), | ||
x => propertyTracker.AssignedValue(x) is int mode && mode == 0); // PasswordHasherCompatibilityMode.IdentityV2 results to 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x => propertyTracker.AssignedValue(x) is int mode && mode == 0); // PasswordHasherCompatibilityMode.IdentityV2 results to 0 | |
x => propertyTracker.AssignedValue(x) is 0); // PasswordHasherCompatibilityMode.IdentityV2 results to 0 |
I will take care of the issues on part2, so that I can validate tomorrow the findings of this one :) |
Part of ##8998
Whatever is checked, is implemented in this PR:
PasswordHasherOptions
.IterationCount < 100K (Core)PasswordHasherOptions
.CompatibilityMode == IdentityV2 (Core)KeyDerivation
.Pbkdf2.iterationCount < 100K (Core)Rfc2898DeriveBytes.
Pbkdf2.iterations < 100K (Core)PasswordHasher
instantiated (FRM)Rfc2898DeriveBytes
.iterations < 100K (cross-platform)Rfc2898DeriveBytes
.hashAlgorithm does not exist (cross-platform)OpenBsdCrypt
/BCrypt
).Generate.cost < 12 (BouncyCastle)PbeParametersGenerator
.Init.iterationCount < 100K (BouncyCastle)SCrypt
.Generate N < 2^12, r < 8, or dklen < 32 (BouncyCastle)