Strings are NOT arrays, so you cannot loop char-by-char in RouterOS script. You can however use a regex on the original string to do this check for "bad chars". The only issue is "$" is a special char to RouterOS, so the $ dollar-sign needs to be escaped with backslash like \$
In the most basic form, this works:
:put ("bad string!"~"[!@#\$%^&*]")
As a check, this "throws" an error if "bad string" – again the $ must be escaped since that mean a variable name is next in RouterOS...
:global messageText "bad string!!! & *even bad word d@c% or s#\$%"
:if ($messageText~"[!@#\$%^&*]") do={
:error "bad char detected"
}