v1.1.0
·
5 commits
to master
since this release
Added an adapter layer to integrate PoW-based DoS attack protection with HTTP servers and clients.
Change Log
The format is based on Keep a Changelog.
Added
- Middlewares:
LoadLevelMiddleware: tracks the current server load by counting in-flight requests:- Intended to be used in conjunction with the dynamic hash difficulty provider.
- Interacts with the latter via an interface.
ResourceMiddleware: sets the request URL as the protected resource in the request context:- Optionally enriches the URL with a host:
- Host can be taken from the request itself.
- Host can be taken from proxy-provided headers.
- Optionally enriches the URL with a host:
DoSProtectorMiddleware: implements the core logic of DoS attack protection using the PoW algorithm:- If a request lacks the solution header
X-Dos-Protector-Solution, it generates a new challenge, signs it, and returns it via the response headersX-Dos-Protector-ChallengeandX-Dos-Protector-Signature. - If a request includes the solution header
X-Dos-Protector-Solution, it parses and validates the solution:- If validation fails, the
403 Forbiddenerror response is returned. - If validation succeeds, the request proceeds to the protected handler.
- If validation fails, the
- All operations are delegated to the corresponding use case via an interface.
- If a request lacks the solution header
- Models:
- Introduced adapter-layer models:
Challenge: corresponds to the domain-level challenge entity.Solution: corresponds to the domain-level solution entity.
- Functions:
NewChallengeFromEntity()andNewSolutionFromEntity(): convert domain entities into adapter-layer models.ParseChallengeFromQuery()andParseSolutionFromQuery(): parse adapter-layer models from URL-encoded query strings.
- Methods:
Challenge.ToQuery()andSolution.ToQuery(): serialize adapter-layer models into URL-encoded query strings.
- Introduced adapter-layer models:
- Errors:
TransformErrorToStatusCode()maps internal errors to appropriate HTTP status codes:- Internal error
dosProtectorUsecaseErrors.ErrInvalidParameterscorresponds to the HTTP status code400 Bad Request. - Internal error
powErrors.ErrValidationFailurecorresponds to the HTTP status code403 Forbidden. - Other errors correspond to the HTTP status code
500 Internal Server Error.
- Internal error
- Clients:
HTTPClientWrapper: a wrapper around the standard HTTP client (via an interface) that automates interaction withDoSProtectorMiddleware(see above):- Sends an initial
HEADrequest to the target URL to retrieve the challenge and signature from theX-Dos-Protector-ChallengeandX-Dos-Protector-Signatureheaders, respectively. - Parses and solves the challenge by invoking the corresponding use case via an interface.
- Clones the original request and enriches it with the computed solution and signature in the headers
X-Dos-Protector-SolutionandX-Dos-Protector-Signature. - Sends the enriched request to the server as usual.
- Sends an initial
- Tests:
newTestHTTPClient()andnewTestServer()for reusable test setup.- Integration tests for middleware and client interaction with constant and dynamic providers.
- Docs:
newExampleHTTPClient()andnewExampleServer()for reusable example setup.- Demonstrations of usage with constant and dynamic providers.
Changed
- Refactored
usecases/models:- Renamed
MessageAuthenticationCodefields toSignaturefor clarity.
- Renamed
Features
- use of patterns:
- implementation based on Clean Architecture principles:
- separate use case layers for server and client;
- adapter layer for integrating with HTTP servers and clients;
- input parsing and validation handled internally in the use cases (inputs are passed as raw DTOs);
- relies on the library
github.com/thewizardplusplus/go-powfor PoW algorithm implementation;
- implementation based on Clean Architecture principles:
- use cases:
- server-side:
SignChallenge(): generate a message authentication code (MAC) signature for a challenge:- MAC signature generation uses a secret key and configurable hashing algorithm;
GenerateChallenge(): generate a challenge with specified parameters:- number of leading zero bits (hash difficulty);
- current timestamp rounded to a configurable precision;
- time to live (TTL);
- target resource URI;
- payload consisting of static and random parts;
- hashing algorithm;
GenerateSignedChallenge(): generate a challenge and sign it;VerifySolution(): verify the correctness of a PoW solution;VerifySolutionAndChallengeSignature(): verify both PoW solution and challenge MAC signature;
- client-side:
SolveChallenge(): solve a challenge using the PoW algorithm;
- providers:
- extensible provider interfaces for:
- hash difficulty;
- target resource URI;
- static payload part;
- built-in provider implementations:
- extensible provider interfaces for:
- server-side:
- adapter layer:
- middlewares:
LoadLevelMiddleware: tracks the current server load by counting in-flight requests:- intended to be used in conjunction with the dynamic hash difficulty provider (see above);
- interacts with the latter via an interface;
ResourceMiddleware: sets the request URL as the protected resource in the request context:- optionally enriches the URL with a host:
- host can be taken from the request itself;
- host can be taken from proxy-provided headers;
- optionally enriches the URL with a host:
DoSProtectorMiddleware: implements the core logic of DoS attack protection using the PoW algorithm:- if a request lacks the solution header
X-Dos-Protector-Solution, it generates a new challenge, signs it, and returns it via the response headersX-Dos-Protector-ChallengeandX-Dos-Protector-Signature; - if a request includes the solution header
X-Dos-Protector-Solution, it parses and validates the solution:- if validation fails, the
403 Forbiddenerror response is returned; - if validation succeeds, the request proceeds to the protected handler;
- if validation fails, the
- all operations are delegated to the corresponding use case via an interface;
- if a request lacks the solution header
- models:
- introduced adapter-layer models:
Challenge: corresponds to the domain-level challenge entity;Solution: corresponds to the domain-level solution entity;
- functions:
NewChallengeFromEntity()andNewSolutionFromEntity(): convert domain entities into adapter-layer models;ParseChallengeFromQuery()andParseSolutionFromQuery(): parse adapter-layer models from URL-encoded query strings;
- methods:
Challenge.ToQuery()andSolution.ToQuery(): serialize adapter-layer models into URL-encoded query strings;
- introduced adapter-layer models:
- errors:
TransformErrorToStatusCode()maps internal errors to appropriate HTTP status codes:- internal error
dosProtectorUsecaseErrors.ErrInvalidParameterscorresponds to the HTTP status code400 Bad Request; - internal error
powErrors.ErrValidationFailurecorresponds to the HTTP status code403 Forbidden; - other errors correspond to the HTTP status code
500 Internal Server Error;
- internal error
- clients:
HTTPClientWrapper: a wrapper around the standard HTTP client (via an interface) that automates interaction withDoSProtectorMiddleware(see above):- sends an initial
HEADrequest to the target URL to retrieve the challenge and signature from theX-Dos-Protector-ChallengeandX-Dos-Protector-Signatureheaders, respectively; - parses and solves the challenge by invoking the corresponding use case via an interface;
- clones the original request and enriches it with the computed solution and signature in the headers
X-Dos-Protector-SolutionandX-Dos-Protector-Signature; - sends the enriched request to the server as usual.
- sends an initial
- middlewares: