Yes, not only
(( dict[$var]++ ))
Won't work with some values of $var, but it's also an arbitrary command execution vulnerability.
bash-5.1$ var='1$(uname>&2)'
bash-5.1$ typeset -A dict
bash-5.1$ (( dict[$var]++ ))
Linux
Linux
Quoting the value of $var with printf %q or ${var@Q} is not an option because with some values of $var, those operators use the $'...' form of quoting which is not understood in an arithmetic expression:
bash-5.1$ typeset -A dict
bash-5.1$ var=$(seq 2)
bash-5.1$ (( dict[${var@Q}]++ ))
bash-5.1$ echo "${!dict[@]}"
$1\n2
bash-5.1$ var=$'\n\'$(uname >&2)],x['
bash-5.1$ (( dict["${var@Q}"]++ ))
Linux
bash: ((: dict[$'\n\'$(uname >&2)],x[']++ : bad array subscript (error token is "x[']++ ")
(still an ACE).
Using the new (since 5.0) assoc_expand_once doesn't help as it still doesn't address the problem with the @/* values or the ] character (and so doesn't fix the ACE vulnerabilities):
bash-5.1$ shopt -s assoc_expand_once
bash-5.1$ var='x],b[1$(uname>&2)'
bash-5.1$ typeset -A dict
bash-5.1$ (( dict[$var]++ ))
Linux
Another problem specific to bash (not ksh93 nor zsh) is that bash associative arrays don't support the empty key, so you just can't use arbitrary strings as associative array keys. A work around is to prefix/suffix all your keys with a fixed string.
Here, you can do:
dict[.$var]=$(( ${dict[.$var]} + 1 ))
Or (assuming the assoc_expand_once option is not enabled):
let 'dict[.$var]++'
(make sure you use single quotes).
Here using . as the prefix.
See How to use associative arrays safely inside arithmetic expressions? for all the gory details and more caveats about that.
More generally, shell arithmetic expressions are a minefield. See also: Security Implications of using unsanitized data in Shell Arithmetic evaluation.