NAME

PAGI::FastAPI::BotProtection::ProofOfWork - Stateless Proof-of-Work Bot Mitigation Engine

VERSION

Version v1.0.0

SYNOPSIS

use PAGI::FastAPI::BotProtection::ProofOfWork;

my $pow = PAGI::FastAPI::BotProtection::ProofOfWork->new(
    difficulty => 4,
    secret     => 'app_secret_key',
    ttl        => 300,
);

# Generate a signed challenge for an incoming IP
my $challenge = $pow->create_challenge('192.168.1.100');

# Verify client submission
my $is_valid = $pow->verify(
    $challenge->{challenge},
    $client_nonce,
    '192.168.1.100'
);

DESCRIPTION

PAGI::FastAPI::BotProtection::ProofOfWork provides a stateless, cryptographic Proof-of-Work (PoW) challenge-and-response engine designed to mitigate automated web scraping, credential stuffing, and bot attacks.

When a client requests access, the engine generates an HMAC-signed challenge requiring the client's browser to compute a SHA-256 hash collision (finding a nonce that yields a hash beginning with a set number of leading zeros).

Because verification relies on HMAC signatures, the engine is entirely stateless and does not require shared memory, database storage, or external caching backends.

Challenge strings are safe to use with both IPv4 and IPv6 client addresses; internally, fields are delimited with | rather than :, since IPv6 literals (e.g. ::1, 2001:db8::1) contain colons themselves.

CONSTRUCTOR

new(%options)

Instantiates a new Proof-of-Work engine. Accepts the following named parameters:

  • difficulty (Optional)

    Integer specifying the number of leading hexadecimal zeros required in the calculated SHA-256 hash collision. Higher values exponentially increase CPU effort for the client while keeping server verification costs near instant. Defaults to 3.

  • secret (Optional)

    A secret seed scalar used to generate HMAC signatures for challenges. Must be customized in production environments to prevent challenge tampering or forgery. Defaults to 'change_me_in_production'.

  • ttl (Optional)

    Integer specifying the validity window of generated challenges in seconds. Defaults to 300 (5 minutes).

METHODS

create_challenge($client_ip)

my $data = $pow->create_challenge('10.0.0.1');

Generates a signed challenge string bound to the client's IP address, difficulty level, and timestamp.

Returns a HashRef containing:

  • challenge: The signed challenge token string.

  • difficulty: The difficulty integer.

  • expires: The UNIX expiration epoch.

verify($challenge_str, $nonce, $client_ip)

my $bool = $pow->verify($challenge_str, $nonce, $client_ip);

Validates a client's Proof-of-Work solution. Performs signature integrity verification, expiration checking, IP matching, and cryptographic hash collision calculation.

Returns 1 if valid, or 0 if verification fails.

SEE ALSO

PAGI::FastAPI::Middleware::BotProtection, PAGI::FastAPI

AUTHOR

Mohammad Sajid Anwar, <mohammad.anwar at yahoo.com>

BUGS

Please report any bugs or feature requests through the web interface at https://github.com/manwar/PAGI-FastAPI/issues. I will be notified and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc PAGI::FastAPI::BotProtection::ProofOfWork

You can also look for information at:

LICENSE AND COPYRIGHT

Copyright (C) 2026 Mohammad Sajid Anwar.

This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License (2.0).