Skip to content
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

Try to fix flake in hardcoded secrets test #4843

Merged
merged 3 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,28 @@

namespace Datadog.Trace.Iast.Analyzers;

internal class HardcodedSecretsAnalyzer
internal class HardcodedSecretsAnalyzer : IDisposable
{
private const int UserStringsArraySize = 100;
private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor<HardcodedSecretsAnalyzer>();
private static HardcodedSecretsAnalyzer? _instance = null;

private static bool _started = false;
private readonly ManualResetEventSlim _waitEvent = new(false);
private readonly TimeSpan _regexTimeout;
private bool _started = false;
private List<SecretRegex>? _secretRules = null;

private static List<SecretRegex>? _secretRules = null;

private static ManualResetEventSlim _waitEvent = new ManualResetEventSlim(false);

public HardcodedSecretsAnalyzer()
// Internal for testing
internal HardcodedSecretsAnalyzer(TimeSpan regexTimeout)
{
Log.Debug("HardcodedSecretsAnalyzer -> Init");
LifetimeManager.Instance.AddShutdownTask(RunShutdown);
_regexTimeout = regexTimeout;
_started = true;
Task.Run(() => PoolingThread())
.ContinueWith(t => Log.Error(t.Exception, "Error in Hardcoded secret analyzer"), TaskContinuationOptions.OnlyOnFaulted);
}

private static void PoolingThread()
private void PoolingThread()
{
try
{
Expand Down Expand Up @@ -106,11 +106,23 @@ private static void PoolingThread()
Log.Debug("HardcodedSecretsAnalyzer polling thread -> Exit");
}

internal static string? CheckSecret(string secret)
internal static void Initialize(TimeSpan regexTimeout)
{
lock (Log)
{
if (_instance == null)
{
_instance = new HardcodedSecretsAnalyzer(regexTimeout);
LifetimeManager.Instance.AddShutdownTask(_instance.Dispose);
}
}
}

internal string? CheckSecret(string secret)
{
if (_secretRules == null)
{
_secretRules = GenerateSecretRules();
_secretRules = GenerateSecretRules(_regexTimeout);
}

foreach (var rule in _secretRules)
Expand All @@ -124,22 +136,9 @@ private static void PoolingThread()
return null;
}

internal static void Initialize()
{
lock (Log)
{
if (_instance == null)
{
_instance = new HardcodedSecretsAnalyzer();
}
}
}

// Rules imported from https://github.com/gitleaks/gitleaks/blob/master/cmd/generate/config/rules
private static List<SecretRegex> GenerateSecretRules()
private static List<SecretRegex> GenerateSecretRules(TimeSpan timeout)
{
var timeout = TimeSpan.FromMilliseconds(Iast.Instance.Settings.RegexTimeout);

var res = new List<SecretRegex>(68); // Note: Update this with the new rules count, if modified

res.Add(new SecretRegex("aws-access-token", @"\b((A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16})(?:['|""|\n|\r|\s|\x60|;]|$)", timeout));
Expand Down Expand Up @@ -214,7 +213,7 @@ private static List<SecretRegex> GenerateSecretRules()
return res;
}

private void RunShutdown()
public void Dispose()
{
try
{
Expand Down
3 changes: 2 additions & 1 deletion tracer/src/Datadog.Trace/Iast/Iast.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

using System;
using System.Threading;
using Datadog.Trace.Configuration;
using Datadog.Trace.Iast.Analyzers;
Expand Down Expand Up @@ -41,7 +42,7 @@ private Iast(IastSettings settings = null)
_settings = settings ?? IastSettings.FromDefaultSources();
if (_settings.Enabled)
{
HardcodedSecretsAnalyzer.Initialize();
HardcodedSecretsAnalyzer.Initialize(TimeSpan.FromMilliseconds(_settings.RegexTimeout));
}

_overheadController = new OverheadController(_settings.MaxConcurrentRequests, _settings.RequestSampling);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

using Datadog.Trace.Iast;
using System;
using Datadog.Trace.Iast.Analyzers;
using FluentAssertions;
using Xunit;

namespace Datadog.Trace.Security.Unit.Tests.IAST;

public class HardcodedSecretsTests
public class HardcodedSecretsTests : IClassFixture<HardcodedSecretsTests.HardcodedSecretsFixture>
{
private readonly HardcodedSecretsAnalyzer _analyzer;

public HardcodedSecretsTests(HardcodedSecretsFixture fixture)
{
_analyzer = fixture.Analyzer;
}

[Theory]
[InlineData("private-key", "-----BEGIN OPENSSH PRIVATE KEY-----\r\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\r\nQyNTUxOQAAACA8YWKYztuuvxUIMomc3zv0OdXCT57Cc2cRYu3TMbX9XAAAAJDiKO3C4ijt\r\nwgAAAAtzc2gtZWQyNTUxOQAAACA8YWKYztuuvxUIMomc3zv0OdXCT57Cc2cRYu3TMbX9XA\r\nAAAECzmj8DGxg5YHtBK4AmBttMXDQHsPAaCyYHQjJ4YujRBTxhYpjO266/FQgyiZzfO/Q5\r\n1cJPnsJzZxFi7dMxtf1cAAAADHJvb3RAZGV2aG9zdAE=\r\n-----END OPENSSH PRIVATE KEY-----\r\n")]
[InlineData("aws-access-token", @"A3T43DROGX[[DD_SECRET]]R2PGF4BI5T")]
Expand Down Expand Up @@ -104,6 +111,14 @@ public class HardcodedSecretsTests
public void GivenAHardcodedSecretString_WhenAnalysed_ResultIsEspected(string rule, string secret)
{
var realSecret = secret.Replace("[[DD_SECRET]]", string.Empty);
Assert.Equal(rule, HardcodedSecretsAnalyzer.CheckSecret(realSecret));
_analyzer.CheckSecret(realSecret).Should().Be(rule);
}

public class HardcodedSecretsFixture : IDisposable
{
// We use a stupidly-big timeout here to avoid flake
internal HardcodedSecretsAnalyzer Analyzer { get; } = new(TimeSpan.FromMinutes(5));

public void Dispose() => Analyzer.Dispose();
}
}
Loading