Skip to content

Commit

Permalink
Add basic vulnerability page validation
Browse files Browse the repository at this point in the history
  • Loading branch information
zivkan committed Apr 5, 2023
1 parent e40d06f commit 62c4aa7
Showing 1 changed file with 94 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ public async Task<GetVulnerabilityInfoResult> GetVulnerabilityInfoAsync(SourceCa
tasks[i] = GetVulnerabilityDataAsync(indexEntry, cacheContext, logger, cancellationToken);
}

indexEntries = GetValidIndexEntries(indexEntries, ref exceptions);

await Task.WhenAll(tasks);

for (int i = 0; i < tasks.Length; i++)
Expand Down Expand Up @@ -201,5 +203,97 @@ static void AddException(ref List<Exception>? exceptions, Exception ex)
return aggregateException;
}
}

private IReadOnlyList<V3VulnerabilityIndexEntry> GetValidIndexEntries(IReadOnlyList<V3VulnerabilityIndexEntry> indexEntries, ref List<Exception>? exceptions)
{
List<V3VulnerabilityIndexEntry> validIndexEntries = new(indexEntries.Count);
HashSet<string> pageNames =
#if NETSTANDARD
new(comparer: StringComparer.InvariantCultureIgnoreCase);
#else
new(indexEntries.Count, StringComparer.InvariantCultureIgnoreCase);
#endif

for (int i = 0; i < indexEntries.Count; i++)
{
V3VulnerabilityIndexEntry entry = indexEntries[i];

string name = entry.Name;
if (string.IsNullOrWhiteSpace(name))
{
string message = string.Format("Vulnerability page index {0} does not contain a name (Source: '{1}')",
i, _sourceRepository.PackageSource.Name);
AddException(new FatalProtocolException(message), ref exceptions);
continue;
}

const int maxNameLength = 32;
if (name.Length > maxNameLength)
{
string message = string.Format("Vulnerability page index {0} name is longer than {1} characters (Source: '{2}')",
i, maxNameLength, _sourceRepository.PackageSource.Name);
AddException(new FatalProtocolException(message), ref exceptions);
continue;
}

bool hasOnlyValidChars = true;
for (int j = 0; j < name.Length; j++)
{
char c = name[j];
if (!(c >= 'A' && c <= 'Z')
&& !(c >= 'a' && c <= 'z')
&& !(c >= '0' && c <= '9')
&& !(c == '-' || c == '_'))
{
hasOnlyValidChars = false;
break;
}
}
if (!hasOnlyValidChars)
{
string message = string.Format("Vulnerability page index {0} contains invalid characters (Source: '{1}')",
i, _sourceRepository.PackageSource.Name);
AddException(new FatalProtocolException(message), ref exceptions);
continue;
}

if (entry.Url == null)
{
string message = string.Format("Vulnerability page '{0}' does not contain a URL (Source: '{1}')",
entry.Name, _sourceRepository.PackageSource.Name);
AddException(new FatalProtocolException(message), ref exceptions);
continue;
}

if (entry.Url.Scheme != "https" && entry.Url.Scheme != "http")
{
string message = string.Format("Vulnerability page '{0}' contains URL that is not http(s) (Source: '{1}')",
entry.Name, _sourceRepository.PackageSource.Name);
AddException(new FatalProtocolException(message), ref exceptions);
continue;
}

if (!pageNames.Add(entry.Name))
{
string message = string.Format("Vulnerability page name '{0}' is not unique. Only using the first (Source: '{1}')",
entry.Name, _sourceRepository.PackageSource.Name);
AddException(new FatalProtocolException(message), ref exceptions);
continue;
}

validIndexEntries.Add(entry);
}

return validIndexEntries;

static void AddException(Exception exception, ref List<Exception>? exceptions)
{
if (exceptions == null)
{
exceptions = new();
}
exceptions.Add(exception);
}
}
}
}

0 comments on commit 62c4aa7

Please sign in to comment.