csharp.lang.security.cryptography.x509-subject-name-validation.X509-subject-name-validation
semgrep
Author
unknown
Download Count*
License
Validating certificates based on subject name is bad practice. Use the X509Certificate2.Verify() method instead.
Run Locally
Run in CI
Defintion
rules:
- id: X509-subject-name-validation
severity: WARNING
languages:
- csharp
metadata:
cwe:
- "CWE-295: Improper Certificate Validation"
owasp:
- A03:2017 - Sensitive Data Exposure
- A07:2021 - Identification and Authentication Failures
references:
- https://docs.microsoft.com/en-us/dotnet/api/system.identitymodel.tokens.issuernameregistry?view=netframework-4.8
category: security
technology:
- .net
confidence: MEDIUM
subcategory:
- vuln
likelihood: LOW
impact: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Improper Authentication
message: Validating certificates based on subject name is bad practice. Use the
X509Certificate2.Verify() method instead.
patterns:
- pattern-inside: |
using System.IdentityModel.Tokens;
...
- pattern-either:
- patterns:
- pattern-either:
- pattern-inside: |
X509SecurityToken $TOK = $RHS;
...
- pattern-inside: |
$T $M(..., X509SecurityToken $TOK, ...) {
...
}
- metavariable-pattern:
metavariable: $RHS
pattern-either:
- pattern: $T as X509SecurityToken
- pattern: new X509SecurityToken(...)
- patterns:
- pattern-either:
- pattern-inside: |
X509Certificate2 $CERT = new X509Certificate2(...);
...
- pattern-inside: |
$T $M(..., X509Certificate2 $CERT, ...) {
...
}
- pattern-inside: |
foreach (X509Certificate2 $CERT in $COLLECTION) {
...
}
- patterns:
- pattern-either:
- pattern: String.Equals($NAME, "...")
- pattern: String.Equals("...", $NAME)
- pattern: $NAME.Equals("...")
- pattern: $NAME == "..."
- pattern: $NAME != "..."
- pattern: |
"..." == $NAME
- pattern: |
"..." != $NAME
- metavariable-pattern:
metavariable: $NAME
pattern-either:
- pattern: $TOK.Certificate.SubjectName.Name
- pattern: $CERT.SubjectName.Name
- pattern: $CERT.GetNameInfo(...)
Examples
X509-subject-name-validation.cs
using System.IdentityModel.Tokens;
namespace System.IdentityModel.Samples
{
public class TrustedIssuerNameRegistry : IssuerNameRegistry
{
public override string GetIssuerName(SecurityToken securityToken)
{
X509SecurityToken x509Token = securityToken as X509SecurityToken;
if (x509Token != null)
{
// ruleid: X509-subject-name-validation
if (String.Equals(x509Token.Certificate.SubjectName.Name, "CN=localhost"))
{
return x509Token.Certificate.SubjectName.Name;
}
// ruleid: X509-subject-name-validation
if (String.Equals("CN=localhost", x509Token.Certificate.SubjectName.Name))
{
return x509Token.Certificate.SubjectName.Name;
}
}
// ok
if(String.Equals("Hello", "Goodbye")) { }
}
public override string GetIssuerName2() // no args
{
X509SecurityToken x509Token = new X509SecurityToken();
if (x509Token != null)
{
// ruleid: X509-subject-name-validation
if (x509Token.Certificate.SubjectName.Name.Equals("CN=localhost"))
{
return x509Token.Certificate.SubjectName.Name;
}
}
}
public override string GetIssuerName3()
{
X509SecurityToken x509Token = new X509SecurityToken();
if (x509Token != null)
{
// ruleid: X509-subject-name-validation
if ("CN=localhost" == x509Token.Certificate.SubjectName.Name)
{
return x509Token.Certificate.SubjectName.Name;
}
// ruleid: X509-subject-name-validation
if (x509Token.Certificate.SubjectName.Name == "CN=localhost")
{
return x509Token.Certificate.SubjectName.Name;
}
}
}
public override string GetIssuerNameLoop()
{
X509Store store = new X509Store("MY",StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid,DateTime.Now,false);
X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Test Certificate Select","Select a certificate from the following list to get information on that certificate",X509SelectionFlag.MultiSelection);
foreach (X509Certificate2 x509 in scollection)
{
// ruleid: X509-subject-name-validation
String.Equals(x509.GetNameInfo(X509NameType.SimpleName), "CN=localhost");
// ruleid: X509-subject-name-validation
if(x509.SubjectName.Name == "CN=localhost") { }
}
store.Close();
}
}
}
Short Link: https://sg.run/XZ6B