Verified Commit 21c8d112 authored by Aral Balkan's avatar Aral Balkan
Browse files

Prepare 1.1.3 release

parent 793486a0
......@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.1.3] - 2020-10-28
### Improved
Query security updates:
- Fail faster on disallowed character detection.
- Fail at function creation instead of code execution on syntax error by using function constructor instead of eval.
- Add square brackets to disallowed characters. As far as I can see, [esoteric](http://www.businessinfo.co.uk/labs/talk/Nonalpha.pdf) [approaches](http://slides.com/sylvainpv/xchars-js/) to writing non-alphanumeric JavaScript were already being thwarted by disallowing the plus sign, semicolon, etc., but there’s no harm in removing these also as subscript syntax is powerful in JavaScript.
- Add a few more tests.
## [1.1.2] - 2020-10-23
### Improved
......
......@@ -266,6 +266,7 @@ class QuerySanitiser {
if (Disallowed.dangerousCharacters.test(queryString)) {
// Disallowed character(s) found, reject.
// log(' 💾 ❨JSDB❩ Warning: disallowed character(s) found in query string; rejecting.', queryString)
return []
}
......@@ -294,8 +295,7 @@ class QuerySanitiser {
query = new Function('valueOf', finalQueryString)
} catch (error) {
// Syntax error in query string, reject.
// (This should not happen.)
log('Warning: syntax error in query string. This could be an attack.', error)
// log(' 💾 ❨JSDB❩ Warning: syntax error in query string; rejecting.', queryString, error)
return []
}
......@@ -303,10 +303,10 @@ class QuerySanitiser {
result = data.filter(function(value) {
try {
return query(value)
} catch (error) {
// Something went wrong while executing the query.
// (This should not happen.)
log('Warning: query function threw unexpected error. This could be an attack.', error)
} catch (error) /* istanbul ignore next */ {
// Unexpected error: something went wrong while executing the query.
// (This should not happen as all errors should have been caught before this point.)
log(' 💾 ❨JSDB❩ Warning: query function threw unexpected error; rejecting.', queryString, error)
return false
}
})
......
{
"name": "@small-tech/jsdb",
"version": "1.1.2",
"version": "1.1.3",
"description": "A transparent, in-memory, streaming write-on-update JavaScript database for Small Web applications that persists to a JavaScript transaction log.",
"keywords": [
"js",
......
......@@ -700,6 +700,9 @@ test('Basic queries', t => {
const queryInjectionAttackAttemptResult5 = db.cars.whereIsTrue('valueOf.make === `2`; globalThis.t.fail("Query injection payload 5 delivered"); valueOf.make === \'something\'').get()
// This should trigger a syntax error at function creation.
const queryInjectionAttackAttemptResult6 = db.cars.whereIsTrue('valueOf.make === 1.2.3').get()
// Remove the global reference to the test instance as it’s no longer necessary.
globalThis.t = null
......@@ -708,6 +711,7 @@ test('Basic queries', t => {
t.ok(Array.isArray(queryInjectionAttackAttemptResult3) && queryInjectionAttackAttemptResult3.length === 0, '🔒 result of query injection attack attempt 3 is empty array as expected')
t.ok(Array.isArray(queryInjectionAttackAttemptResult4) && queryInjectionAttackAttemptResult4.length === 0, '🔒 result of query injection attack attempt 4 is empty array as expected')
t.ok(Array.isArray(queryInjectionAttackAttemptResult5) && queryInjectionAttackAttemptResult5.length === 0, '🔒 result of query injection attack attempt 5 is empty array as expected')
t.ok(Array.isArray(queryInjectionAttackAttemptResult6) && queryInjectionAttackAttemptResult6.length === 0, '🔒 result of query injection attack attempt 6 is empty array as expected')
t.end()
})
......@@ -737,7 +741,7 @@ test('Time', t => {
t.strictEquals(typeof globalTime5, 'string', 'positive number as argument to elapsed method returns string')
t.strictEquals(typeof globalTime6, 'string', 'default behaviour of elapsed method is to return string')
t.ok(labelTime2 < labelTime3, 'label1 durations are in expected order')
t.ok(labelTime1 < globalTime1, 'label1 and global start times are in expected order')
t.ok(labelTime3 > globalTime7, 'global and label1 durations are in expected order')
t.end()
......@@ -868,6 +872,8 @@ test('JSDF', t => {
testSerialisation(t, '🔒 String injection attempt 1 fails as expected', "${t.fail('Payload 1 delivered')}")
testSerialisation(t, '🔒 String injection attempt 2 fails as expected', "\\${t.fail('Payload 2 delivered')}")
testSerialisation(t, '🔒 String injection attempt 3 fails as expected', "` + t.fail('Payload 3 delivered') + `")
testSerialisation(t, '🔒 String injection attempt 3 fails as expected', "' + t.fail('Payload 4 delivered') + '")
testSerialisation(t, '🔒 String injection attempt 3 fails as expected', "\" + t.fail('Payload 5 delivered') + \"")
//
// Plain objects.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment