PHPackages                             cirrusidentity/simplesamlphp-module-ratelimit - 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. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. cirrusidentity/simplesamlphp-module-ratelimit

ActiveSimplesamlphp-module[Authentication &amp; Authorization](/categories/authentication)

cirrusidentity/simplesamlphp-module-ratelimit
=============================================

Ratelimit certain actions, such as username + password login

v3.0.1(1y ago)624.1k↓18%2[1 issues](https://github.com/cirrusidentity/simplesamlphp-module-ratelimit/issues)PHPPHP ^8.1CI failing

Since Mar 13Pushed 1y ago6 watchersCompare

[ Source](https://github.com/cirrusidentity/simplesamlphp-module-ratelimit)[ Packagist](https://packagist.org/packages/cirrusidentity/simplesamlphp-module-ratelimit)[ RSS](/packages/cirrusidentity-simplesamlphp-module-ratelimit/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (5)Versions (11)Used By (0)

**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [Overview](#overview)
- [Installation](#installation)
- [Rate Limiting Auth Source](#rate-limiting-auth-source)
    - [Limiters](#limiters)
    - [Configuration](#configuration)
        - [Sample Configuration](#sample-configuration)
            - [Standalone delegate/SSP 2 style configuration](#standalone-delegatessp-2-style-configuration)
            - [Embedded delegate/SSP 1.x style configuration](#embedded-delegatessp-1x-style-configuration)
    - [Blocking behavior](#blocking-behavior)
- [Login Loop Detection](#login-loop-detection)
    - [Configuration](#configuration-1)
- [Exploring with Docker](#exploring-with-docker)
    - [Things to try](#things-to-try)
        - [Blocking logins](#blocking-logins)
        - [Loop Detection](#loop-detection)
- [Development](#development)

Overview
========

[](#overview)

This module provides functionality to rate limit aspects of SSP

Installation
============

[](#installation)

- SSP 2.2: Use v3 (currently at v3.0.0)
- SSP 2.0 or 2.1: Use v2 (currently at v2.0.0-alpha.1)
- SSP 1: Use v1 (currently at 1.10)

    composer require cirrusidentity/simplesamlphp-module-ratelimit

Rate Limiting Auth Source
=========================

[](#rate-limiting-auth-source)

Any authsource that uses username and password (and also extends `UserPassBase`) can be wrapped with `RateLimitUserPass` to limit the number of authentication attempts an attacker can make.

Limiters
--------

[](#limiters)

- DeviceCookieLimimter: This sets a device cookie on successful authentications. Subsequent authentication attempts for the same user, on the same device will be allowed to proceed. This prevents an attacker from denial of servicing other users.
- IpLimiter: Allow limiting attempts by IP address. Allows white listing IPs and subnets to exclude
- PasswordStuffLimiter: Limits the amount of attempts an incorrect password can be used. Used to prevent password stuffing attacks where an attacker uses the same password but varies the username
- UsernameLimiter: Limits the amount of attempts by username.

Configuration
-------------

[](#configuration)

All included limiters support these 2 settings:

- limit: (int)The number of failed attempts before limiter takes affect
- window: (string) An ISO8601 duration string for the time window to track limit. Example: PT5M would be 5 minutes. P14D would be 14 days.

Configuration should be done in `authsources.php`. The `RateLimitUserPass` authsource wraps other auth sources to enforce the rate limits. Each of your existing `authsource` definitions should get moved inside the `'delegate'` key.

`limiters` are run in the order defined, and not in numerical order of the keys.

### Sample Configuration

[](#sample-configuration)

#### Standalone delegate/SSP 2 style configuration

[](#standalone-delegatessp-2-style-configuration)

In SSP v2, on the IdP side, an attacker cannot invoke an authsource directly. This allows you to define the rate limit authsource and have it reference another one in the config file.

```
$config = [

//  Sample authsource prior to using rate limiting
   'sample' => [
       'ldap:Ldap',
       //Other ldap:LDAP options
   ],

// Sample authsource after moving to rate limiting
     'sample-ratelimit' => [  // Authsource name stays the same
        'ratelimit:RateLimitUserPass',
         'delegate' => 'sample',
         'ratelimit' => [
               0 => [
                    'device',
                    'window' => 'P28D',
                    'limit' => 10,
               ],
               1 => [
                    'user',
                    'window' => 'PT5M',
                    'limit' => 20
               ],
               2 => [
                    'password',
                    'window' => 'PT5M',
                    'limit' => 20
               ],
               3 => [
                    'ip',
                    'window' => 'PT5M',
                    'limit' => 100,
                    'whitelist' => [
                       '1.2.3.4',
                       '5.6.7.0/24',
                    ],
               ],
          ],
     ]
];
```

#### Embedded delegate/SSP 1.x style configuration

[](#embedded-delegatessp-1x-style-configuration)

In SSP 1.x there was no way to hide an authsource from someone invoking it directly through the test authsources functionality. This meant to truly rate limit an authsource you had to hide its configuration inside the ratelimit authsource.

```
$config = [

//  Sample authsource prior to using rate limiting
//    'sample' => [
//        'ldap:Ldap',
//         //Other ldap:LDAP options
//     ],

// Sample authsource after moving to rate limiting
     'sample' => [  // Authsource name stays the same
        'ratelimit:RateLimitUserPass',
         'delegate' => [  // Previous authsource configuration for 'sample' moves here
            'ldap:Ldap',
            //Other ldap:LDAP options
         ],
         'ratelimit' => [
               0 => [
                    'device',
                    'window' => 'P28D',
                    'limit' => 10,
               ],
               1 => [
                    'user',
                    'window' => 'PT5M',
                    'limit' => 20
               ],
               2 => [
                    'password',
                    'window' => 'PT5M',
                    'limit' => 20
               ],
               3 => [
                    'ip',
                    'window' => 'PT5M',
                    'limit' => 100,
                    'whitelist' => [
                       '1.2.3.4',
                       '5.6.7.0/24',
                    ],
               ],
          ],
     ]
 ];
```

If no `ratelimit` block is defined then the `UsernameLimiter` and `DeviceCookieLimiter`are automatically enabled.

Blocking behavior
-----------------

[](#blocking-behavior)

When a login attempt is blocked the authsource throws a `WRONGUSERPASS` error.

Login Loop Detection
====================

[](#login-loop-detection)

When configured, will stop the browser from looping indefinately when interacting with a broken/mis configured SP.

Configuration
-------------

[](#configuration-1)

```
    $config['authproc.idp'] = [
...
        51 => [
            'class' => 'loginloopdetection:LoopDetection',
            'secondsSinceLastSso' => 5,
            'loopsBeforeWarning' => 15,
            'logOnly' => false,
        ],
...

```

Exploring with Docker
=====================

[](#exploring-with-docker)

You can explore these features with Docker.

```
docker network create --driver bridge ratelimit-net
# Ratelimit requires you to define a "store" to store rate limit data. These tests use memcached
docker run --network ratelimit-net -p 11211:11211 --name memcache-ratelimit -d memcached

docker run -d --name ssp-ratelimit \
   --network ratelimit-net \
   --mount type=bind,source="$(pwd)",target=/var/simplesamlphp/staging-modules/ratelimit,readonly \
  -e STAGINGCOMPOSERREPOS=ratelimit \
  -e COMPOSER_REQUIRE="cirrusidentity/simplesamlphp-module-ratelimit:@dev" \
  -e SSP_ENABLED_MODULES="ratelimit" \
  --mount type=bind,source="$(pwd)/tests/docker/metadata/",target=/var/simplesamlphp/metadata/,readonly \
  --mount type=bind,source="$(pwd)/tests/docker/authsources.php",target=/var/simplesamlphp/config/authsources.php,readonly \
  --mount type=bind,source="$(pwd)/tests/docker/config-override.php",target=/var/simplesamlphp/config/config-override.php,readonly \
  --mount type=bind,source="$(pwd)/tests/docker/cert/",target=/var/simplesamlphp/cert/,readonly \
  --mount type=bind,source="$(pwd)/tests/docker/public/looping-login.php",target=/var/simplesamlphp/public/looping-login.php,readonly \
   -p 443:443 cirrusid/simplesamlphp:v2.2.2
```

Then log in as `admin:secret` to to confirm SSP is running.

Things to try
-------------

[](#things-to-try)

### Blocking logins

[](#blocking-logins)

To reach the `admin` test login endpoints you must first authenticate as an admin. Login to as `admin:secret`

The [example-userpass](https://ratelimit.local.stack-dev.cirrusidentity.com/simplesaml/module.php/admin/test/example-userpass)authsource is configured with a low number of attempts for logins. Try logging in 3 or 4 times with the same username and wrong password and you should see log lines like

```
[Tue Dec 06 22:04:23.114923 2022] [php:notice] [pid 58] [client 172.18.0.1:59924] %date{M j H:i:s} simplesamlphp NOTICE STAT [c854ab328b] User 'testuser' login attempt blocked by SimpleSAML\\Module\\ratelimit\\Limiters\\UsernameLimiter

```

If you try varying usernames and the same password (a password stuffing attack) then after a few attempts you should see

```
User 'pass2' login attempt blocked by SimpleSAML\\Module\\ratelimit\\Limiters\\PasswordStuffingLimiter

```

### Loop Detection

[](#loop-detection)

Visiting the [looping-login page](https://ratelimit.local.stack-dev.cirrusidentity.com/simplesaml/looping-login.php)will issue a request as an SP to log in with a local IdP and print out the attributes. User `member`, password `memberpass`. If you add a `loop` query parameter you can mimic a misbehaving SP that continuously sends a user to the IdP to login. The IdP is configured (see `saml20-idp-hosted.php`) with loop detection and will display an error page after too many loops.

```
WARNING [c854ab328b] LoopDetection: Only 0 seconds since last SSO for this user from the SP 'https://ratelimit.local.stack-dev.cirrusidentity.com/simplesaml/module.php/saml/sp/metadata.php/loop-test' LoopDetectionCount 5

```

Development
===========

[](#development)

Run `phpcs` to check code style

```
./vendor/bin/phpcs

```

Run `phpunit` to test

```
./vendor/bin/phpunit

```

You can auto correct some findings from phpcs. It is recommended you do this after stage your changes (or maybe even commit) since there is a non-trivial chance it will just mess up your code.

```
./vendor/bin/phpcbf

```

I always have trouble with `psalm` and it's cache, so I tend to run without caching

```
 ./vendor/bin/psalm --no-cache

```

###  Health Score

45

—

FairBetter than 93% of packages

Maintenance45

Moderate activity, may be stable

Popularity33

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor1

Top contributor holds 66.2% 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.

###  Release Activity

Cadence

Every ~376 days

Recently: every ~414 days

Total

6

Last Release

378d ago

Major Versions

v1.1.0 → v2.0.0-alpha.12022-12-07

v2.0.0-alpha.1 → v3.0.02024-05-16

PHP version history (2 changes)v2.0.0-alpha.1PHP &gt;=7.4 || ^8.0

v3.0.0PHP ^8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/932934?v=4)[Patrick](/maintainers/pradtke)[@pradtke](https://github.com/pradtke)

---

Top Contributors

[![pradtke](https://avatars.githubusercontent.com/u/932934?v=4)](https://github.com/pradtke "pradtke (43 commits)")[![tvdijen](https://avatars.githubusercontent.com/u/841045?v=4)](https://github.com/tvdijen "tvdijen (18 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (3 commits)")[![dunkoh](https://avatars.githubusercontent.com/u/150254?v=4)](https://github.com/dunkoh "dunkoh (1 commits)")

### Embed Badge

![Health badge](/badges/cirrusidentity-simplesamlphp-module-ratelimit/health.svg)

```
[![Health](https://phpackages.com/badges/cirrusidentity-simplesamlphp-module-ratelimit/health.svg)](https://phpackages.com/packages/cirrusidentity-simplesamlphp-module-ratelimit)
```

###  Alternatives

[simplesamlphp/simplesamlphp

A PHP implementation of a SAML 2.0 service provider and identity provider.

1.1k12.4M193](/packages/simplesamlphp-simplesamlphp)[simplesamlphp/simplesamlphp-module-webauthn

A PHP implementation of a FIDO2 / WebAuthn authentication agent

181.4k](/packages/simplesamlphp-simplesamlphp-module-webauthn)

PHPackages © 2026

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