Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need to adjust price of opcode PACK/UNPACK, CONVERT to prevent DoS attack #2383

Closed
Qiao-Jin opened this issue Mar 9, 2021 · 0 comments · Fixed by #2384
Closed

Need to adjust price of opcode PACK/UNPACK, CONVERT to prevent DoS attack #2383

Qiao-Jin opened this issue Mar 9, 2021 · 0 comments · Fixed by #2384
Labels
Discussion Initial issue state - proposed but not yet accepted

Comments

@Qiao-Jin
Copy link
Contributor

Qiao-Jin commented Mar 9, 2021

Summary or problem description
We have discussed about relationship between opcode functionalities & prices in #2004, #1875, etc. However, there still exist some opcodes whose prices are lower than their execution costs in worst cases, which might be utilized in DoS attack.

PACK/UNPACK

According to test result in #2004 the execution time cost of PACK/UNPACK in worst cases are 3874/1656 times of NOP. But the price of both the 2 opcodes are currently 512 times of NOP. Besides, test result shows that a malicious node can use this to delay about 7 seconds with 1 GAS's cost.

        public void TestDosPacking()
        {
            using var script = new ScriptBuilder();
            script.EmitPush((2 * 1024) - 1);
            script.Emit(OpCode.NEWARRAY_T, new byte[] { (byte)StackItemType.Integer });
            script.Emit(OpCode.UNPACK);
            script.Emit(OpCode.PACK);
            script.EmitJump(OpCode.JMP, -2);
            var sc = script.ToArray();
            var snapshot = TestBlockchain.TheNeoSystem.GetSnapshot();
            for (int x = 0; x < 10; x++)
            {
                using var engine = ApplicationEngine.Run(sc, snapshot: snapshot, gas:
                1_00000000);
                engine.LoadScript(script.ToArray(), -1, 0);
                engine.Execute();
            }
        }

CONVERT

Similarly, for opcode CONVERT test result shows that a malicious node can use this to delay about 9.2 seconds with 1 GAS's cost.

        public void TestDosBuffer()
        {
            using var script = new ScriptBuilder();
            script.EmitPush(1024 * 1024);
            script.Emit(OpCode.NEWBUFFER);
            script.Emit(OpCode.CONVERT, new byte[] { (byte)StackItemType.ByteString });
            script.Emit(OpCode.CONVERT, new byte[] { (byte)StackItemType.Buffer });
            script.EmitJump(OpCode.JMP, -4); // Infinite loop
            var sc = script.ToArray();
            var snapshot = TestBlockchain.TheNeoSystem.GetSnapshot();
            for (int x = 0; x < 10; x++)
            {
                using var engine = ApplicationEngine.Run(sc, snapshot: snapshot, gas:
                1_00000000);
                engine.LoadScript(script.ToArray(), -1, 0);
                engine.Execute();
            }
        }

Do you have any solution you want to propose?
Redefine the prices of the 3 opcodes.

Neo Version

  • Neo 3
@Qiao-Jin Qiao-Jin added the Discussion Initial issue state - proposed but not yet accepted label Mar 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion Initial issue state - proposed but not yet accepted
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant