Originario di Alzano Sopra, tra il 1999 al 2006 corre nelle categorie giovanissimi, esordienti e allievi con una squadra di Nembro, la Valoti Arredamenti poi dal 2004 G.S. Cicloteam Nembro, senza mai raccogliere successi importanti. Tra gli Juniores veste invece per due anni, dal 2007 al 2008, la maglia della For 3-Milram, dove ha il suo primo exploit di successi.
Grazie a questi successi riscuote l'interessamento di diverse squadre professionistiche. Nel settembre del 2011 è così la Lampre-ISD, formazione World Tour, a metterlo sotto contratto: secondo l'accordo, il bergamasco avrebbe dovuto gareggiare come stagista con la squadra di Giuseppe Saronni dal 1º agosto 2012, per poi passare professionista con la stessa maglia all'inizio del 2013[2]. Nel 2012, dopo il secondo posto al Trofeo Franco Balestra, Cattaneo non ottiene vittorie, complice anche una frattura al radio rimediata in una caduta al Giro delle Pesche Nettarine[1][3]. Secondo contratto debutta comunque nelle competizioni pro con la Lampre-ISD in agosto, al Trittico Lombardo, classificandosi tra i primi quindici sia nella Coppa Agostoni che nella Tre Valli Varesine.
Nel 2013 con il team Lampre-Merida fa il suo esordio in numerose classiche come il Giro delle Fiandre e la Liegi-Bastogne-Liegi; approda per la prima volta anche al Giro d'Italia che, però, deve abbandonare presto a causa di una caduta nella settima tappa, da San Salvo a Pescara. Nel 2014, sempre tra le file della Lampre-Merida, partecipa ancora alla Liegi-Bastogne-Liegi e conclude il suo primo Giro d'Italia, al 64º posto.
Ottiene la prima vittoria da professionista al Tour La Provence nel febbraio 2017: scatta a 15 km dall'arrivo della 3ª e ultima tappa, sulla penultima salita, e sul traguardo di Notre Dame de la Garde, il punto più alto di Marsiglia, mantiene 2" di vantaggio su Rohan Dennis, vincitore della classifica finale della corsa proprio davanti a Cattaneo.[4] Nel resto della stagione si mette in luce conquistando il secondo posto nella generale della Okolo Slovenska e il quarto al Tour de l'Ain.
Nel 2019 ottiene risultati di prestigio nelle corse di rifinitura in vista del Giro: dopo aver preso parte alla Settimana Internazionale di Coppi e Bartali e al Giro di Sicilia, è al via del Tour of the Alps, dove ottiene quattro top-10 in cinque frazioni e il quarto posto nella classifica generale. Due giorni dopo vince per distacco il Giro dell'Appennino, precedendo il compagno di squadra Fausto Masnada. Alla corsa rosa riesce ad entrare più volte nella fuga di giornata, ottenendo quattro top-10 tra cui spicca il secondo posto nella 16ª frazione, la Ivrea-Como, dove al termine di una lunghissima fuga di oltre 200 km con Dario Cataldo viene battuto allo sprint.
Cattaneo dietro a Cataldo, nei pressi di Momo, durante la 15ª tappa del Giro d'Italia 2019.