PHPackages                             userfrosting/fortress - 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. [Validation &amp; Sanitization](/categories/validation)
4. /
5. userfrosting/fortress

AbandonedArchivedLibrary[Validation &amp; Sanitization](/categories/validation)

userfrosting/fortress
=====================

A PHP library for whitelisting, validating, and canonicalizing HTTP request data against a JSON Schema

4.5.0(5y ago)2549.4k↑718.2%9[11 issues](https://github.com/userfrosting/fortress/issues)[2 PRs](https://github.com/userfrosting/fortress/pulls)MITPHPPHP &gt;=7.1

Since Mar 29Pushed 5y ago7 watchersCompare

[ Source](https://github.com/userfrosting/fortress)[ Packagist](https://packagist.org/packages/userfrosting/fortress)[ Docs](https://github.com/userfrosting/fortress)[ RSS](/packages/userfrosting-fortress/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (5)Versions (20)Used By (0)

Fortress 4
==========

[](#fortress-4)

[![Latest Version](https://camo.githubusercontent.com/3f508b91c5729ea3345d3ec88874c13082b84cf1e86f25e465235fb60c126bf2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f7573657266726f7374696e672f666f7274726573732e737667)](https://github.com/userfrosting/fortress/releases)[![Software License](https://camo.githubusercontent.com/074b89bca64d3edc93a1db6c7e3b1636b874540ba91d66367c0e5e354c56d0ea/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e737667)](LICENSE.md)[![Join the chat at https://chat.userfrosting.com/channel/support](https://camo.githubusercontent.com/3ef275424b9a67f2277aea0eeb294f16f16660d8fc4073a0a988298d626d4c5a/68747470733a2f2f636861742e7573657266726f7374696e672e636f6d2f6170692f76312f736869656c642e7376673f6e616d653d5573657246726f7374696e67)](https://chat.userfrosting.com/channel/support)[![Donate](https://camo.githubusercontent.com/9b77bd2b1b19b6b8fcbff67c4cfa703b0ab2c936b33ce26d534e1222cbdcdea6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f70656e253230436f6c6c6563746976652d446f6e6174652d626c75652e737667)](https://opencollective.com/userfrosting#backer)

BranchBuildCoverageStyle[master](https://github.com/userfrosting/fortress)[![](https://github.com/userfrosting/fortress/workflows/Build/badge.svg?branch=master)](https://github.com/userfrosting/fortress/actions?query=workflow%3ABuild)[![](https://camo.githubusercontent.com/b411e97fca8b59a81dd77e09b6d56a02f61b50868ee4a1b864f37e41d5d3d6d4/68747470733a2f2f636f6465636f762e696f2f67682f7573657266726f7374696e672f666f7274726573732f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://codecov.io/gh/userfrosting/fortress)[![](https://camo.githubusercontent.com/b8bbc4cc037f431c317e7b757d050b72b4f8749cb23486426e3a4e023af4a51b/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f33303535313935342f736869656c643f6272616e63683d6d6173746572267374796c653d666c6174)](https://github.styleci.io/repos/30551954)[develop](https://github.com/userfrosting/fortress/tree/develop)[![](https://github.com/userfrosting/fortress/workflows/Build/badge.svg?branch=develop)](https://github.com/userfrosting/fortress/actions?query=workflow%3ABuild) [![](https://camo.githubusercontent.com/b34fbc67a6118f2f6457e6a8ee73d8b0d9b3f96897b272d6b769d54db41f3fd1/68747470733a2f2f636f6465636f762e696f2f67682f7573657266726f7374696e672f666f7274726573732f6272616e63682f646576656c6f702f67726170682f62616467652e737667)](https://codecov.io/gh/userfrosting/fortress)[![](https://camo.githubusercontent.com/76ca174269766505f1705e1f5c8aaec899c2e3cbff9ca4a28834e469561c7a18/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f33303535313935342f736869656c643f6272616e63683d646576656c6f70267374796c653d666c6174)](https://github.styleci.io/repos/30551954)If you simply want to show that you like this project, or want to remember it for later, you should **star**, not **fork**, this repository. Forking is only for when you are ready to create your own copy of the code to work on.

### By [Alex Weissman](https://alexanderweissman.com)

[](#by-alex-weissman)

Copyright (c) 2015-2019

A schema-driven system for elegant whitelisting, transformation and validation of user input on both the client and server sides from a unified set of rules.

Introduction
------------

[](#introduction)

Data from the outside world is the Achilles' heel of modern interactive web services and applications. Code injection, cross-site scripting (XSS), CSRF, and many other types of malicious attacks are successful when a web application accepts user input that it shouldn't have, or fails to neutralize the damaging parts of the input. Even non-malicious users can inadvertently submit something that breaks your web service, causing it to behave in some unexpected way.

For the sake of both security and quality user experience, it is important for a web developer to do two things:

1. Decide exactly what type of input your application should accept, and;
2. Decide how your application should behave when it receives something that violates those rules.

Sounds simple, right? Unfortunately, even experienced developers often slip up, allowing a malicious user to execute SQL or PHP on the application's server (or, in the case of XSS and CSRF attacks, allow a user to trick *other users* into executing malicious code).

Part of the problem is that this kind of filtering must be done at every point in the application where the user can submit raw data to the server. A modern web application might accept hundreds of different types of POST requests, and it can become extremely tedious to code the rules for each request manually. Much of this work must also be done on both the client side (for user experience) and the server side (for security).

Fortress solves this problem by providing a uniform interface for validating raw user input on both the client side (in Javascript) and on the server side (in PHP) using a single unified set of rules. All you have to do is create a **request schema**, which defines what fields you're expecting the user to submit, and [rules](https://github.com/userfrosting/wdvss) for how to handle the contents of those fields. For example, you might want to check that an email address is well-formed. The request schema, which is simply a YAML or JSON document, makes it easy to manipulate these rules in one place.

The request schema can be applied on the server side to received request data, but also be transformed to formats compatible with client-side validation libraries such as [the jQuery Validation plugin](https://jqueryvalidation.org/), making it easy to perform client- and server-side validation without having to write every rule twice.

An example request schema, written using the [WDVSS standard](https://github.com/userfrosting/wdvss):

**schema.yaml**

```
name:
    validators:
        length:
            min: 1
            max: 200
            message: Please enter a name between 1 and 200 characters.
        required :
            message : Please specify your name.

email:
    validators:
        required:
            message: Please specify your email address.

        length:
            min: 1
            max: 150
            message: Please enter an email address between 1 and 150 characters.

        email:
            message : That does not appear to be a valid email address.

message:
    validators:
        required:
            message: Please enter a message

```

Dependencies
------------

[](#dependencies)

- PHP 5.6+
- [Valitron (server-side validation)](https://github.com/vlucas/valitron)
- [HTML Purifier](https://github.com/ezyang/htmlpurifier)
- [Symfony YAML Parser](http://symfony.com/doc/current/components/yaml.html)
- userfrosting/i18n
- userfrosting/support

Installation
------------

[](#installation)

### To install with composer:

[](#to-install-with-composer)

1. If you haven't already, get [Composer](http://getcomposer.org/) and [install it](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx) - preferably, globally.
2. Require Fortress, either by running `php composer.phar require alexweissman/fortress`, or by creating a `composer.json` file:

```
{
    "require": {
        "php": ">=5.6.0",
        "userfrosting/fortress": "^4.2.0"
    }
}

```

and running `composer install`.

3. Include the `vendor/autoload.php` file in your project:

```
require dirname(__DIR__) . '/vendor/autoload.php';

```

Usage
-----

[](#usage)

### Request schema

[](#request-schema)

To read a YAML or JSON schema, use a `YamlFileLoader`:

```
$loader = new \UserFrosting\Support\Repository\Loader\YamlFileLoader('schema/forms/contact.yaml');

```

To use it, it must be read and loaded into a `RequestSchemaRepository` object:

```
$schema = new \UserFrosting\Fortress\RequestSchema\RequestSchemaRepository($loader->load());

```

You can add additional validation rules to a schema at runtime, if you wish:

```
$schema->addValidator("puppies", "required");

$schema->addValidator("minions", "range", [
    "min" => 0,
    "max" => 20,
    "message" => "Not enough minions"
]);

$schema->addValidator("email", "length", [
    "min" => 1,
    "max" => 100,
    "message" => "ACCOUNT_EMAIL_CHAR_LIMIT"
]);

```

### Data transformation

[](#data-transformation)

The data transformer performs the following tasks:

1. Whitelisting of input array against the schema. By default, any parameters not listed in the schema will be filtered out. Other options are "error" and "skip".
2. Perform a series of transformations on the input data. For example, `trim` or `purify`.
3. Set any default values for fields in the schema which are not present in the input array.

```
$post = [
    "puppies" => "I'm definitely really a puppy  0  ",
    "horses" => "seven pretty horses"
];

$transformer = new \UserFrosting\Fortress\RequestDataTransformer($schema);

// Transform, and print transformed data for demo purposes
$transformedData = $transformer->transform($post, "skip");

echo "Transformed data";
echo "";
print_r($transformedData);
echo "";

```

### Server-side data validation

[](#server-side-data-validation)

To process an array of user input, create a `ServerSideValidator` object with the schema and a translator object.

### Translator object

[](#translator-object)

Fortress requires a `Translator` (see [i18n](https://github.com/userfrosting/i18n)) object to translate message keys that may appear in rules:

```
$locale = new \UserFrosting\I18n\Locale('en_US');
$dictionary = new \UserFrosting\I18n\Dictionary($locale, $this->ci->locator);
$translator = new \UserFrosting\I18n\Translator($dictionary);

```

Then, call `validate` on the input array. `validate` will return false if any of the rules are failed. Call `errors` to get the list of generated error messages. You might want to store these error messages to a flash messaging system so they can be shown to the user.

```
$validator = new \UserFrosting\Fortress\ServerSideValidator($schema, $translator);

if (!$validator->validate($transformedData)) {
    echo "Validation results";
    echo "";
    print_r($validator->errors());
    echo "";
}

```

### Client-side data validation

[](#client-side-data-validation)

When generating a page or form, you will use one of the `Adapter` classes to generate a compatible set of rules from your WDVSS schema:

```
// Test client validators
$clientVal = new \UserFrosting\Fortress\Adapter\JqueryValidationAdapter($schema, $translator);
echo "Client-side validation schema (JSON)";
echo "";
print_r($clientVal->rules());
echo "";

```

### Add Namespace to the validation field names

[](#add-namespace-to-the-validation-field-names)

You can also add an array prefix to the field names to generate validation rules for the input schema that will wrap all the field names with the namespace of the form for which the validation rules are being generated.

```
// Test client validators
$clientVal = new \UserFrosting\Fortress\Adapter\JqueryValidationAdapter($schema, $translator);
echo "Client-side validation schema (JSON)";
echo "";
print_r($clientVal->rules('json',false,'mycoolform1'));
echo "";

```

This will generate validation rules with field names `mycoolform1[] : { .... }` instead of ` : { .... }`

This comes in handy when you are generating validation rules for multiple forms or form sections on the same page

### Message keys

[](#message-keys)

The `message` for a rule can be either a plain string, or a [translatable message key](https://github.com/userfrosting/i18n).

In the definitions of translatable message keys, the keyword "self" is reserved to refer to the name of the field being validated. Thus, a message like this:

"MIN\_LENGTH" =&gt; "The field '{{self}}' must be at least {{min}} characters long"

for a field defined as:

```
tagline:
  validators:
    length:
      min: 10
      message: MIN_LENGTH

```

Would translate to:

"The field 'tagline' must be at least 10 characters long"

### Limit rules to server or client only

[](#limit-rules-to-server-or-client-only)

Sometimes, you only want a validation rule to be applied server-side but not in Javascript on the client side, or vice versa. For example, there may be forms that contain hidden data that needs to be validated on the server-side, but is not directly manipulated by the user in the browser. Thus, these fields would not need client-side validation rules.

Alternatively, there might be fields that appear in the form that should be validated for the sake of user experience, but are not actually used by (or even sent to) the server.

To accomplish this, each validation rule can now accept a `domain` property. Setting to "server" will have it only applied server-side. Setting to "client" will have it only appear in the client-side rules. If not specified, rules will be applied both server- and client-side by default. You can also set this explicitly with the value "both".

[Style Guide](STYLE-GUIDE.md)
-----------------------------

[](#style-guide)

[Testing](RUNNING_TESTS.md)
---------------------------

[](#testing)

###  Health Score

36

—

LowBetter than 81% of packages

Maintenance11

Infrequent updates — may be unmaintained

Popularity36

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 54.9% 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 ~108 days

Recently: every ~167 days

Total

18

Last Release

1844d ago

Major Versions

0.666-alpha → 1.02016-03-29

1.0 → 2.02016-06-01

2.0 → 4.0.02017-02-18

PHP version history (3 changes)1.x-devPHP &gt;=5.4.0

4.0.1PHP &gt;=5.6.0

4.3.0PHP &gt;=7.1

### Community

Maintainers

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

---

Top Contributors

[![lcharette](https://avatars.githubusercontent.com/u/2566513?v=4)](https://github.com/lcharette "lcharette (62 commits)")[![alexweissman](https://avatars.githubusercontent.com/u/5004534?v=4)](https://github.com/alexweissman "alexweissman (47 commits)")[![phillmac](https://avatars.githubusercontent.com/u/4534835?v=4)](https://github.com/phillmac "phillmac (2 commits)")[![ssnukala](https://avatars.githubusercontent.com/u/5246509?v=4)](https://github.com/ssnukala "ssnukala (1 commits)")[![unplugged216](https://avatars.githubusercontent.com/u/15083445?v=4)](https://github.com/unplugged216 "unplugged216 (1 commits)")

---

Tags

userfrostinguserfrosting-componentvalidationtransformationuserfrostingwhitelisting

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/userfrosting-fortress/health.svg)

```
[![Health](https://phpackages.com/badges/userfrosting-fortress/health.svg)](https://phpackages.com/packages/userfrosting-fortress)
```

###  Alternatives

[composer/semver

Version comparison library that offers utilities, version constraint parsing and validation.

3.3k489.6M671](/packages/composer-semver)[giggsey/libphonenumber-for-php

A library for parsing, formatting, storing and validating international phone numbers, a PHP Port of Google's libphonenumber.

5.0k148.7M414](/packages/giggsey-libphonenumber-for-php)[respect/validation

The most awesome validation engine ever created for PHP

5.9k37.4M379](/packages/respect-validation)[propaganistas/laravel-phone

Adds phone number functionality to Laravel based on Google's libphonenumber API.

3.0k35.7M106](/packages/propaganistas-laravel-phone)[opis/json-schema

Json Schema Validator for PHP

64236.9M185](/packages/opis-json-schema)[giggsey/libphonenumber-for-php-lite

A lite version of giggsey/libphonenumber-for-php, which is a PHP Port of Google's libphonenumber

8412.9M47](/packages/giggsey-libphonenumber-for-php-lite)

PHPackages © 2026

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