Si antes se refiere a una OTP que precede a una con la que el usuario ya se autenticó, entonces sí, esto se considera una mala práctica. La OTP está destinada a ser utilizada una vez, de ahí el nombre. El punto central de 2FA es que representa el "algo que tienes" en la trinidad de seguridad. Permitir que un token se use dos veces anula el propósito de lo que las OTP deben evitar. Convirtiéndolo en "algo que sabes", lo que hace que sea solo una segunda contraseña.
Este problema generalmente no se presenta como un problema de fuerza bruta. Por ejemplo, en el caso de TOTP, donde las ventanas de tiempo son relativamente cortas, el forzamiento brutal no se usa para eludirlo. El caso de uso como atacante de un sitio que permite reutilizar las OTP, actuales o pasadas, es la interceptación.
Si el cliente usa la OTP y se intercepta de alguna manera, el atacante ahora reduce el problema a la contraseña del nombre de usuario. Lo cual, si están interceptando información, es probable que también los estén escuchando.
En el caso de HOTP, el problema es aún peor, porque teóricamente el contador o factor de movimiento no se incrementa muy a menudo. Lo que significa que la última o incluso la OTP anterior con la que se autentico el usuario probablemente será válida durante mucho tiempo. En algunos casos, meses dependiendo de la implementación del servidor.
Si por anterior te refieres a la OTP en o antes de la actual generada pero aún no utilizada, entonces no, dentro de los límites. Las implementaciones estándar de OTP aplican una "ventana" para superar los problemas de sincronización generalmente. En el caso de TOTP, se emplea una ventana de 5 segundos (tanto hacia delante como hacia atrás) pero esto, en cualquier implementación que haya visto, siempre desactiva cualquier OTP que esté en o antes de la última con la que el usuario se autenticó. Si tomamos el caso de un paso móvil de 15s con una ventana de 15s, habría tres OTP que se pueden usar para autenticarse en un marco de tiempo de 45s, uno en el pasado, uno ahora y otro en el futuro (esto supone que el intervalo es el mismo como el paso en movimiento). El razonamiento detrás de esto se explica elegantemente en la respuesta de @ cornelinux.
Para HOTP, la ventana es una ventana de "mirar hacia adelante". La última OTP con la que se autentico el usuario fue permitida si estaba dentro de las siguientes 10 OTP de la anterior aceptada, y luego la implementación calcula las siguientes 10 para la verificación contra la próxima OTP ingresada. Tiene el buen sentido de ignorar cualquiera de las OTP que no se usaron en la ventana antes de la que se usó con éxito.
Nota:
En HOTP 10 es arbitrario. Por lo general, el factor es aproximadamente 2.5 veces el número de OTP requeridas para la autenticación exitosa. Por lo tanto, si el usuario necesita 3 HOTP para autenticar la ventana, habrá aproximadamente 8 OTP después de la actual.
En TOTP 5 segundos también es variable. En algunos casos, he visto ventanas tan grandes como el 100% del paso en movimiento. Por lo tanto, con un paso de 30 y una ventana de 30 hace un código válido para 1:30. Nuevamente, expandiendo tanto antes como después de la iteración actual.