TOTP is an extension of the HMAC-based One Time Password algorithm (HOTP). Both TOTP and HOTP require an secret key to be incorporated into the algorithm. Devices and tokens that implement TOTP (Yubikey, Google Authenticator app) are designed to protect the secret key against extraction.
For example, Yubico mentions:
Secure manufacturing process
The YubiKey is manufactured in Sweden, in a fully access automated process, using YubiHSM technology to
ensure that no staff or IT administrators can have access to
Easy to program own secrets The YubiKey requires no special hardware for programming, enabling you to easily program and control your own
encryption keys. If required, Yubico offer optional password write
protection of the settings, but all YubiKeys sold on our web store can
be re-programmed. For security reasons Yubico firmware is not
upgradable, it’s a write only device and the encryption key can
never be read out from the device. [Emphasis mine]
Tamper proof casing The YubiKey is based on standard components, high-pressure moulded into plastic, making it practically impossible
to tamper. If tampered, it will require sophisticated equipment to
read out the secrets and cannot be done without physically destroying
the device. Each YubiKey is seeded individually, so any breach would
be for that unique Yubikey only, there is no systemic breach. If lost
or stolen, the user administrator can easily disable the YubiKey so
that it no longer can be used.
If we assume that the secret key cannot easily be extracted from the token (and the above examples indicate that we can make that assumption), then it counts as "something you have". Even though the token may be mass produced, once combined with the secret key it becomes unique for the purposes of two-factor auth.
Thank you to Terry Chia who has pointed out that the Google Authenticator app stores the key in cleartext in a sqlite database on the device. This was reported in a bug report in March 2013. Google promptly noted that this is a "won't fix" issue:
Reported by wolfka...@gmail.com, Mar 26, 2013 What steps will
reproduce the problem?
1. Open the databases database from within /data/data/com.google.android.apps.authenticator2/databases/database...
Thank you for your report. This is working as
intended/designed. Step #1 assumes you have root access or have
otherwise compromised the security of the Android device. Security of
data stored on or processed by such devices cannot be guaranteed. ...
I'll note here that you can and should encrypt your Android device, and doing so will mandate a password to unlock the screen. This will protect against key extraction, among other things.