From 0bc7f645316a8c0b1223d7b9de366c6fef726a1b Mon Sep 17 00:00:00 2001 From: Bastien CHAMAGNE Date: Fri, 27 Jan 2023 15:08:18 +0100 Subject: [PATCH] blacklist even more strict --- lib/archethic/contracts/interpreter/action.ex | 86 +++++++++++++++++-- .../contracts/interpreter/action_test.exs | 33 ++++++- 2 files changed, 109 insertions(+), 10 deletions(-) diff --git a/lib/archethic/contracts/interpreter/action.ex b/lib/archethic/contracts/interpreter/action.ex index 7c026a76a9..984bbeffa6 100644 --- a/lib/archethic/contracts/interpreter/action.ex +++ b/lib/archethic/contracts/interpreter/action.ex @@ -148,29 +148,101 @@ defmodule Archethic.Contracts.ActionInterpreter do # Blacklist the add_uco_transfer argument list defp prewalk( - node = {{:atom, key}, _args}, + node = {{:atom, "to"}, address}, _acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}} ) - when key != "to" and key != "amount" do + when not is_binary(address) do + throw({:error, "invalid add_uco_transfer arguments", node}) + end + + defp prewalk( + node = {{:atom, "amount"}, amount}, + _acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}} + ) + when not is_integer(amount) or amount <= 0 do + throw({:error, "invalid add_uco_transfer arguments", node}) + end + + defp prewalk( + node = {{:atom, atom}, _}, + _acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}} + ) + when atom != "to" and atom != "amount" do throw({:error, "invalid add_uco_transfer arguments", node}) end # Blacklist the add_token_transfer argument list defp prewalk( - node = {{:atom, key}, _args}, + node = {{:atom, "to"}, address}, + _acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}} + ) + when not is_binary(address) do + throw({:error, "invalid add_token_transfer arguments", node}) + end + + defp prewalk( + node = {{:atom, "amount"}, amount}, + _acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}} + ) + when not is_integer(amount) or amount <= 0 do + throw({:error, "invalid add_token_transfer arguments", node}) + end + + defp prewalk( + node = {{:atom, "token_address"}, address}, + _acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}} + ) + when not is_binary(address) do + throw({:error, "invalid add_token_transfer arguments", node}) + end + + defp prewalk( + node = {{:atom, "token_id"}, id}, _acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}} ) - when key != "to" and key != "amount" and key != "token_address" and key != "token_id" do + when not is_integer(id) or id < 0 do + throw({:error, "invalid add_token_transfer arguments", node}) + end + + defp prewalk( + node = {{:atom, atom}, _}, + _acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}} + ) + when atom != "to" and atom != "amount" and atom != "token_address" and atom != "token_id" do throw({:error, "invalid add_token_transfer arguments", node}) end # Blacklist the add_ownership argument list defp prewalk( - node = {{:atom, key}, _args}, + node = {{:atom, "secret"}, secret}, _acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}} ) - when key != "secret" and key != "secret_key" and key != "authorized_public_keys" do - throw({:error, "invalid add_token_transfer arguments", node}) + when not is_binary(secret) do + throw({:error, "invalid add_ownership arguments", node}) + end + + defp prewalk( + node = {{:atom, "secret_key"}, secret_key}, + _acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}} + ) + when not is_binary(secret_key) do + throw({:error, "invalid add_ownership arguments", node}) + end + + defp prewalk( + node = {{:atom, "authorized_public_keys"}, authorized_public_keys}, + _acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}} + ) + when not is_list(authorized_public_keys) do + throw({:error, "invalid add_ownership arguments", node}) + end + + defp prewalk( + node = {{:atom, atom}, _}, + _acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}} + ) + when atom != "secret" and atom != "secret_key" and atom != "authorized_public_keys" do + throw({:error, "invalid add_ownership arguments", node}) end # Whitelist the keywords diff --git a/test/archethic/contracts/interpreter/action_test.exs b/test/archethic/contracts/interpreter/action_test.exs index 72710fb31a..5598a3d125 100644 --- a/test/archethic/contracts/interpreter/action_test.exs +++ b/test/archethic/contracts/interpreter/action_test.exs @@ -530,6 +530,8 @@ defmodule Archethic.Contracts.ActionInterpreterTest do ~S""" actions triggered_by: transaction do add_uco_transfer to: "ABC123", amount: 64 + add_token_transfer to: "ABC123", amount: 64, token_id: 0, token_address: "012" + add_ownership secret: "ABC123", secret_key: "s3cr3t", authorized_public_keys: ["ADE459"] end """ |> Interpreter.sanitize_code() @@ -541,8 +543,14 @@ defmodule Archethic.Contracts.ActionInterpreterTest do assert {:ok, :transaction, _ast} = ~S""" actions triggered_by: transaction do - transfer = [to: "ABC123", amount: 33] - add_uco_transfer transfer + uco_transfer = [to: "ABC123", amount: 33] + add_uco_transfer uco_transfer + + token_transfer = [to: "ABC123", amount: 64, token_id: 0, token_address: "012"] + add_token_transfer token_transfer + + ownership = [secret: "ABC123", secret_key: "s3cr3t", authorized_public_keys: ["ADE459"]] + add_ownership ownership end """ |> Interpreter.sanitize_code() @@ -560,7 +568,26 @@ defmodule Archethic.Contracts.ActionInterpreterTest do |> Interpreter.sanitize_code() |> elem(1) |> ActionInterpreter.parse() + + assert {:error, "invalid add_token_transfer arguments - amount"} = + ~S""" + actions triggered_by: transaction do + add_token_transfer to: "abc123", amount: "thirty one" + end + """ + |> Interpreter.sanitize_code() + |> elem(1) + |> ActionInterpreter.parse() + + assert {:error, "invalid add_ownership arguments - authorized_public_keys"} = + ~S""" + actions triggered_by: transaction do + add_ownership secret: "ABC123", secret_key: "s3cr3t", authorized_public_keys: 42 + end + """ + |> Interpreter.sanitize_code() + |> elem(1) + |> ActionInterpreter.parse() end end - end