Skip to content

Commit

Permalink
Whitelist keywords and blacklist some keyword in functions
Browse files Browse the repository at this point in the history
  • Loading branch information
bchamagne committed Jan 27, 2023
1 parent 3d39ad4 commit 88cadf3
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 121 deletions.
139 changes: 18 additions & 121 deletions lib/archethic/contracts/interpreter/action.ex
Original file line number Diff line number Diff line change
Expand Up @@ -146,140 +146,37 @@ defmodule Archethic.Contracts.ActionInterpreter do
{node, acc}
end

# Whitelist the add_uco_transfer function parameters
# Blacklist the add_uco_transfer argument list
defp prewalk(
node = {{:atom, "to"}, address},
acc = {:ok, %{scope: {"add_uco_transfer", {:actions, _}}}}
node = {{:atom, key}, _args},
_acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}}
)
when is_binary(address) do
{node, acc}
when key != "to" and key != "amount" do
throw({:error, "invalid add_uco_transfer arguments", node})
end

# Blacklist the add_token_transfer argument list
defp prewalk(
node = {{:atom, "to"}, address},
acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}}
node = {{:atom, key}, _args},
_acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}}
)
when is_binary(address) do
{node, acc}
end

defp prewalk(
node = {{:atom, "to"}, {{:atom, _}, _, _}},
acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}}
) do
{node, acc}
end

defp prewalk(
node = {{:atom, "amount"}, amount},
acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}}
)
when is_integer(amount) and amount > 0 do
{node, acc}
end

defp prewalk(
node = {{:atom, "amount"}, {{:atom, _}, _, _}},
acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}}
) do
{node, acc}
end

# Whitelist the add_token_transfer argument list
defp prewalk(
node = {{:atom, "to"}, address},
acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}}
)
when is_binary(address) do
{node, acc}
end

defp prewalk(
node = {{:atom, "to"}, {{:atom, _}, _, _}},
acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}}
) do
{node, acc}
end

defp prewalk(
node = {{:atom, "amount"}, amount},
acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}}
)
when is_integer(amount) and amount > 0 do
{node, acc}
end

defp prewalk(
node = {{:atom, "amount"}, {{:atom, _}, _, _}},
acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}}
) do
{node, acc}
when key != "to" and key != "amount" and key != "token_address" and key != "token_id" do
throw({:error, "invalid add_token_transfer arguments", node})
end

# Blacklist the add_ownership argument list
defp prewalk(
node = {{:atom, "token_address"}, token_address},
acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}}
node = {{:atom, key}, _args},
_acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}}
)
when is_binary(token_address) do
{node, acc}
end

defp prewalk(
node = {{:atom, "token_address"}, {{:atom, _}, _, _}},
acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}}
) do
{node, acc}
end

defp prewalk(
node = {{:atom, "token_id"}, token_id},
acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}}
)
when is_integer(token_id) and token_id >= 0 do
{node, acc}
end

defp prewalk(
node = {{:atom, "token_id"}, {{:atom, _}, _, _}},
acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}}
) do
{node, acc}
end

# Whitelist the add_ownership argument list
defp prewalk(
node = {{:atom, "secret"}, secret},
acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}}
)
when is_binary(secret) do
{node, acc}
end

defp prewalk(
node = {{:atom, "secret"}, {{:atom, _}, _, _}},
acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}}
) do
{node, acc}
end

defp prewalk(
node = {{:atom, "secret_key"}, _secret_key},
acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}}
) do
{node, acc}
end

defp prewalk(
node = {{:atom, "authorized_public_keys"}, authorized_public_keys},
acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}}
)
when is_list(authorized_public_keys) do
{node, acc}
when key != "secret" and key != "secret_key" and key != "authorized_public_keys" do
throw({:error, "invalid add_token_transfer arguments", node})
end

# Whitelist the keywords
defp prewalk(
node = {{:atom, "authorized_public_keys"}, {{:atom, _, _}}},
acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}}
node = {{:atom, _}, _},
acc = {:ok, _}
) do
{node, acc}
end
Expand Down
40 changes: 40 additions & 0 deletions test/archethic/contracts/interpreter/action_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -523,4 +523,44 @@ defmodule Archethic.Contracts.ActionInterpreterTest do
}
})
end

describe "blacklist" do
test "should parse when arguments are allowed" do
assert {:ok, :transaction, _ast} =
~S"""
actions triggered_by: transaction do
add_uco_transfer to: "ABC123", amount: 64
end
"""
|> Interpreter.sanitize_code()
|> elem(1)
|> ActionInterpreter.parse()
end

test "should parse when building a keyword list" do
assert {:ok, :transaction, _ast} =
~S"""
actions triggered_by: transaction do
transfer = [to: "ABC123", amount: 33]
add_uco_transfer transfer
end
"""
|> Interpreter.sanitize_code()
|> elem(1)
|> ActionInterpreter.parse()
end

test "should not parse when arguments are not allowed" do
assert {:error, "invalid add_uco_transfer arguments - hello"} =
~S"""
actions triggered_by: transaction do
add_uco_transfer to: "abc123", amount: 31, hello: 1
end
"""
|> Interpreter.sanitize_code()
|> elem(1)
|> ActionInterpreter.parse()
end
end

end

0 comments on commit 88cadf3

Please sign in to comment.