Se per precedente intendi un OTP che precede uno già autenticato dall'utente allora sì, questo è considerato una cattiva pratica. L'OTP è pensato per essere usato una volta, da cui il nome. L'intero punto di 2FA è che rappresenta il "qualcosa che hai" nella trinità della sicurezza. Consentire a un token di essere usato due volte sconfigge lo scopo di ciò che gli OTP intendono prevenire. Trasformandolo in "qualcosa che conosci" che lo rende solo una seconda password.
Di solito questo problema non si presenta come un problema di forza bruta. Ad esempio, nel caso del TOTP, in cui le finestre temporali sono relativamente brevi, la forzatura bruta non viene realmente utilizzata per aggirarla. Il caso d'uso come attaccante di un sito che consente il riutilizzo di OTP, sia in corso che passato, è l'intercettazione.
Se il client utilizza l'OTP ed è intercettato in qualche modo, l'utente malintenzionato riduce il problema alla password del nome utente. Che, se stanno intercettando le informazioni, probabilmente li sta anche ascoltando.
Nel caso di HOTP il problema è anche peggiore, perché teoricamente il contatore o il fattore di movimento non aumenta molto spesso. Significa l'OTP precedente o precedente che l'utente autenticato sarà probabilmente valido per un lungo periodo. In alcuni casi mesi a seconda dell'implementazione del server.
Se per precedente si intende l'OTP su o prima di quello corrente generato ma non ancora utilizzato, quindi no, entro i limiti. Le implementazioni standard di OTP applicano una "finestra" per superare i problemi di sincronizzazione di solito. Nel caso di TOTP, viene impiegata una finestra di 5 secondi (sia in avanti che all'indietro) ma questo, in tutte le implementazioni che ho visto, disattiva sempre qualsiasi OTP che si trova su o prima dell'ultimo con cui l'utente ha autenticato. Se consideriamo il caso di un passaggio di 15 secondi con una finestra di 15s, ci saranno tre OTP che possono essere usati per autenticare in un intervallo di 45 secondi, uno nel passato, uno ora e uno nel futuro (questo presuppone che l'intervallo sia lo stesso come il passaggio in movimento). Il ragionamento alla base di questo è spiegato elegantemente nella risposta di @ cornelinux.
Per HOTP la finestra è una finestra "guarda avanti". L'ultimo OTP con cui è stato autenticato l'utente era consentito se era compreso tra i successivi 10 OTP del precedente accettato, e quindi l'implementazione calcola il successivo 10 da quello per il controllo rispetto al prossimo OTP immesso. Ha il considerevole buon senso di ignorare qualsiasi OTP non utilizzato nella finestra prima di quello usato con successo.
Nota:
In HOTP 10 è arbitrario. Di solito il fattore è circa 2,5 volte il numero di OTP richiesti per l'autenticazione con successo. Quindi se l'utente ha bisogno di 3 HOTP per autenticare la finestra saranno circa 8 OTP dopo quella corrente.
In TOTP 5 secondi è anche variabile. In alcuni casi ho visto finestre grandi quanto il 100% del passaggio in movimento. Quindi con un passo di 30 secondi e una finestra di 30 fa effettivamente un codice valido per 1:30. Di nuovo, espandendo sia prima che dopo l'iterazione corrente.