@snaplet/copycat
Advanced tools
Comparing version 0.4.0 to 0.5.0
@@ -25,2 +25,9 @@ var __defProp = Object.defineProperty; | ||
const codeOf = (x) => x.charCodeAt(0); | ||
const safeSpecialChars = "-_+".split("").map(codeOf); | ||
const safeAscii = import_fictional.char.inRanges([ | ||
import_fictional.char.lower, | ||
import_fictional.char.upper, | ||
import_fictional.char.digit, | ||
...safeSpecialChars.map((code) => [code, code]) | ||
]); | ||
const CHAR_RANGES_TO_MAKERS = [ | ||
@@ -30,3 +37,3 @@ [[codeOf("a"), codeOf("z")], import_fictional.char.lower], | ||
[[codeOf("0"), codeOf("9")], import_fictional.char.digit], | ||
[[32, 126], import_fictional.char.ascii] | ||
[[32, 126], safeAscii] | ||
]; | ||
@@ -33,0 +40,0 @@ const FALLBACK_MAKER = import_fictional.char.inRanges([import_fictional.char.ascii, import_fictional.char.latin1]); |
var import__ = require("."); | ||
test("scrambling", () => { | ||
expect(import__.copycat.scramble("the DOG ate the cheese!")).toMatchInlineSnapshot(`"xeh ABC agf mom usckyc'"`); | ||
expect(import__.copycat.scramble("the DOG ate the cheese!")).toMatchInlineSnapshot(`"xeh ABC agf mom usckycP"`); | ||
expect(import__.copycat.scramble("99 red balloons")).toMatchInlineSnapshot(`"53 byt idcouxvu"`); | ||
@@ -9,1 +9,4 @@ }); | ||
}); | ||
test("special chars", () => { | ||
expect(import__.copycat.scramble("foo-bar_baz+quux@corge.org", { preserve: ["@", "."] })).toMatchInlineSnapshot(`"wcirsqgecrsSpmwy@evkbl.gzn"`); | ||
}); |
{ | ||
"name": "@snaplet/copycat", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -71,3 +71,49 @@ # ![copycat](https://user-images.githubusercontent.com/1731223/167850970-584e6953-6543-4085-af5a-f9d8b7ffe988.png) | ||
## Working with PII (Personal Identifiable Information) | ||
If you're using sensitive information as input to Copycat, the fact that Copycat makes use of [md5](https://en.wikipedia.org/wiki/MD5) means it is difficult for the original input value to be inferred from the output value - it is computationally infeasible. | ||
```js | ||
// It is difficult to reverse engineer 'Some sensitive input' | ||
// from 'Rhianna Ebert' | ||
copycat.fullName('Some sensitive input') | ||
// => 'Rhianna Ebert' | ||
``` | ||
That said, there is still something we need to watch out for: with enough guessing, the input values can still be figured out from the output values. | ||
Lets say we replaced all the first names in some table of data. Included in this data was the name `'Susan'`, which was replaced with `'Therese'`: | ||
```js | ||
copycat.firstName('Susan') // -> 'Therese' | ||
``` | ||
While the attacker is able to see the name `Therese`, it is difficult for them to look at Copycat's code, and figure out `'Susan'` from `'Therese'`. But the attacker knows they're dealing with first names, and they have access to the Copycat library. What they can do, is input a list of first names into Copycat, until they find a matching name. | ||
Let's say they input the name `'John'`. The result is `'April'`, which does not match `'Therese'`, so they move on. They next try `'Sarah'`, which maps to `'Florencio'` - again no match, they move on. They next try `Susan`, which maps to the name they see - `Therese`. This means they have a match, and now know that the original name was `Susan`: | ||
```js | ||
copycat.firstName('John') // -> 'April', no match | ||
copycat.firstName('Sarah') // -> 'Florencio', no match | ||
copycat.firstName('Susan') // -> 'Therese', match! | ||
``` | ||
To mitigate this, Copycat supports [salt](https://en.wikipedia.org/wiki/Salt_(cryptography)) with [`setSalt`](#set-salt) - additional data concatenated onto the input value before hashing: | ||
```js | ||
copycat.fullName('foo') | ||
// => 'Zakary Hessel' | ||
copycat.setSalt('something-else') | ||
copycat.fullName('foo') | ||
// => 'Damion Brown' | ||
``` | ||
The idea is that while Copycat's code is publicly known, the salt isn't publically known. This means that even though attackers have access to Copycat's | ||
code, they are not able to figure out which inputs map to which outputs, since | ||
they do not have access to the salt. | ||
Ideally, one salt should be used per-value, rather than re-used for several values. If salt is re-used, an attacker can [pre-compute a table of results](https://en.wikipedia.org/wiki/Rainbow_table). In our example, a salt value can be chosen and used along with a list of names to pre-compute the corresponding output values. | ||
### `faker` | ||
@@ -445,3 +491,3 @@ | ||
Uses the given `string` value as salt when copycat hashes input values. Helpful for changing the generated results. | ||
<a name="set-salt"></a>Uses the given `string` value as salt when copycat hashes input values. Helpful for changing the generated results. | ||
@@ -448,0 +494,0 @@ ```js |
Sorry, the diff of this file is not supported yet
146220
2174
500