The problem is in cases where the content of $x has not been sanitized and contains data that could potentially be under the control of an attacker in cases that shell code may end up being used in a privilege escalation context (for instance a script invoked by a setuid application, a sudoers script or used to process off-the-network data (CGI, DHCP hook...) directly or indirectly).
If:
x='PATH=2' Then:
x=$((1-$x)) has the side effect of setting PATH to 2 (a relative path that could very well be under control of the attacker). You can replace PATH with LD_LIBRARY_PATH or IFS... The same happens with x=$((1-x)) in bash, zsh or ksh (not dash nor yash which only accept numerical constants in variables there).
In bash, zsh and ksh (not dash or yash), if x is:
x='a[0$(id>&2)]' Then the expansion of $((1-$x)) causes that id command to be executed.
Note that:
x=$((1-$x)) won't work properly for negative values of $x in some shells that implement the (optional as per POSIX) -- (decrement) operator (as with x=-1, that means asking the shell to evaluate the 1--1 arithmetic expression). "$((1-x))" doesn't have the problem as x is expanded as part of (not before) the arithmetic evaluation.
In summary, one shouldn't use uninitialised or non-sanitized external data in arithmetic expressions in shells (note that arithmetic evaluation can be done by $((...)) but depending on the shell in the let, [/test, declare/typeset, return, break, continue, printf, print builtin and ((..)) and [[...]] constructs to name a few).
More reading at:
- http://www.zsh.org/mla/workers/2014/msg01041.html (where Oliver Kiddle brought the
x[0$(...)]issue to our attention). - http://thread.gmane.org/gmane.comp.standards.posix.austin.general/9971
- http://thread.gmane.org/gmane.comp.shells.bash.bugs/22737 for another mis-design potentially leading to code injection in
bash. - Security implications of forgetting to quote a variable in bash/POSIX shells where that and leaving a variable unquoted can aggravate each other.