Can super/sub-scripts bind more tightly than macro expansion?

You can't change this behaviour directly, no. However, the breqn package makes ^ and _ active characters that behave as macros that take arguments ‘like normal’, which then has the effect you're looking for. So if you're happy to load breqn, that should fix your problem:

\documentclass{article}
\usepackage{amsmath,breqn}
\begin{document}
\def\ab{ab}\def\cd{cd}
$\ab^\cd$
\end{document}

Another option is to add an extra group in the definition of the macros. For example

\newcommand\ab{{ab}}
\newcommand\cd{{cd}}

However, depending on the actual usage, an additional group may not be desirable.