Research
Security News
Kill Switch Hidden in npm Packages Typosquatting Chalk and Chokidar
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Serialize anything. Pretty surreal!
Install using your favorite package manager:
npm install surrial
# OR
yarn add surrial
const { serialize, deserialize } = require('surrial');
class Person {
constructor(name, parent){
this.name = name;
this.parent = parent;
}
}
function identity(thing) { return thing; }
const stringified = serialize({
a: 1,
b: new Date(),
c: /foo/,
d: new Set([1, 2, 3]),
e: new Map([[1, 'one'], [2, 'two']]),
f: Person,
g: identity
});
/* => '{ "a": 1, "b": new Date("2018-02-13T20:27:39.073Z"), "c": /foo/, "d": new Set([1, 2, 3]), "e": new Map([[1, "one"], [2, "two"]]), "f": class Person { constructor(name, parent) { this.name = name; this.parent = parent; } }, "g": function identity(thing) { return thing; } }'
*/
const output = deserialize(stringified)
/* =>
{ a: 1,
b: 2018-02-13T20:32:52.218Z,
c: /foo/,
d: Set { 1, 2, 3 },
e: Map { 1 => 'one', 2 => 'two' },
f: [Function: Person],
h: [Function: identity] }
*/
Also supports serializing instances of classes for known classes.
const p = new Person('Foo', new Person('Bar', null));
const knownClasses = [Person];
const personString = serialize(p, knownClasses);
// => 'new Person("Foo", new Person("Bar", null))'
const copy = deserialize(p, knownClasses);
// => Person { name: 'Foo', parent: Person { name: 'Bar', parent: null } }
TypeScript typings are included in the library.
/**
* Serializes the thing to a javascript string. This is NOT necessarily a JSON string, but will be valid javascript.
* @param thing The thing to be serialized
* @param knownClasses the classes of which instances are serialized as constructor calls (for example "new Person('Henry')").
*/
function serialize(thing: any, knownClasses: ClassConstructor[] = []): string {
/**
* Deserializes a string into it's javascript equivalent. CAUTION! Evaluates the string in the current javascript engine
* (`eval` or one of its friends). Be sure the `serializedThing` comes from a trusted source!
* @param serializedThing The string to deserialize
* @param knownClasses A list of known classes used to provide as constructor functions
*/
function deserialize(serializedThing: string, knownClasses: ClassConstructor[] = []): any;
Date
, RegExp
, Map
, Set
and Buffer
toString()
new MyClass()
syntax (see limitations).deserialize
convenience method. This uses the new Function(/*...*/)
(comparable to eval
) (see limitations).Surrial, like any serialization library, has some limitations, but supports my personal use case. If you need more functionality, don't hesitate to open an issue. I'm always in for a discussion.
Circular references are not supported.
When you call the deserialize
method, any string will be interpreted as javascript using the new Function(...)
constructor. Keep in mind that any arbitrary code will be executed in the global scope of your current javascript engine! Please don't use this library to deserialize strings coming from untrusted sources!
Class instances are serialized using their constructor. Any additional properties are ignored.
class Person {
constructor(name){
this.name = name;
}
}
const p = new Person('foo');
p.age = 10; // => ignored
serialize(p, [Person]);
// => 'new Person("foo")'
Both the class
syntax and prototype
syntax (es5 syntax) are supported here.
When serializing an instance of a class, it is assumed that the constructor parameters are also properties (or attributes) of that class. If not, that parameter will be undefined.
class Person {
constructor(n, age){
this.name = n; // => ignored
this.age = age;
}
}
const p = new Person('foo', 42);
serialize(p);
// => 'new Person(undefined, 42)'
When serializing a class instance, only classes you specify as knownClasses
are actually serialized using new MyClass()
,
by default it would just have a JSON format.
class Person { constructor(name) { this.name = name; }}
serialize(new Person('Foo'));
// => { "name": "foo" }
serialize(new Person('Foo'), [Person]);
// => new Person("foo")
When deserializing a class instance, you are responsible for providing a class definition (or a class with the same name).
class Person { constructor(name) { this.name = name; }}
deserialize('new Person("Foo")');
// => ReferenceError: Person is not defined
deserialize('new Person("Foo")', [Person]);
// => OK: Person { name: 'Foo' }
1.0.0 (2019-02-12)
<a name="0.2.0"></a>
FAQs
Serialize anything. This is surreal!
The npm package surrial receives a total of 10,408 weekly downloads. As such, surrial popularity was classified as popular.
We found that surrial demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.