This commit is contained in:
thosakwe 2017-03-28 22:14:47 -04:00
parent cb5c61dc14
commit fc6bfcb6de
6 changed files with 17 additions and 13 deletions

View file

@ -1,5 +1,5 @@
# security # security
[![version 1.0.0](https://img.shields.io/badge/pub-v1.0.0-brightgreen.svg)](https://pub.dartlang.org/packages/angel_security) [![version 1.0.1](https://img.shields.io/badge/pub-v1.0.1-brightgreen.svg)](https://pub.dartlang.org/packages/angel_security)
[![build status](https://travis-ci.org/angel-dart/security.svg)](https://travis-ci.org/angel-dart/security) [![build status](https://travis-ci.org/angel-dart/security.svg)](https://travis-ci.org/angel-dart/security)
Angel middleware designed to enhance application security by patching common Web security Angel middleware designed to enhance application security by patching common Web security

View file

@ -12,9 +12,9 @@ RequestMiddleware verifyCsrfToken(
return (RequestContext req, res) async { return (RequestContext req, res) async {
String csrfToken; String csrfToken;
if (allowQuery && req.query.containsKey(name)) if (allowQuery && (await req.lazyQuery()).containsKey(name))
csrfToken = req.query[name]; csrfToken = req.query[name];
else if (req.body.containsKey(name)) else if ((await req.lazyBody()).containsKey(name))
csrfToken = req.body[name]; csrfToken = req.body[name];
else if (allowCookie) { else if (allowCookie) {
var cookie = var cookie =

View file

@ -10,6 +10,8 @@ final Map<Pattern, String> DEFAULT_SANITIZERS = {
/// Mitigates XSS risk by sanitizing user HTML input. /// Mitigates XSS risk by sanitizing user HTML input.
/// ///
/// You can also provide a Map of patterns to [replace]. /// You can also provide a Map of patterns to [replace].
///
/// You can sanitize the [body] or [query] (both `true` by default).
RequestMiddleware sanitizeHtmlInput( RequestMiddleware sanitizeHtmlInput(
{bool body: true, {bool body: true,
bool query: true, bool query: true,
@ -17,8 +19,8 @@ RequestMiddleware sanitizeHtmlInput(
var sanitizers = {}..addAll(DEFAULT_SANITIZERS)..addAll(replace ?? {}); var sanitizers = {}..addAll(DEFAULT_SANITIZERS)..addAll(replace ?? {});
return (RequestContext req, res) async { return (RequestContext req, res) async {
if (body) _sanitizeMap(req.body, sanitizers); if (body) _sanitizeMap(await req.lazyBody(), sanitizers);
if (query) _sanitizeMap(req.query, sanitizers); if (query) _sanitizeMap(await req.lazyQuery(), sanitizers);
return true; return true;
}; };
} }

View file

@ -1,5 +1,5 @@
name: angel_security name: angel_security
version: 1.0.0 version: 1.0.1
description: Angel middleware designed to enhance application security by patching common Web security holes. description: Angel middleware designed to enhance application security by patching common Web security holes.
author: Tobe O <thosakwe@gmail.com> author: Tobe O <thosakwe@gmail.com>
environment: environment:

View file

@ -11,6 +11,7 @@ main() {
setUp(() async { setUp(() async {
app = new Angel() app = new Angel()
..lazyParseBodies = true
..before.add((RequestContext req, res) async { ..before.add((RequestContext req, res) async {
var xUser = req.headers.value('X-User'); var xUser = req.headers.value('X-User');
if (xUser != null) if (xUser != null)
@ -65,7 +66,8 @@ main() {
var response = await client var response = await client
.post('/artists', headers: {'X-User': 'John'}, body: {'foo': 'bar'}); .post('/artists', headers: {'X-User': 'John'}, body: {'foo': 'bar'});
print('Response: ${response.body}'); print('Response: ${response.body}');
expect(response, allOf(hasStatus(200), isJson({'foo': 'bar'}))); print('Status: ${response.statusCode}');
expect(response, allOf(hasStatus(201), isJson({'foo': 'bar'})));
}); });
}); });

View file

@ -27,35 +27,35 @@ main() {
// First request within the hour is fine // First request within the hour is fine
var response = await client.get('/once-per-hour'); var response = await client.get('/once-per-hour');
print(response.body); print(response.body);
expect(response.body, contains('OK')); expect(response, hasBody('OK'));
// Second request within an hour? No no no! // Second request within an hour? No no no!
response = await client.get('/once-per-hour'); response = await client.get('/once-per-hour');
print(response.body); print(response.body);
expect(response, hasStatus(429)); expect(response, isAngelHttpException(statusCode: 429));
}); });
test('thrice per minute', () async { test('thrice per minute', () async {
// First request within the minute is fine // First request within the minute is fine
var response = await client.get('/thrice-per-minute'); var response = await client.get('/thrice-per-minute');
print(response.body); print(response.body);
expect(response.body, contains('OK')); expect(response, hasBody('OK'));
// Second request within the minute is fine // Second request within the minute is fine
response = await client.get('/thrice-per-minute'); response = await client.get('/thrice-per-minute');
print(response.body); print(response.body);
expect(response.body, contains('OK')); expect(response.body, hasBody('OK'));
// Third request within the minute is fine // Third request within the minute is fine
response = await client.get('/thrice-per-minute'); response = await client.get('/thrice-per-minute');
print(response.body); print(response.body);
expect(response.body, contains('OK')); expect(response, hasBody('OK'));
// Fourth request within a minute? No no no! // Fourth request within a minute? No no no!
response = await client.get('/thrice-per-minute'); response = await client.get('/thrice-per-minute');
print(response.body); print(response.body);
expect(response, hasStatus(429)); expect(response, isAngelHttpException(statusCode: 429));
}); });
} }