Socket
Socket
Sign inDemoInstall

toxy

Package Overview
Dependencies
30
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.0 to 0.3.1

6

lib/admin/middleware/reply.js

@@ -5,9 +5,5 @@ module.exports = function reply(req, res, next) {

res.setHeader('Content-Type', 'application/json')
res.end(toJSON(data))
res.end(JSON.stringify(data))
}
next()
}
function toJSON(data) {
return JSON.stringify(data)
}

4

lib/base.js

@@ -38,3 +38,3 @@ module.exports = Base

if (item) {
return item.$of || item
return item.$of || item
}

@@ -49,3 +49,3 @@ return null

if (node.$name === name || node.$of === name
|| node.name === name || node === name) {
|| node.name === name || node === name) {
return node

@@ -52,0 +52,0 @@ }

module.exports = function responseStatus(opts) {
opts = opts || {}
if (Array.isArray(opts)) {
if (typeof opts === 'number') {
opts = { value: opts }
}
else if (Array.isArray(opts)) {
opts = { range: opts }
}
opts = opts || {}
var lower = +opts.lower
var higher = +opts.higher
var range = opts.range || [200, 400]
var value = +opts.value
var range = opts.range || [200, 300]

@@ -16,2 +20,6 @@ return function responseStatus(req, res, next) {

if (value) {
return next(null, !(status === value))
}
if (lower) {

@@ -18,0 +26,0 @@ return next(null, !(status < lower))

{
"name": "toxy",
"version": "0.3.0",
"version": "0.3.1",
"description": "Hackable HTTP proxy to simulate server failure scenarios and unexpected network conditions",

@@ -5,0 +5,0 @@ "repository": "h2non/toxy",

@@ -7,3 +7,3 @@ # toxy [![Build Status](https://api.travis-ci.org/h2non/toxy.svg?branch=master&style=flat)](https://travis-ci.org/h2non/toxy) [![Code Climate](https://codeclimate.com/github/h2non/toxy/badges/gpa.svg)](https://codeclimate.com/github/h2non/toxy) [![NPM](https://img.shields.io/npm/v/toxy.svg)](https://www.npmjs.org/package/toxy)

It was mainly designed for fuzzing/evil testing purposes, when toxy becomes particularly useful to cover fault tolerance and resiliency capabilities of a system, especially in [service-oriented](http://microservices.io/patterns/index.html) architectures, where toxy may act as intermediate proxy among services.
It was mainly designed for fuzzing/evil testing purposes, when toxy becomes particularly useful to cover fault tolerance and resiliency capabilities of a system, especially [disruption-tolerant networks](https://en.wikipedia.org/wiki/Delay-tolerant_networking) and [service-oriented](http://microservices.io/patterns/index.html) architectures, where toxy may act as intermediate proxy among services.

@@ -14,3 +14,3 @@ toxy allows you to plug in [poisons](#poisons), optionally filtered by [rules](#rules), which essentially can intercept and alter the HTTP flow as you need, performing multiple evil actions in the middle of that process, such as limiting the bandwidth, delaying TCP packets, injecting network jitter latency or replying with a custom error or status code.

toxy can be fluently used [programmatically](#programmatic-api) or via [HTTP API](#http-api).
It's compatible with [connect](https://github.com/senchalabs/connect)/[express](http://expressjs.com), and it was built on top of [rocky](https://github.com/h2non/rocky), a full-featured middleware-oriented HTTP proxy.
It was built on top of [rocky](https://github.com/h2non/rocky), a full-featured middleware-oriented HTTP proxy, and it's [pluggable](https://github.com/h2non/toxy/blob/master/examples/express.js) in [connect](https://github.com/senchalabs/connect)/[express](http://expressjs.com) as standard middleware.

@@ -48,8 +48,8 @@ Requires node.js +0.12 or io.js +1.6

- [Method](#method)
- [Content Type](#content-type)
- [Headers](#headers)
- [Response headers](#response-headers)
- [Content Type](#content-type)
- [Response status](#response-status)
- [Body](#body)
- [Response body](#response-body)
- [Response status](#response-status)
- [How to write rules](#how-to-write-rules)

@@ -70,6 +70,6 @@ - [Programmatic API](#programmatic-api)

- Featured built-in router with nested configuration
- Hierarchical and composable poisioning with rule based filtering
- Hierarchical and composable poisoning with rule based filtering
- Hierarchical middleware layer (both global and route scopes)
- Easily augmentable via middleware (based on connect/express middleware)
- Supports both incoming and outgoing traffic poisioning
- Supports both incoming and outgoing traffic poisoning
- Built-in poisons (bandwidth, error, abort, latency, slow read...)

@@ -87,16 +87,18 @@ - Rule-based poisoning (probabilistic, HTTP method, headers, body...)

There're some other similar solutions like `toxy` in the market, but most of them do not provide a proper programmatic control and usually are not easy to hack, configure and/or extend. Additionally, most of the those solutions only operate at TCP L3 level stack instead of providing high-level abstraction to cover common requirements in the specific domain and nature of the HTTP L7 protocol, like toxy does.
There're some other similar solutions like `toxy` in the market, but most of them do not provide a proper programmatic control and usually are not easy to hack, configure and/or directly closed to extensibility.
Additionally, most of the those solutions only operates at TCP L3 level stack instead of providing high-level abstractions to cover common requirements in the specific domain and nature of the HTTP L7 protocol, like toxy try to provide.
toxy provides a powerful hackable and extensible solution with a convenient abstraction, but without losing a convenient low-level interface capabilities to deal with HTTP protocol primitives properly.
toxy brings a powerful hackable and extensible solution with a convenient abstraction, but without losing a proper low-level interface capabilities to deal with HTTP protocol primitives easily.
toxy was designed based on the rules of composition, simplicity and extensibility.
Via its middleware layer you can easily augment toxy features to your own needs.
Via its built-in hierarchical domain specific middleware layer you can easily augment toxy features to your own needs.
### Concepts
`toxy` introduces two core directives that you can plug in the proxy and should knowing before using: poisons and rules.
`toxy` introduces two directives: poisons and rules.
**Poisons** are the specific logic to infect an incoming or outgoing HTTP flow (e.g: injecting a latency, replying with an error). HTTP flow can be poisoned by one or multiple poisons, and poisons can be plugged to infect both global or route level traffic, and in both incoming and outgoing traffic flows.
**Poisons** are the specific logic which infects an incoming or outgoing HTTP transaction (e.g: injecting a latency, replying with an error). One HTTP transaction can be poisoned by one or multiple poisons, and those poisons can be also configured to infect both global or route level traffic.
**Rules** are a kind of validation filters that can be reused and applied to global incoming HTTP traffic, route level traffic or into a specific poison. Their responsability is to determine, via inspecting each incoming HTTP request, if the registered poisons should be enabled or not, and therefore infecting or not the HTTP traffic (e.g: match headers, query params, method, body...).
**Rules** are a kind of match validation filters that inspects an HTTP request/response in order to determine, given a certain rules, if the HTTP transaction should be poisioned or not (e.g: if headers matches, query params, method, body...).
Rules can be reused and applied to both incoming and outgoing traffic flows, including different scopes: global, route or poison level.

@@ -108,7 +110,7 @@ ### How it works

↓ ||| ↓
↓ --------------- ↓
↓ +-------------+ ↓
↓ | Toxy Router | ↓ -> Match the incoming request
↓ --------------- ↓
↓ +-------------+ ↓
↓ ||| ↓
↓ |--------------------| ↓
↓ +--------------------+ ↓
↓ | Incoming phase | ↓

@@ -123,11 +125,11 @@ ↓ |~~~~~~~~~~~~~~~~~~~~| ↓

↓ | ---------------- | ↓
↓ |~~~~~~~~~~~~~~~~~~~~| ↓
↓ +~~~~~~~~~~~~~~~~~~~~+ ↓
↓ / \ ↓
↓ \ / ↓
↓ /--------------------\ ↓
↓ +--------------------+ ↓
↓ | HTTP dispatcher | ↓ -> Forward the HTTP traffic to the target server, either poisoned or not
↓ \--------------------/ ↓
↓ +--------------------+ ↓
↓ / \ ↓
↓ \ / ↓
↓ |--------------------| ↓
↓ +--------------------+ ↓
↓ | Outgoing phase | ↓ -> Receives response from target server

@@ -142,3 +144,3 @@ ↓ |~~~~~~~~~~~~~~~~~~~~| ↓

↓ | ---------------- | ↓
↓ |~~~~~~~~~~~~~~~~~~~~| ↓
↓ +~~~~~~~~~~~~~~~~~~~~+ ↓
↓ ||| ↓

@@ -214,3 +216,3 @@ ↓ ( Send to the client ) ↓ -> Finally, send the request to the client, either poisoned or not

Poisons host specific logic which intercepts and mutates, wraps, modify and/or cancel an HTTP transaction in the proxy server.
Poisons can be applied to incoming or outgoing, or even both traffic flows (see [poison phases](#poisioning-phases)).
Poisons can be applied to incoming or outgoing, or even both traffic flows (see [poison phases](#poisoning-phases)).

@@ -222,6 +224,10 @@ Poisons can be composed and reused for different HTTP scenarios.

`toxy` has a hierarchical design. There're two different scopes: `global` and `route`.
`toxy` has a hierarchical design based on two different scopes: `global` and `route`.
Poisons can be plugged to both scopes, meaning you can limit the scope of the poisioning,
for instance, you might wanna apply a bandwidth limit poisioning only to
**Global** scope points to all the incoming HTTP traffic received by the proxy server, regardless of the HTTP method or path.
**Route** scope points to any incoming traffic which matches with a specific HTTP verb and URI path.
Poisons can be plugged to both scopes, meaning you can operate with better accuracy and restrict the scope of the poisoning,
for instance, you might wanna apply a bandwidth limit poisoning only to
a certain routes, such as `/download` or `/images`.

@@ -233,16 +239,16 @@

Poisoning can be done to incoming or outgoing traffic flows, or even both.
Poisons can be plugged to incoming or outgoing traffic flows, or even both.
**Incoming** poisoning is applied when the traffic is still receiving by proxy
and it has not been forwarded to the target server yet.
**Incoming** poisoning is applied when the traffic has been received by proxy
but it has not been forwarded to the target server yet.
**Outgoing** poisoning is applied when the traffic has been forwarded to the target server and
the proxy recieves the response from it, but that response has not been send to the client yet.
**Outgoing** poisoning refers to the traffic that has been forwarded to the target server and
when proxy recieves the response from it, but that response has not been sent to the client yet.
This is, essentially, that you can plug in your poisons to infect the HTTP traffic
before or after the request is forwarded to the target HTTP server.
This means, essentially, that you can plug in your poisons to infect the HTTP traffic
before or after the request is forwarded to the target HTTP server or sent to the client.
This allows you apply a better and more accurated poisoning based on the server response.
This allows you apply a better and more accurated poisoning based on the request or server response.
For instance, given the nature of some poisons, like `inject error`,
you may require to enable it according to the target server response.
you may want to enable it according to the target server response (e.g: some header is present or not).

@@ -260,3 +266,3 @@ See [poison-phases.js](https://github.com/h2non/toxy/blob/master/examples/poison-phases.js) for a featured example.

<tr>
<td><b>Poisioning Phase</b></td><td>incoming / outgoing</td>
<td><b>Poisoning Phase</b></td><td>incoming / outgoing</td>
</tr>

@@ -290,3 +296,3 @@ <tr>

<tr>
<td><b>Poisioning Phase</b></td><td>incoming / outgoing</td>
<td><b>Poisoning Phase</b></td><td>incoming / outgoing</td>
</tr>

@@ -324,3 +330,3 @@ <tr>

<tr>
<td><b>Poisioning Phase</b></td><td>incoming / outgoing</td>
<td><b>Poisoning Phase</b></td><td>incoming / outgoing</td>
</tr>

@@ -353,3 +359,3 @@ <tr>

<tr>
<td><b>Poisioning Phase</b></td><td>incoming / outgoing</td>
<td><b>Poisoning Phase</b></td><td>incoming / outgoing</td>
</tr>

@@ -385,3 +391,3 @@ <tr>

<tr>
<td><b>Poisioning Phase</b></td><td>incoming</td>
<td><b>Poisoning Phase</b></td><td>incoming</td>
</tr>

@@ -413,3 +419,3 @@ <tr>

<tr>
<td><b>Poisioning Phase</b></td><td>incoming</td>
<td><b>Poisoning Phase</b></td><td>incoming</td>
</tr>

@@ -439,3 +445,3 @@ <tr>

<tr>
<td><b>Poisioning Phase</b></td><td>incoming / outgoing</td>
<td><b>Poisoning Phase</b></td><td>incoming / outgoing</td>
</tr>

@@ -465,3 +471,3 @@ <tr>

<tr>
<td><b>Poisioning Phase</b></td><td>incoming / outgoing</td>
<td><b>Poisoning Phase</b></td><td>incoming / outgoing</td>
</tr>

@@ -492,3 +498,3 @@ <tr>

<tr>
<td><b>Poisioning Phase</b></td><td>incoming / outgoing</td>
<td><b>Poisoning Phase</b></td><td>incoming / outgoing</td>
</tr>

@@ -518,3 +524,3 @@ <tr>

<tr>
<td><b>Poisioning Phase</b></td><td>incoming / outgoing</td>
<td><b>Poisoning Phase</b></td><td>incoming / outgoing</td>
</tr>

@@ -587,6 +593,6 @@ <tr>

Rules are simple validation filters which inspect an HTTP request and determine, given a certain rules (e.g: method, headers, query params), if the HTTP transaction should be poisoned or not.
Rules are simple validation filters which inspects an incoming or outgoing HTTP traffic in order to determine, given a certain rules (e.g: matches the method, headers, query params, body...), if the current HTTP transaction should be poisoned or not, based on the resolution value of the rule.
Rules are useful to compose, decouple and reuse logic among different scenarios of poisoning.
Rules can be applied to the global, route or even poison scope.
Rules can be applied to global, route or even poison scope, and it also applies to both [phases of poisoning](#poisoning-phases).

@@ -599,4 +605,13 @@ Rules are executed in FIFO order. Their evaluation logic is equivalent to `Array#every()` in JavaScript: all the rules must pass in order to proceed with the poisoning.

Enables the rule by a random probabilistic. Useful for random poisioning.
<table>
<tr>
<td><b>Name</b></td><td>probability</td>
</tr>
<tr>
<td><b>Poison Phase</b></td><td>incoming / outgoing</td>
</tr>
</table>
Enables the rule by a random probabilistic. Useful for random poisoning.
**Arguments**:

@@ -613,2 +628,11 @@

<table>
<tr>
<td><b>Name</b></td><td>method</td>
</tr>
<tr>
<td><b>Poison Phase</b></td><td>incoming / outgoing</td>
</tr>
</table>
Filters by HTTP method.

@@ -625,4 +649,26 @@

#### Content Type
Filters by content type header. It should be present
**Arguments**:
- **value** `string|regexp` - Header value to match.
```js
var rule = toxy.rules.contentType('application/json')
toxy.rule(rule)
```
#### Headers
<table>
<tr>
<td><b>Name</b></td><td>headers</td>
</tr>
<tr>
<td><b>Poison Phase</b></td><td>incoming / outgoing</td>
</tr>
</table>
Filter by request headers.

@@ -649,2 +695,11 @@

<table>
<tr>
<td><b>Name</b></td><td>responseHeaders</td>
</tr>
<tr>
<td><b>Poison Phase</b></td><td>outgoing</td>
</tr>
</table>
Filter by response headers from target server. Same as `headers` rule, but evaluating the outgoing request.

@@ -654,3 +709,3 @@

- **headers** `object` - Headers to match by key-value pair. `value` can be a string, regexp, `boolean` or `function(headerValue, headerName) => boolean`
- **headers** `object` - Headers to match by key-value pair. `value` can be a `string`, `regexp`, `boolean` or `function(headerValue, headerName) => boolean`

@@ -670,35 +725,16 @@ ```js

#### Content Type
#### Body
Filters by content type header. It should be present
<table>
<tr>
<td><b>Name</b></td><td>body</td>
</tr>
<tr>
<td><b>Poison Phase</b></td><td>incoming / outgoing</td>
</tr>
</table>
**Arguments**:
- **value** `string|regexp` - Header value to match.
```js
var rule = toxy.rules.contentType('application/json')
toxy.rule(rule)
```
#### Response status
Evaluates the response status from the target server.
Only applicable to outgoing poisons.
**Arguments**:
- **range** `array` - Pair of status code range. Default to `[200, 400]`.
- **value** `string|regexp` - Header value to match.
```js
var rule = toxy.rules.contentType('application/json')
toxy.rule(rule)
```
#### Body
Match incoming body payload by a given `string`, `regexp` or custom filter `function`.
This rule is pretty simple, so for complex body matching (e.g: validating againts a JSON schema)
This rule is pretty simple, so for complex body matching (e.g: validating against a JSON schema)
you should probably write your own rule.

@@ -726,2 +762,11 @@

<table>
<tr>
<td><b>Name</b></td><td>responseBody</td>
</tr>
<tr>
<td><b>Poison Phase</b></td><td>outgoing</td>
</tr>
</table>
Match outgoing body payload by a given `string`, `regexp` or custom filter `function`.

@@ -746,2 +791,28 @@

#### Response status
<table>
<tr>
<td><b>Name</b></td><td>responseStatus</td>
</tr>
<tr>
<td><b>Poison Phase</b></td><td>outgoing</td>
</tr>
</table>
Evaluates the response status from the target server.
Only applicable to outgoing poisons.
**Arguments**:
- **range** `array` - Pair of status code range to match. Default `[200, 300]`.
- **lower** `number` - Compare status as `lower than` operation. Default to `null`.
- **higher** `number` - Compare status as `higher than` operation. Default to `null`.
- **value** `number` - Status code to match using a strict equality comparison. Default `null`.
```js
var rule = toxy.rules.contentType('application/json')
toxy.rule(rule)
```
### How to write rules

@@ -752,3 +823,3 @@

Your rule must resolve with a `boolean` param calling the `next(err,
shouldIgnore)` function in the middleware, passing a `true` value if the rule has not matches and should not apply the poisioning, and therefore continuing with the next middleware stack.
shouldIgnore)` function in the middleware, passing a `true` value if the rule has not matches and should not apply the poisoning, and therefore continuing with the next middleware stack.

@@ -934,5 +1005,5 @@ Here's an example of a simple rule matching the HTTP method to determine if:

#### toxy#poison(poison)
Alias: `usePoison`
Alias: `usePoison`, `useIncomingPoison`
Register a new poison to be applied to [incoming](#poisioning-phases) traffic.
Register a new poison to infect [incoming](#poisoning-phases) traffic.

@@ -942,3 +1013,3 @@ #### toxy#outgoingPoison(poison)

Register a new poison to be applied to [outgoing](#poisioning-phases) traffic.
Register a new poison to infect [outgoing](#poisoning-phases) traffic.

@@ -945,0 +1016,0 @@ #### toxy#rule(rule)

@@ -19,2 +19,9 @@ const expect = require('chai').expect

test('value', function () {
assert(204, 204, equals(false))
assert(400, 400, equals(false))
assert(300, 500, equals(true))
assert(-1, 200, equals(true))
})
test('lower', function () {

@@ -21,0 +28,0 @@ assert({ lower: 300 }, 204, equals(false))

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc