Skip to content

Commit

Permalink
Use generated number itself as a captcha secret instead of its text r…
Browse files Browse the repository at this point in the history
…epresentation
  • Loading branch information
Pavel Sviridov committed May 6, 2023
1 parent c4b822e commit 5457b92
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 14 deletions.
3 changes: 2 additions & 1 deletion src/DNTCaptcha.Core/DNTCaptchaApiProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public DNTCaptchaApiResponse CreateDNTCaptcha(DNTCaptchaTagHelperHtmlAttributes
var number = _randomNumberProvider.NextNumber(captchaAttributes.Min, captchaAttributes.Max);
var randomText = _captchaTextProvider(captchaAttributes.DisplayMode).GetText(number, captchaAttributes.Language);
var encryptedText = _captchaProtectionProvider.Encrypt(randomText);
var encryptedNumber = _captchaProtectionProvider.Encrypt(number.ToString(CultureInfo.InvariantCulture));
var captchaImageUrl = getCaptchaImageUrl(captchaAttributes, encryptedText);
var captchaDivId = Invariant($"{_captchaOptions.CaptchaClass}{Guid.NewGuid():N}{_randomNumberProvider.NextNumber(captchaAttributes.Min, captchaAttributes.Max)}");
var cookieToken = $".{captchaDivId}";
Expand All @@ -74,7 +75,7 @@ public DNTCaptchaApiResponse CreateDNTCaptcha(DNTCaptchaTagHelperHtmlAttributes
{
DntCaptchaImgUrl = captchaImageUrl,
DntCaptchaId = captchaDivId,
DntCaptchaTextValue = encryptedText,
DntCaptchaTextValue = encryptedNumber,
DntCaptchaTokenValue = hiddenInputToken
};
}
Expand Down
3 changes: 2 additions & 1 deletion src/DNTCaptcha.Core/DNTCaptchaTagHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public void Process(TagHelperContext context, TagHelperOutput output)
var number = _randomNumberProvider.NextNumber(Min, Max);
var randomText = _captchaTextProvider(DisplayMode).GetText(number, Language);
var encryptedText = _captchaProtectionProvider.Encrypt(randomText);
var encryptedNumber = _captchaProtectionProvider.Encrypt(number.ToString(CultureInfo.InvariantCulture));

var captchaImage = getCaptchaImageTagBuilder(ViewContext, encryptedText);
output.Content.AppendHtml(captchaImage);
Expand All @@ -113,7 +114,7 @@ public void Process(TagHelperContext context, TagHelperOutput output)
output.Content.AppendHtml(refreshButton);
}

var hiddenInput = getHiddenInputTagBuilder(encryptedText);
var hiddenInput = getHiddenInputTagBuilder(encryptedNumber);
output.Content.AppendHtml(hiddenInput);

var textInput = getTextInputTagBuilder();
Expand Down
37 changes: 25 additions & 12 deletions src/DNTCaptcha.Core/DNTCaptchaValidatorService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public class DNTCaptchaValidatorService : IDNTCaptchaValidatorService
private readonly DNTCaptchaOptions _captchaOptions;
private readonly ICaptchaCryptoProvider _captchaProtectionProvider;
private readonly ICaptchaStorageProvider _captchaStorageProvider;
private readonly Func<DisplayMode, ICaptchaTextProvider> _captchaTextProvider;
private readonly IHttpContextAccessor _contextAccessor;
private readonly ILogger<DNTCaptchaValidatorService> _logger;

Expand All @@ -26,7 +25,6 @@ public DNTCaptchaValidatorService(
ILogger<DNTCaptchaValidatorService> logger,
ICaptchaCryptoProvider captchaProtectionProvider,
ICaptchaStorageProvider captchaStorageProvider,
Func<DisplayMode, ICaptchaTextProvider> captchaTextProvider,
IOptions<DNTCaptchaOptions> options
)
{
Expand All @@ -35,7 +33,6 @@ IOptions<DNTCaptchaOptions> options
throw new ArgumentNullException(nameof(captchaProtectionProvider));
_captchaStorageProvider =
captchaStorageProvider ?? throw new ArgumentNullException(nameof(captchaStorageProvider));
_captchaTextProvider = captchaTextProvider ?? throw new ArgumentNullException(nameof(captchaTextProvider));
_contextAccessor = contextAccessor ?? throw new ArgumentNullException(nameof(contextAccessor));
_captchaOptions = options == null ? throw new ArgumentNullException(nameof(options)) : options.Value;
}
Expand Down Expand Up @@ -76,23 +73,29 @@ public bool HasRequestValidCaptchaEntry(

inputText = inputText.ToEnglishNumbers();

if (!long.TryParse(
inputText,
NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands,
CultureInfo.InvariantCulture,
out var inputNumber))
if (!TryParseNumber(inputText, out var inputNumber))
{
_logger.LogDebug("inputText is not a number.");
return false;
}

var decryptedText = _captchaProtectionProvider.Decrypt(captchaText);

var numberToText = _captchaTextProvider(captchaGeneratorDisplayMode)
.GetText(inputNumber, captchaGeneratorLanguage);
if (decryptedText?.Equals(numberToText, StringComparison.Ordinal) != true)
if (string.IsNullOrEmpty(decryptedText))
{
_logger.LogDebug($"{decryptedText} != {numberToText}");
_logger.LogDebug("Decrypted text is empty.");
return false;
}

if (!TryParseNumber(decryptedText, out var decryptedNumber))
{
_logger.LogDebug("Decrypted text is not a number.");
return false;
}

if (decryptedNumber != inputNumber)
{
_logger.LogDebug("{DecryptedNumber} != {InputNumber}", decryptedNumber, inputNumber);
return false;
}

Expand Down Expand Up @@ -154,5 +157,15 @@ private bool isValidCookie(HttpContext httpContext, string decryptedText, string

private static bool shouldValidate(HttpContext context) =>
string.Equals("POST", context.Request.Method, StringComparison.OrdinalIgnoreCase);

private static bool TryParseNumber(string str, out long number)
{
return long.TryParse(
str,
NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands,
CultureInfo.InvariantCulture,
out number
);
}
}
}

0 comments on commit 5457b92

Please sign in to comment.