Browse Source

removed serialization, was a security risk

master
nitowa 1 year ago
parent
commit
c138a2b9af
5 changed files with 7 additions and 205 deletions
  1. 1
    2
      Index.ts
  2. 0
    67
      src/Decorator.ts
  3. 3
    7
      src/Frontend.ts
  4. 1
    5
      src/Utils.ts
  5. 2
    124
      test/Test.ts

+ 1
- 2
Index.ts View File

@@ -2,5 +2,4 @@ export * from './src/Backend';
2 2
 export * from './src/Frontend';
3 3
 export * from './src/Interfaces'
4 4
 export * from './src/Types';
5
-export * from './src/Utils'
6
-export * from './src/Decorator'
5
+export * from './src/Utils'

+ 0
- 67
src/Decorator.ts View File

@@ -1,67 +0,0 @@
1
-import { CLASSNAME_ATTRIBUTE } from "./Strings"
2
-
3
-export abstract class DeserializerFactory {
4
-    static entityClasses = {}
5
-
6
-    static from(object: any) {
7
-        if(!object){
8
-            return
9
-        }
10
-
11
-        if(typeof object !== 'object'){ //definitely not a class object
12
-            return object
13
-        }
14
-        
15
-        if(Array.isArray(object)){
16
-            return object.map(DeserializerFactory.from)
17
-        }
18
-
19
-        const clazz = DeserializerFactory.entityClasses[object[CLASSNAME_ATTRIBUTE]]
20
-        delete object[CLASSNAME_ATTRIBUTE]
21
-
22
-        if(!clazz){ //anonymous object or class not registered as @Serializable
23
-            Object.keys(object).forEach(key => {
24
-                object[key] = DeserializerFactory.from(object[key])
25
-            })
26
-            return object
27
-        }
28
-
29
-        const obj = new clazz()
30
-        Object.keys(object).forEach(key => {
31
-            obj[key] = DeserializerFactory.from(object[key])
32
-        })
33
-        return obj
34
-    }
35
-
36
-    
37
-
38
-    static makeDeserializable(object: any){
39
-        if(!object)
40
-            return
41
-        
42
-        if(typeof object !== 'object')
43
-            return object
44
-        
45
-        if(object.constructor.name === 'Object'){
46
-            Object.keys(object).forEach(key => {
47
-                object[key] = DeserializerFactory.makeDeserializable(object[key])
48
-            })
49
-            return object
50
-        }
51
-
52
-        object[CLASSNAME_ATTRIBUTE] = object.constructor.name
53
-        Object.keys(object).forEach(key => {
54
-            object[key] = DeserializerFactory.makeDeserializable(object[key])
55
-        })
56
-
57
-        return object
58
-    }
59
-}
60
-
61
-export function Serializable(attr?: any) {
62
-    return function _Serializable<T extends { new(...args: any[]): {} }>(clazz: T) {
63
-        DeserializerFactory.entityClasses[clazz.name] = clazz
64
-        
65
-        return clazz
66
-    }
67
-}

+ 3
- 7
src/Frontend.ts View File

@@ -5,8 +5,6 @@ import * as T from './Types';
5 5
 import * as I from './Interfaces';
6 6
 import { stripAfterEquals, appendComma } from './Utils';
7 7
 import { CALLBACK_NAME, DESTROY_PREFIX, SOCKET_NOT_CONNECTED, UNKNOWN_RPC_IDENTIFIER, USER_DEFINED_TIMEOUT } from './Strings';
8
-import { DeserializerFactory } from './Decorator';
9
-DeserializerFactory
10 8
 
11 9
 
12 10
 /**
@@ -209,10 +207,9 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
209 207
         const headerArgs = fnArgs.join(",")
210 208
         const argParams = fnArgs.map(stripAfterEquals).join(",")
211 209
         sesame = appendComma(sesame)
212
-        const deserializer = DeserializerFactory
213 210
         return eval(`async (${headerArgs}) => { 
214 211
             const returnvalue = await this.call("${fnName}", ${sesame} ${argParams})
215
-            return deserializer.from(returnvalue)
212
+            return returnvalue
216 213
         }`)
217 214
     }
218 215
 
@@ -230,7 +227,6 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
230 227
         const argParams = fnArgs.map(stripAfterEquals).join(",")
231 228
         sesame = appendComma(sesame, true)
232 229
         headerArgs = fnArgs.length > 0 ? headerArgs + "," : headerArgs
233
-        const deserializer = DeserializerFactory
234 230
         const destroy_prefix = DESTROY_PREFIX
235 231
 
236 232
         const frontendHookStr = `
@@ -248,10 +244,10 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
248 244
                         })
249 245
 
250 246
                         this.socket.hook(r.uuid, (...args) => {
251
-                            ${CALLBACK_NAME}.apply(${CALLBACK_NAME}, args.map(deserializer.from))
247
+                            ${CALLBACK_NAME}.apply(${CALLBACK_NAME}, args)
252 248
                         })
253 249
                     }
254
-                    return deserializer.from(r.return)
250
+                    return r.return
255 251
                 }else{
256 252
                     throw new Error("Empty response")
257 253
                 }

+ 1
- 5
src/Utils.ts View File

@@ -4,7 +4,6 @@ import * as T from "./Types";
4 4
 import * as I from "./Interfaces";
5 5
 import { Socket } from "socket.io"
6 6
 import { CALL_NOT_FOUND, DESTROY_PREFIX, RPC_BAD_TYPE, RPC_NO_NAME } from "./Strings";
7
-import { DeserializerFactory } from "./Decorator";
8 7
 
9 8
 /**
10 9
  * Translate an RPC to RPCInfo for serialization.
@@ -80,12 +79,11 @@ const callGenerator = (rpcName: string, $__socket__$: I.Socket, rpcFunction: T.G
80 79
     const argsArr = extractArgs(rpcFunction)
81 80
     const args = argsArr.join(',')
82 81
     const argsStr = argsArr.map(stripAfterEquals).join(',')
83
-    const deserializer = DeserializerFactory 
84 82
 
85 83
     const callStr = `async (${args}) => {
86 84
         try{
87 85
             const res = await rpcFunction(${argsStr})
88
-            return deserializer.makeDeserializable(res)
86
+            return res
89 87
         }catch(e){
90 88
             errorHandler($__socket__$, e, rpcName, [${args}])
91 89
         }
@@ -108,7 +106,6 @@ export function stripAfterEquals(str: string): string {
108 106
  * @returns A {@link HookFunction}
109 107
  */
110 108
 const hookGenerator = (rpc: T.HookRPC<any, any>, errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction, injectSocket?: boolean): T.HookInfo['generator'] => {
111
-    const deserializer = DeserializerFactory 
112 109
     let argsArr = extractArgs(rpc.hook)
113 110
     argsArr.shift()//remove callback param
114 111
 
@@ -125,7 +122,6 @@ const hookGenerator = (rpc: T.HookRPC<any, any>, errorHandler: T.ErrorHandler, s
125 122
             const uuid = uuidv4()
126 123
             const res = await rpc.hook((...cbargs) => {
127 124
                 ${rpc.onCallback ? `rpc.onCallback.apply({}, cbargs)` : ``}
128
-                cbargs = cbargs.map(deserializer.makeDeserializable)
129 125
                 $__socket__$.call.apply($__socket__$, [uuid, ...cbargs])
130 126
             },${callArgs})
131 127
             ${rpc.onDestroy ? `$__socket__$.bind(destroy_prefix+uuid, () => {

+ 2
- 124
test/Test.ts View File

@@ -1,5 +1,4 @@
1 1
 import { describe, it } from "mocha";
2
-import { RPCServer, RPCSocket, Serializable } from '../Index'
3 2
 import { RPCExporter, Socket } from "../src/Interfaces";
4 3
 import { ConnectedSocket, Callback, GenericFunction } from "../src/Types";
5 4
 import * as log from 'why-is-node-running';
@@ -10,6 +9,7 @@ import { PromiseIO } from "../src/PromiseIO/Server";
10 9
 import { PromiseIOClient } from "../src/PromiseIO/Client";
11 10
 import { assert, expect } from 'chai';
12 11
 import { CLASSNAME_ATTRIBUTE, USER_DEFINED_TIMEOUT } from "../src/Strings";
12
+import { RPCServer, RPCSocket } from "../Index";
13 13
 var should = require('chai').should();
14 14
 var chai = require("chai");
15 15
 var chaiAsPromised = require("chai-as-promised");
@@ -1010,126 +1010,4 @@ describe("attaching handlers before connecting", () => {
1010 1010
             done(e)
1011 1011
         })
1012 1012
     })
1013
-})
1014
-
1015
-describe("class (de-)serialization", () => {
1016
-
1017
-    @Serializable()
1018
-    class SubClass {
1019
-        fString = "F"
1020
-    }
1021
-
1022
-    @Serializable()
1023
-    class TestClass {
1024
-        aString = "A"
1025
-        aNumber = 46
1026
-        aObject = {
1027
-            x: "x",
1028
-            y: undefined,
1029
-            sub: new SubClass()
1030
-        }
1031
-        aClassObject = new SubClass()
1032
-
1033
-        public returnOK() {
1034
-            return "OK"
1035
-        }
1036
-    }
1037
-
1038
-    const verifyObject = (obj: any) => {
1039
-        expect(obj).to.be.an.instanceOf(TestClass)
1040
-        expect(obj.aString).to.be.a('string')
1041
-        expect(obj.aNumber).to.be.a('number')
1042
-        expect(obj.aObject).to.be.a('object')
1043
-        expect(obj.aObject.x).to.be.a('string')
1044
-        expect(obj.aObject.y).to.be.undefined
1045
-        expect(obj.aObject.sub).to.be.an.instanceOf(SubClass)
1046
-        expect(obj.aClassObject).to.be.an.instanceOf(SubClass)
1047
-        expect(obj).to.not.have.key(CLASSNAME_ATTRIBUTE)
1048
-        expect(obj.aObject.sub).to.not.have.key(CLASSNAME_ATTRIBUTE)
1049
-        expect(obj.aClassObject).to.not.have.key(CLASSNAME_ATTRIBUTE)
1050
-        expect(obj.returnOK()).to.be.equal('OK')
1051
-    }
1052
-
1053
-    describe("Responses", () => {
1054
-        type TestIfc = {
1055
-            Test: {
1056
-                returnClass: () => Promise<TestClass>
1057
-                classCallback: (callback: Callback<[TestClass]>) => Promise<TestClass>
1058
-            }
1059
-        }
1060
-
1061
-        let myServer: RPCServer<TestIfc>;
1062
-        let mySocket: ConnectedSocket<TestIfc>;
1063
-
1064
-        before(function (done) {
1065
-            myServer = new RPCServer<TestIfc>([{
1066
-                name: "Test",
1067
-                RPCs: [
1068
-                    async function returnClass() {
1069
-                        return new TestClass()
1070
-                    }, {
1071
-                        name: "classCallback",
1072
-                        hook: async function (callback) {
1073
-                            setTimeout(_ => callback(new TestClass()), 250)
1074
-                            return new TestClass()
1075
-                        }
1076
-                    }
1077
-                ]
1078
-            }])
1079
-            myServer.listen(8084)
1080
-
1081
-            new RPCSocket<TestIfc>(8084, 'localhost').connect().then(connsock => {
1082
-                mySocket = connsock
1083
-                done()
1084
-            })
1085
-        })
1086
-
1087
-        after(function (done) {
1088
-            mySocket.close()
1089
-            myServer.close()
1090
-            done()
1091
-        })
1092
-
1093
-
1094
-        it("receives class object in call response", async () => {
1095
-            const obj: TestClass = await mySocket['Test'].returnClass()
1096
-            verifyObject(obj)
1097
-        })
1098
-
1099
-        it("receives class object in hook response", async function () {
1100
-            const obj: TestClass = await mySocket.Test.classCallback(function(x){
1101
-                x
1102
-            })
1103
-            verifyObject(obj)
1104
-        })
1105
-
1106
-        it("receives class object in callback", function (done) {
1107
-            mySocket.Test.classCallback(function (cbValue) {
1108
-                verifyObject(cbValue)
1109
-                done()
1110
-            }).then(verifyObject)
1111
-        })
1112
-    })
1113
-    describe("Parameters", () => {
1114
-        it("Class object in call", function(done){
1115
-            const server = new RPCServer([
1116
-                {
1117
-                    name: "Test",
1118
-                    RPCs: [
1119
-                        function callWithClass(testObj: TestClass){
1120
-                            verifyObject(testObj)
1121
-                            done()
1122
-                        }
1123
-                    ]
1124
-                }
1125
-            ]).listen(8086)
1126
-
1127
-            new RPCSocket(8086, 'localhost').connect().then(sock => {
1128
-                sock['Test'].callWithClass(new TestClass()).then(_ => {
1129
-                    sock.close()
1130
-                    server.close()
1131
-                })
1132
-            })
1133
-        })
1134
-    })
1135
-})
1013
+})

Loading…
Cancel
Save