Skip to main content

Input validation framework for Python

Project description

Stoplight [![Build Status](https://api.travis-ci.org/painterjd/stoplight.png)](https://travis-ci.org/painterjd/stoplight)
=========

Stoplight -- An Input Validation Framework for Python

Why Validate User Input?
------------------------
Input validation is the most basic, first step to adding security to any application that accepts untrusted user input. Volumes have been written on the subject, but the gist is to reduce the attack surface of your application by sanitizing all user input so that it meets a very tight set of criteria needed just for the application, and nothing more. The most common type of attack prevented by input validation is [Code Injection](http://en.wikipedia.org/wiki/Code_injection).

A great number of user input vulnerabilities (i.e. [Shellshock](http://en.wikipedia.org/wiki/Shellshock_%28software_bug%29)) could be avoided almost entirely if user input were sanitized.

Example
-------
Let's say that our application is accepting a US Phone Number only. In that case, our application should only need to accept NNN-NNN-NNNN where N is a digit from 0-9. If the user passes anything else, we can throw it away.

The problem that stoplight aims to address is the intermixing of input validation logic with application logic (in particular with RESTful/REST-like API frameworks). Sometimes they are inseparable, but in almost all cases, they are not. So let's look at the above-mentioned phone number example.

Almost all of today's API frameworks work in a similar manner -- you declare a function that defines an endpoint and the framework calls the function when an HTTP request comes in from a client.

```python
def post(self, account_id, phone_number):
if not is_valid_account_id(account_id):
handle_bad_account_id()

if not is_valid_phone_number(phone_number):
handle_bad_phone_number()

model.set_phone_number(account_id, phone_number)
```

This is a simple, contrived example. Typically things start getting much more complex. For certain HTTP verbs, a user will want different responses returned. There may be other things to accomplish as well.

In Stoplight, we would validate the input like so:

```python
@validate(account_id=AccountIdRule, phone_number=PhoneNumberRule)
def post(self, account_id, phone_number):
model.set_phone_number(account_id, phone_number)
```

This allows us to effectively separate our "input validation" logic from "business logic".

Rules are fairly simple to create. For example, here is how one might declare the PhoneNumberRule

```python
PhoneNumberRule = Rule(is_validate_phone_number(), lambda: abort(404))
```

And of course, that leads us to is_valid_phone_number() declaration.

```python
@validation_function
def is_valid_phone_number(candidate):
if (phone_regex.match(candidate) is None):
msg = 'Not a valid phone number: {0}'
msg = msg.format(candidate)
raise ValidationFailed(msg)
```

This allows us to separate validation from transports (imagine an API where you must support HTTP and ZMQ, for example). It also allows us to centralize validation logic and write separate tests for the validation rules.

Other Features:
---------------
* Ensures that all parameters (positional and keyword) are all validated. If they are not validated, a ValidationProgrammingError is raised.
* Allows validation of globally-scoped values (think items in thread local storage, as is done in the Pecan framework)

Caveats (TODO):
---------------
* Overhead. Such is the nature of Python with decorators.

Documentation:
--------------
The project is being documented at readthedocs [here](http://stoplight.readthedocs.org/en/latest/). For other examples, please see the unit tests.


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

stoplight-1.4.1-py2-none-any.whl (15.7 kB view details)

Uploaded Python 2

File details

Details for the file stoplight-1.4.1-py2-none-any.whl.

File metadata

  • Download URL: stoplight-1.4.1-py2-none-any.whl
  • Upload date:
  • Size: 15.7 kB
  • Tags: Python 2
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.9.1 pkginfo/1.4.1 requests/2.18.4 setuptools/38.2.4 requests-toolbelt/0.8.0 tqdm/4.19.5 CPython/2.7.14

File hashes

Hashes for stoplight-1.4.1-py2-none-any.whl
Algorithm Hash digest
SHA256 51797962ad4223baac78f0ce762954c9a09e29529285ee82633ce36e5875f7ae
MD5 16801b3e60591109dd2cd0adc7e832a7
BLAKE2b-256 0c346480bafa08c519fb767b51ddf55f095d1ee5771e877cdebb508390627f64

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page