platform/README.md

123 lines
3.3 KiB
Markdown
Raw Normal View History

2017-01-10 13:24:29 +00:00
# security
2019-04-20 14:55:47 +00:00
[![Pub](https://img.shields.io/pub/v/angel_security.svg)](https://pub.dartlang.org/packages/angel_security)
2017-01-12 23:57:13 +00:00
[![build status](https://travis-ci.org/angel-dart/security.svg)](https://travis-ci.org/angel-dart/security)
2017-01-13 03:11:55 +00:00
Angel middleware designed to enhance application security by patching common Web security
holes.
2017-01-12 23:57:13 +00:00
2017-01-14 00:45:35 +00:00
* Generic Middleware
* [Sanitizing HTML](#sanitizing-html)
* [CSRF Tokens](#csrf-tokens)
* [Banning by IP/Origin](#banning-by-ip)
* [Trusted Proxy](#trusted-proxy)
* [Throttling Requests](#throttling-requests)
* [Helmet Port](#helmet)
* [Service Hooks](#service-hooks)
2017-01-21 03:09:37 +00:00
* [Permissions](#permissions)
2017-01-14 00:45:35 +00:00
2017-01-12 23:57:13 +00:00
## Sanitizing HTML
```dart
app.before.add(sanitizeHtmlInput());
// Or:
app.chain(sanitizeHtmlInput()).get(...)
2017-01-13 03:11:55 +00:00
```
## CSRF Tokens
```dart
app.chain(verifyCsrfToken()).post('/form', ...);
app.responseFinalizers.add(setCsrfToken());
```
2017-01-14 00:45:35 +00:00
## Banning by IP
2017-01-13 03:11:55 +00:00
```dart
app.before.add(banIp('1.2.3.4'));
// Or a range:
app.before.add(banIp('1.2.3.*'));
app.before.add(banIp('1.2.*.4'));
// Or multiple filters:
2019-04-20 14:53:52 +00:00
app.before.add(banIp(['1.2.3.4', '192.*.*.*', RegExp(r'1\.2.\3.\4')]));
2017-01-14 00:45:35 +00:00
// Also can ban origins
app.before.add(banOrigin('*.known-attacker.com'));
// By default, `banOrigin` forces users to have an `Origin` header.
// Use this flag to disable it:
app.before.add(banOrigin('evil.site', allowEmptyOrigin: true));
```
## Trusted Proxy
Works well with Apache or Nginx.
```dart
// ONLY trust localhost X-Forwarded-* headers
app.before.add(trustProxy('127.0.0.1'));
```
## Throttling Requests
Throws a `429` error if the given rate limit is exceeded.
```dart
// Example: 5 requests per minute
2019-04-20 14:53:52 +00:00
app.before.add(throttleRequests(5, Duration(minutes: 1)));
2017-01-14 00:46:25 +00:00
```
2017-01-14 00:45:35 +00:00
# Helmet
2017-03-02 22:11:36 +00:00
[Supplementary security library](https://github.com/angel-dart/helmet)
2017-01-14 00:45:35 +00:00
# Service Hooks
2017-01-28 20:29:20 +00:00
Also included are a set of service hooks, some [ported from FeathersJS](https://github.com/feathersjs/feathers-legacy-authentication-hooks).
Others are created just for Angel.
2017-01-14 00:45:35 +00:00
```dart
2017-01-28 20:29:20 +00:00
import 'package:angel_security/hooks.dart' as hooks;
2017-01-21 03:09:37 +00:00
```
2017-01-28 20:29:20 +00:00
Included:
* `addUserToParams`
* `associateCurrentUser`,
* `hashPassword`
* `queryWithCurrentUser`
* `restrictToAuthenticated`
* `restrictToOwner`
* `variantPermission`
Also exported is the helper function `isServerSide`. Use this to determine
whether a service method is being called by the server, or by a client.
2017-01-21 03:09:37 +00:00
# Permissions
2017-01-28 20:29:20 +00:00
Permissions are a great way to restrict access to resources.
They take the form of:
* `service:foo`
* `service:create:*`
* `some:arbitrary:permission:*:with:*:a:wild:*card`
The specifics are up to you.
```dart
2019-04-20 14:53:52 +00:00
var permission = Permission('admin | users:find');
2017-01-28 20:29:20 +00:00
// Or:
// PermissionBuilders support + and | operators. Operands can be Strings, Permissions or PermissionBuilders.
2019-04-20 14:53:52 +00:00
var permission = (PermissionBuilder('admin') | (PermissionBuilder('users') + 'find')).toPermission();
2017-01-28 20:29:20 +00:00
// Transform into middleware
app.chain(permission.toMiddleware()).get('/protected', ...);
// Or as a service hook
app.service('protected').beforeModify(permission.toHook());
// Dynamically create a permission hook.
// This helps in situations where the resources you need to protect are dynamic.
//
// `variantPermission` is included in the `package:angel_security/hooks.dart` library.
app.service('posts').beforeModify(variantPermission((e) {
2019-04-20 14:53:52 +00:00
return PermissionBuilder('posts:modify:${e.id}');
2017-01-28 20:29:20 +00:00
}));
```