samchon / tgrid

TypeScript RPC (Remote Procedure Call) for WebSocket and Worker protocols
https://tgrid.com/
MIT License
141 stars 19 forks source link

[RFC] Security Enhancements are required #20

Closed samchon closed 4 years ago

samchon commented 4 years ago

Summary

Code occuring the bug

Until v0.1, Remote Function Call can access to dangerous members.

If you call the Function.toString() to member function who is defined in the remote object, you can read implementation code of the remote Provider. If you access to constructor if a remote object, you can access to prototype definition of the remote Provider.

It seems not good within framework of the security. I think those dangerous accesses must be blocked. The blocking must be implemented not only in the RFC level, but also the Driver (type definition) level.

import { WebConnector } from "tgrid/protocols/web/WebConnector";
import { Driver } from "tgrid/components/Driver";

interface ICalculator
{
    scientific: IScientific;
    statistics: IStatistics;

    plus(x: number, y: number): number;
    minus(x: number, y: number): number;
    multiplies(x: number, y: number): number;
    divides(x: number, y: number): number;
}

async function main(): Promise<void>
{
    let connector: WebConnector = new WebConnector();
    await connector.connect("ws://127.0.0.1:10101");

    let calc: Driver<ICalculator> = connector.getDriver();

    // CAN SEE IMPLEMENTATION CODE OF REMOTE PROVIDER
    console.log(await calc.constructor.toString()); 
    console.log(await calc.plus.toString());

    // DANGEROUS ACCESSMENTS, SHOULD BE BLOCKED
    console.log(await calc.prototype.multiplies.bind({})(3, 4));
    console.log(await calc.prototype.divides.call({}, 3, 4));

    await connector.close();
}

Enhancements

The dangerous accesses would be prohibited in RFC communication level. Also, I'm planning to block those dangerous accesses in the compiler level. The Driver type would prohibit to access to those dangerous members by assigning the never type.

type Driver<ICalculator> = 
{
    scientific: Driver<IScientific>;
    statistics: Driver<IStatistics>;

    // FUNCTIONS ARE ENHANCED BY FUNCTOR
    plus: Functor<(x: number, y: number) => Promise<number>>;
    minus: Functor<(x: number, y: number) => Promise<number>>;
    multiplies: Functor<(x: number, y: number) => Promise<number>>;
    divides: Functor<(x: number, y: number) => Promise<number>>;

    // CANNOT ACCESS TO DANGEROUS MEMBERS
    constructor: never;
    prototype: never;
};

type Functor<T extends Function> = T & 
{
    constructor: never;
    prototype: never;
    Symbol: never;
    bind: never;
    ...
};