PHPackages                             danielmarschall/php\_clientchallenge - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. danielmarschall/php\_clientchallenge

ActivePackage[Utility &amp; Helpers](/categories/utility)

danielmarschall/php\_clientchallenge
====================================

Server requests using client-challenges in order to mitigate resource starvation

111PHP

Since Apr 9Pushed 3y ago1 watchersCompare

[ Source](https://github.com/danielmarschall/php_clientchallenge)[ Packagist](https://packagist.org/packages/danielmarschall/php_clientchallenge)[ RSS](/packages/danielmarschall-php-clientchallenge/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Server requests using client challenges
=======================================

[](#server-requests-using-client-challenges)

### What is it?

[](#what-is-it)

This PHP/JavaScript package can be used to add client challenges on top of your AJAX requests to protect your scripts against brute-force or DoS attacks. It can also protect your server against resource starvation attacks, for example, if you have a login script that uses a complex hash algorithm like BCrypt.

### Usage example

[](#usage-example)

A usage example is located in the directory example/

### System requirements

[](#system-requirements)

- PHP-compatible web server (tested with Apache 2, nginx, and Microsoft IIS)
- PHP 7.0 or higher (also tested with PHP 8.0)
- Independent of operating system (tested with Windows, Linux, and macOS X)

### Program flow

[](#program-flow)

#### 1. Request from Client to Server (Get Challenge)

[](#1-request-from-client-to-server-get-challenge)

Request parameters:

- None

The server will generate a secret random number between Min and Max. The difference between Min and Max is the complexity constant.

Response:

- Current time ("Start time")
- IP address of the client
- Challenge = `Hash(StartTime + IP address + Random number)`
- Min value
- Max value
- Challenge integrity = `Hash_HMAC(Challenge, ServerSecret)`

Additionally, the server will create a "transaction file" (which prevents a replay attack). The filename is `Hash_HMAC(IP+Random, ServerSecret)`.

The client will now brute-force all values to find the random value between Min and Max.

#### 2. Request from Client to Server (Solve Challenge and request the resource)

[](#2-request-from-client-to-server-solve-challenge-and-request-the-resource)

Request parameters:

- StartTime (as received previously from the server)
- IP address of the client (as received previously from the server)
- Challenge (as received previously from server)
- Answer (the random number found)
- Challenge Integrity (as received previously from the server)

The server will do:

- Check if parameters exist and have the correct data type
- Verify that the IP address is the same, otherwise return the error "IP address changed"
- Verify StartTime is not older than "X" minutes\*, otherwise return the error "Challenge expired"
- Verify that the challenge integrity fits the HMAC of the Challenge
- Check if the challenge was solved, i.e. Original Challenge matches `Hash(StartTime + IP + Answer)`
- Check if the transaction file exists, otherwise return the error "Challenge submitted twice"
- If all is OK, delete the transaction file (to prevent the answer is sent again) and grant access to the resource

Note: Depending on when you solve the challenge, you should decide on a fitting timeout value, e.g.

- When the challenge is solved once the login/contact/... form is shown -&gt; choose a timeout value of 10 minutes. The usage of a "transaction file" is important, because the same challenge can be submitted within 10 minutes.
- When the challenge is solved during the pressing of the "log in/send/..." button -&gt; choose a timeout value of 10-30 seconds (depending on what your complexity constant is and how fast the client CPU is). Usage of "transaction file" is still recommended, but not as important.

### Reporting a bug

[](#reporting-a-bug)

You can file a bug report here:

-
-
- [https://github.com/danielmarschall/php\_clientchallenge/issues](https://github.com/danielmarschall/php_clientchallenge/issues)

### Support

[](#support)

If you have any questions or need help, please contact us:

###  Health Score

14

—

LowBetter than 2% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity22

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/e3a3ef0452f1d6ecc846289b368b332f61897b6381e947a3635e733be23f6f54?d=identicon)[danielmarschall](/maintainers/danielmarschall)

---

Top Contributors

[![danielmarschall](https://avatars.githubusercontent.com/u/28412477?v=4)](https://github.com/danielmarschall "danielmarschall (12 commits)")

### Embed Badge

![Health badge](/badges/danielmarschall-php-clientchallenge/health.svg)

```
[![Health](https://phpackages.com/badges/danielmarschall-php-clientchallenge/health.svg)](https://phpackages.com/packages/danielmarschall-php-clientchallenge)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
