Giter Site home page Giter Site logo

Comments (42)

StormTide avatar StormTide commented on July 27, 2024 1

@onlykey what would happen then is that the next time the real user logs in they would get an err counter too low and lock out. The goal of the counter here is to detect long term access and prevent token duplication. (Think a high-security corporate employee going through a hostile border, etc)

The spec doesn't allow for an epoch as the counter, it needs to actually be incremented per user interaction. Its actually supposed to be per-site, but lots of the tokens share a common counter between sites.

from php-u2flib-server.

konklone avatar konklone commented on July 27, 2024

Any response at all?

from php-u2flib-server.

jas4711 avatar jas4711 commented on July 27, 2024

As far as we could tell from the U2F specs, there is no way to do anything useful with the counter as it is it can wrap and it is underspecified how devices uses the counter. Do you have any suggestions otherwise? Also, as far as we could tell, there is no real security problem caused by this anyway.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

facepalm No real security problem? This allows for counter iteration and dual-use of a cloned token. This is not only a security problem, but a critical one. There are a number of strategies that must be put in place for counter tracking -- the most important of which is tracking for a simple signed rollback @ < countermax. However that's not a real solution either as a token cloner would simply use cloned values of countermax-1, countermax, 1 and then the cloned counter value again to reset state. The counter is a key part of the security model in the U2F spec and is definitely not optional. Devices must be watched for rollover (likely involving a lockout and re-enrollment) and for the more obvious simple rollback.

from php-u2flib-server.

jas4711 avatar jas4711 commented on July 27, 2024

Please explain how we could do better. As far as we can tell, there is no way to check the U2F counter in any generically useful way. I believe our library allows your application to retrieve the counter value, so your application can perform counter-related checks. However, as a library, I have not been able to see any useful checks that are possible.

To give you some background, let's cite all text in the specification related to the counter.

Quoting "FIDO U2F Implementation Considerations" section 2.6: "A U2F token must increase a counter each time it performs an authentication operation. This counter may be 'global' (i.e., the same counter is incremented regardless of the application parameter in Authentication Request message), or per-application (i.e., one counter for each value of application parameter in the Authentication Request message). U2F token counters should start at 0, and wrap around to 0 when they have reached their maximum value."

Quoting "FIDO U2F Raw Message Formats" section 5.4: "A counter [4 bytes]. This is the big-endian representation of a counter value that the U2F token increments every time it performs an authentication operation. (See Implementation Considerations [U2FImplCons] for more detail.)"

Quoting "Universal 2nd Factor (U2F) Overview" section 8.1: "The U2F device protocol incorporates a usage counter to allow the origin to detect problems in some circumstances. The U2F device remembers a count of the number of signature operations it has performed -- either per key pair (if it has sufficient memory) or globally (if it has a memory constraint, this leaks some privacy across keys) or even something in between (e.g., buckets of keys sharing a counter, with a bit less privacy leakage). The U2F device sends the actual counter value back to the browser which relays it to the origin after every signing operation. The U2F device also concatenates the counter value on to the hash of the client data before signing so that the origin can strongly verify that the counter value was not tampered with (by the browser). The server can compare the counter value that the U2F device sent it and compare it against the counter value it saw in earlier interactions with the same U2F device. If the counter value has moved backward, it signals that there is more than one U2F device with the same key pair for the origin (i.e., a clone of the U2F device has been created at some point)."

Let's say you have recorded a last known counter value of, say, 42, and receive 43 or 41 as a current counter there is no useful distinction to be made as far as I can tell. If you received 43, things may be fine, but the counter may also have wrapped (due to large number of uses against some other site, assuming a global counter) and there is a cloned device out there. If you receive 41, things look fishy, but the counter may just have wrapped and there is no cloned device. As far as I can tell, the only useful way to check the counter is for the APPLICATION to perform two U2F Authenticate operations after each other, and compare the counter values. This minimize the chances that a counter wrap occured. In theory, the user might perform ~2^32 U2F Authenticate operations against some other site between the two attempts, but if the time passed between the two attempts is small, this is unlikely. I argue this is hard to know inside the library, though, making it hard to do anything useful inside the library.

I would prefer to resolve this issue by changing the specs to say that U2F counter rollover MUST NOT be permitted by devices.

Thoughts?

from php-u2flib-server.

konklone avatar konklone commented on July 27, 2024

Yes, the counter could wrap, and that's acknowledged in the spec, but that's not something that should be considered normal expected use of the token. It definitely shouldn't prevent any use of the counter to mitigate device cloning.

If a counter wraps, and starts sending wrong numbers, that token should probably be considered invalidated against all the places it's currently authorized with. That's certainly annoying for a token holder, and there's no guarantee on how many bytes the counter has available to it, but 2^32 U2F authentication operations is over 4 billion operations.

Even 2^16 operations is 65536, which would take 3 login attempts a day, every single day, for 60 years, to wrap.

And that's only for the worst case: a token which uses a single global counter for all logins. The spec notes that using such a global counter will leak privacy across websites (it becomes much easier for multiple service providers to make a good guess at whose token is which in both databases), and that tokens with larger memory requirements may/should use separate counters -- either for individual sites, or buckets of sites.

In fact, a counter wrap is perhaps only viable when an attacker has taken control of someone's token and put it through mechanized counting attempts in an effort to wrap the counter. In which case: please consider my token invalidated! 😃

That's all to say that counter wrapping is a highly exceptional scenario. So when it does happen, if someone's token gets effectively de-authorized from all their existing sites and needs to be re-authorized -- that's probably okay. Every U2F-implementing site is going to have a way of dealing with lost or stolen tokens, and that can apply in situations where a counter has gone awry.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

In your example, you must catch 41, after 42 as a cloned-token. A rollover is, as you point out an exceptional and rare event that should never happen in legitimate usage, and as you point out, really probably shouldn't even be allowed by the spec. Part of the problem with the U2F spec is the use of wrapped-keys and global counters. Really, this should be a per-realm keypair and a per-realm counter in an ideal world.

Regardless, the solution ( within the spec allowance of global counters and wrapped keys ) -- I would add to the lib a data access layer (either as an interface to be implemented or just as user-model object) indicating that there are certain user metadata fields that must be stored and monitored for secure operations. At a minimum those fields should include the counter details, number of authentications, and track key rollovers, authentication events and failures, etc.

It may take some Bayesian math to decide when to throw an audit or lockout event, however, I would suggest if the counter moves more than > 256 or so points between authentication events or exceeds a rate of say 128 auth's per 24 hours, it needs to lock the token out and throw a security exception of some sort. If the counter rolls back outside the rate limit, you know it has been hacked and must lock it out and alert an administrative user.

Ignoring the counters as is currently implemented (and as is being picked up by relying parties) however, leaves a massive everyday security hole, where the utility of the counter is entirely negated, and detection of token cloning just wont happen in practice.

TL;DR: add a Security Exception framework, User Metadata tracking model and some rate limiting algorithms and check counter values for rollback. Update docs to include a checklist that there's a mechanism for notifying an admin if a security exception is thrown.

from php-u2flib-server.

jas4711 avatar jas4711 commented on July 27, 2024

The code related to the counter check in the library is here:

https://github.com/Yubico/php-u2flib-server/blob/master/src/u2flib_server/U2F.php#L283

So the counters aren't ignored, as I mistakenly assumed. However, applications using this library needs to pay attention to this issue, which may turn this into a documentation feature request issue. If someone would contribute a security exception framework, that would be awesome, but pending that, simply documenting that if you get a 'counter-too-low' exception, you should invalidated the credential for that user and alert the admin of a cloned device. Anything missing with that approach?

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

None of the implementations of this lib pick up that exception as anything but an auth failure. Also, that code was added after this bug was opened. If left as is, I'd wager on this being ignored in the ecosystem and cloned tokens being an effective hack. Better to fix it now than try to redeploy the tech in the face of cloning.

from php-u2flib-server.

konklone avatar konklone commented on July 27, 2024

So the counters aren't ignored, as I mistakenly assumed. However, applications using this library needs to pay attention to this issue, which may turn this into a documentation feature request issue. If someone would contribute a security exception framework, that would be awesome, but pending that, simply documenting that if you get a 'counter-too-low' exception, you should invalidated the credential for that user and alert the admin of a cloned device. Anything missing with that approach?

Totally. The library should (as I guess it does?) consider a too-low counter an invalid authentication. Implementors should be aware that that's one of several possible reasons an authentication could fail.

In my own implementation work, I don't know if I'd even try to communicate to the users the threat of cloning -- I might just say: "Unfortunately, your device has gotten out of sync with our application and needs to be reauthorized." and then take them into the lost/stolen token workflow.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

@konklone A simple auth failure is useless here as the attacker will just move the counter up by one until he hits the next valid counter. Then when the real user logs in next time, they'll get one auth failure followed by an auth success --- and unless the implementer is tracking counter-too-low exceptions to the db (which isnt in this pattern), no one will really be the wiser.

from php-u2flib-server.

jas4711 avatar jas4711 commented on July 27, 2024

Agreed -- I believe that as soon as you get ERR_COUNTER_TOO_LOW applications must invalidate the credential rather than treating it as an authentication error.

from php-u2flib-server.

jas4711 avatar jas4711 commented on July 27, 2024

Also note that typically the device that would trigger this error would be the original device, not the cloned one, as an attacker who is able to clone a U2F device is surely capable of incrementing the counter value by a sufficient amount to make it higher than the counter stored in the database for that user. So when this incident is noticed by the server, an attack has likely already occured earlier on. What to do in a situation like that is not simple, and probably depends on what you are implementing, so it is an application concern.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

Well, yes/no. If the attacker is smart he'll start at the cloned value and iterate up if long-term access is the goal. In such cases, it will be the cloned token generating a number of auth failures until the right counter is hit. Then the real one hits one bad login, tries again (cuz users always do) and it works -- so no alert gets raised. So no, not really in the realm of the app, but rather in the realm of the 2fa scheme.

from php-u2flib-server.

jas4711 avatar jas4711 commented on July 27, 2024

Sure, if the attacker wants long-term access at the cost of being possible to detect -- I assumed attackers would prefer to stay undetectable.

So can you suggest anything the library can do to make applications/integrators pay attention to this issue? Or should we punt this to improved documentation of the library? It seems simple: ERR_COUNTER_TOO_LOW => invalidate credential.

from php-u2flib-server.

konklone avatar konklone commented on July 27, 2024

Are there any other error conditions which suggest the application should invalidate the credential?

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

The attack scenario for token cloning is the classical temporary access to longterm access... the ol 'at a border', industrial espionage ala apt, etc... its rarely just to gain access as you can pull that off by simple theft or other local system attacks. What we're talking about here is defeating some sort of supply-chain interdiction, apt, etc.. Thats why these counter exist, to prevent two tokens from co-existing.

I think the library has to re-evaluate the in/out here. What is it trying to provide? If its an implementation for U2F, then that really has to include metadata tracking and security event notification and token lockout, beyond that of a 'please watch for err_too_low' doccomment, because we all know how PHP developers stop coding at 'it works'.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

@konklone several. Multiple invalid authentications would stand out, valid auths with counter gaps too large for the time (eg noticing the token has had 1000's of auths in 24 hours or similar) which would indicate some sort of adaptive brute force against the token. (Remembering that the brute force doesnt have to occur against the server application, but rather can target the token in an offline way)

from php-u2flib-server.

konklone avatar konklone commented on July 27, 2024

Hmm. So I'm implementing this in my own site, this afternoon, and I can see why invalidation has to be an application level concern. For any application where keys are an extra level of security, but not required -- if you just invalidate someone's token, it effectively lowers their security and lets an attacker remove their second factor. It's got to descend from a site's policy on how tokens fit into their workflow.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

That wouldnt be the lockout pattern that I'd suggest -- rather the token should still be associated with the user but not allow login. Answer's not removing the token from the account. Basically, the metadata creates an auth check that can no longer pass....

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

If you leave it up to the implementer, and outside the lib, you're basically trying to require everyone using U2F to be an expert in this stuff, to understand things like counters and their purposes. That doesn't make sense to me. Better that the lib provide clear input/output patterns that encapsulate the full responsibility of the spec/token.

from php-u2flib-server.

streaky avatar streaky commented on July 27, 2024

"the token should still be associated with the user but not allow login"

The outcome is the same, legitimate user can't auth with the physical token, DDoS ensues. Yes you should probably have a spare but the reality for those of us not doing U2F dev work is end users won't.

As far as I can see U2F tokens have no protection in software/api against being cloned as hardware OOB [and they probably shouldn't -] it's for people to maintain their personal physical security of their tokens, and at the end of the day that's why we're talking about second factor as opposed to single factor maintained by a token.

There's replay attack protections and they're not related to the counter which appears to be purely convenience related.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

No, no ddos vector is created, as you have to be able to get to valid signature. Only way to force a ddos would be to be able to valid-sign the counter value (and for it to be wrong)... in which case, you definitely want that token locked out and the account locked.

from php-u2flib-server.

streaky avatar streaky commented on July 27, 2024

You were talking about a cloned token were you not? If you're managing to clone a token then you can create a valid signature, did I read it wrong?

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

If the token is cloned, you want the account locked; you are not worried about a denial-of-service attack in this scenario; the signature prevents denial-of-service by a user that is, lets say, unauthenticated. The counter prevents credential cloning, but if it is detected (by a bad counter value), you don't want to say 'but that would lock out the legit user'... you definitely want the account locked as the key has been lost.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

In short; the code needs to be patched to track the counter values, to do more than just reject a login if it detects these type of valid-signature with bad counter errors. For the counter mechanism to work, the account has to be locked out on rollback/rollover. I'm starting a project soon which will use this library, so I may get to hacking it in soon enough, but if yubico+crew could get to it faster it would save me the time.

from php-u2flib-server.

streaky avatar streaky commented on July 27, 2024

You want to know, you don't want to be prevented from getting into systems - it's multi-factor. The second factor isn't the be all/end all of your account security.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

In the typical pattern the U2F challenge occurs after a password login has succeeded @streaky ... you definitely want the account locked out if the counter falls back. 100% of the time. No legitimate use case for a counter rollback.

from php-u2flib-server.

streaky avatar streaky commented on July 27, 2024

Actually no you're right.

from php-u2flib-server.

onlykey avatar onlykey commented on July 27, 2024

@jas4711 sorry if this has already been addressed and I missed it but is there a ERR_COUNTER_TOO_HIGH?

If not then all you would have to do to clone a token is increment the counter to a value that is likely higher than the user's current counter. So as mentioned above "Even 2^16 operations is 65536, which would take 3 login attempts a day, every single day, for 60 years, to wrap.", just set the counter to 65535 and then cloned token would successfully authenticate.

It looks like the U2F trezor token already does this, which is pretty cool because it allows backup/restore of U2F token, but also would permit cloning - https://doc.satoshilabs.com/trezor-user/u2f.html#restoring-u2f-counter-on-trezor

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

@onlykey this issue was never really resolved, a counter too low exception was added but it doesnt address any of the counter-tracking issues. There needs to be tracking if a counter skips ahead too far, if it resets/wraps, etc... none of thats really handled today so yes, a cloned token would work very reliably in practice.

from php-u2flib-server.

onlykey avatar onlykey commented on July 27, 2024

@StormTide Ok thanks for the info, it sounds like there may not be an easy way to prevent device cloning. If you set a low/high counter threshold of say within 100 there is a chance a user could lock themselves out if they don't log into an app for awhile. And even this would not prevent cloning/backup of a device using a method like Trezor uses.

from php-u2flib-server.

streaky avatar streaky commented on July 27, 2024

Except for physical defences of the device of course. You can't just copy the keys off it - so it would take some physical effort though not impossible at the same time. It never purported to be impenetrable - it's a second factor after all.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

Actually it is a required part of the spec, this lib just isnt conforming.

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

@onlykey I'd think the threshold you'd be looking for would be like 2x the highest counter increment you have ever seen from a legit user. For most workloads a sane value would be like 50 + (24 * days since last login). If it moves more than that, lock out the account and go through a CSR process for recovery. What you're trying to detect are large moves in the counter value that wouldn't happen under normal user login situations. Eg 65535... As for the Trezor recovery reset to 0, thats precisely the kind of reset you're trying to trap with this logic.

A fake/cloned token would generally know its own counter value at time of cloning. An attacker will then want to jump forward until the counter works (which would trigger err too low if they're not the exact next login)... or jump ahead to a safe/clean value (and maybe counter advances too fast for a legit user)... the goal here is to either catch the too low and lockout, catch the too high and lockout or to catch the legit user and lockout on their next login preventing long term use of a cloned credential. In any event, these need be more than login failures but rather enable some sort of account lockout procedure as they occur after authentication and do indicate a serious fault condition.

from php-u2flib-server.

onlykey avatar onlykey commented on July 27, 2024

@StormTide The 2x the highest counter approach sounds good but taking a threat modeling perspective, If I am an attacker that has found a vulnerability that allows reading values from a token and I want to clone it and I have access to the current counter, attestation key, and handle key then I can create an exact copy of this token that would work to authenticate. If I can read all values from a token except for the counter (very unlikely I think) then I would have to guess a number within the 50 + (24 * days since last login) range. I understand its part of the spec but looking at this it sounds like maybe this should be reviewed to see if this really offers value or just creates situation where legitimate user could be locked out.

The Trezor approach from how I understand it uses the current unix epoch timestamp as the counter so when you backup/restore a token the counter is always ahead (unless you use a token more than once a second) and still would always be within 2x the highest counter seen. So this would still work.

from php-u2flib-server.

My1 avatar My1 commented on July 27, 2024

This is a really intresting discussion and I also want to add a few things.

@StormTide
"Part of the problem with the U2F spec is the use of wrapped-keys and global counters. Really, this should be a per-realm keypair and a per-realm counter in an ideal world."

generally this would be nice, but I have had the experience of one of my U2F keys (which even was my favorite U2F key) basically doesnt register any new sites with an insufficient resources, and considering they seem to have seperate counters it probably failed because I dragged too many registrations on it (which can obviously happen when you webdev which U2F) which obviously is VERY annoying.

one thing we could talk would be for example having a bunch of pre-created counters and based on for example the hash of the appid or the keyhandle or whatever the key selects which of the counters to use.

with wrapping keys (no matter whether we just encrypt them into the key handle or play (CS)PRNG shenanigans, as long as the method makes sense and is secure and does not allow easy correlation of the keyhandles to the U2F sticks (the whole point of this system in the first place), because while I have no Idea of the prices, I doubt that tamper-proof and/or -evident storage especially if it's supposed to be writable like with the counters is cheap,

There's probably a reason why with FIDO2 the Yubis only allow 25 resident keys while solo goes with 50, and while for many that may be enough, with 47 2FA credentials in my Authy, AND the fact that you cannot erase single Fido2 keys but have to reset the entire key (which also knocks out all U2F keys along the way)I am WAY past that limit especially if we include the fact that services which currently rely on SMS for 2FA may someday adopt U2F/Fido2 and the fact my Yubis probably have a few dozen dead registrations from webdev, I am WAY over those limits and it obviously is NOT feasible to split the websites among the keys as that would end in utter chaos.

also I think this whole Key wrapping business (again, considering both styles) is basically just similar to a password manager, except that the service gets to store the user-crypted password and that the wrapping does not rely on a potentially weak user-password, but a device secret inside a secure element which, generally, shouldnt be able to be directly accessed without literally destroying the key (thereby leaving evidence so the customer can for example knock out the credential or inform the site owners of the breach)

@konklone
Regarding the whole rollover issue, with some more recent keys it's FAR more plausible than ever before, because they try to work around the privacy issue of global counters with non-uniform increments which in the worst case be in the hundreds easily, which then again makes rollover testing a real pain as you cannot properly say how much you can expect any given U2F key to increase the counter over any given time period, also 2^32-1 fell quite a few times because of the counter.

I think we can knock off yet another bit from this as some languages and/or applications can't handle unsigned 32 bit numbers but treating them as signed instead and I doubt that many will actually try and write a "unsigned-style-check" which goes and compares the number in way to treat negative numbers as larger than any positive number. currently though I can say that it still should be rare as long as the keymakers don't overdo the increments but saying 2^16 is enough is definitely not right in those circumstances, although granted, your post was made an entire year before I even got my first U2F key, so I doubt random increments were even a thing back then.

@ topic

I think too that an application should get a note about a too high counter, but only alongside an acknowledgement of whether the sig was checked and if yes whether it's true/false, which may depending on how the fun is written not always fly, as many would probably say to do the "easy" validations first to not waste resources, and basically say "if the counter is too low I won't even sig-check.

This is for the simple reason that if one wants to go a hardline approach like to grill the access with the U2F stick after a low counter, which can result in a DoS for that user if abused, one wants to be sure that an actual threat is happening before potentially locking the user out completely. and not just a script kiddie which just wants to annoy people as much as possible, also the counter check probably isnt going to help against a cloned key anyway as an attacker can just set the number REALLY high and they are in, and while a lock can happen after the real user logs in with their real key, the attacker probably already got access to the account and did all sorts of BS, so it's too late.

so a counter check in general would be best done IN MY OPINION in a way that the library cant play alone.

  1. directly after registration, let the user complete a few authentications (if it's no problem from a crypto perspective one could even keep the same challenge a few times for simplicity and just store the responses seperately before sending them all together towards the server)

  2. compare the counters of the auths and figure out a "safe" value for increase per auth (maybe double the avg of all of them or whatever) and set a number of missed auths as a "safe distance", for example a max of 5 missed auths per day the key wasnt used and a max of 100 auths.

  3. if a user logs in with a Key that has a counter beyond the safe count (but the sig checks out), first deny the login and lock the key, while then sending a message to the user by whatever means and inform him about the counter and that the stick may just have been used a lot on other sites between logins on that site, and that he should check his U2F stick for tampering ASAP and that if he had the U2F stick on himself while the login occured to best erase that U2F stick from all sites they use it, and if he indeed was it, provide a means to unlock the stick (e.g. by logging in with a different second factor and then doing an auth on the locked stick

from php-u2flib-server.

StormTide avatar StormTide commented on July 27, 2024

hi @My1

Yes, the counter-rolled-back lockout should only occur after the signature checks out.

If there's any keys using the epoch as counter, this would, by my read, break the spec. The purpose of the counter is to ensure that two identical (cloned) keys cannot exist concurrently. If you use one, the other should fall behind, or if the bad one is used the good one should fall behind. The purpose of this counter is that it makes it nearly impossible to do some u2f 'master key' nonsense and clone keys around the room. Thats its practical purpose. Its primarily a mechanism to prevent the credential sharing which we see with totp seeds all the time.

So it needs to be implemented in such a way that this goal is achieved. That a rollback event is detected, and if the signature is valid, it should lock the account as if the credential had been improperly shared.

One solution for the non-conforming alter-keys would be to define rules for Yubikeys only (checking the attestation cert) and agree that no Yubikey will ever generate 2^32 u2f signatures in its lifetime when touch-policy is enabled. In that way rules that make sense for specific hardware could be designed. Similarly if a key is known to (wrongly) use epoch as the counter, then that epoch should be confirmed as in range (1 hour?)... and so forth.

In any event this bug dates from 2014 and was never fixed, and with WebAuthN moving forward, I suspect this lib will be retired shortly. Lets hope they fix it in the new sdk. ;)

from php-u2flib-server.

My1 avatar My1 commented on July 27, 2024

epoch as a counter, wtf who had that idea? also, HOW when there are no batteries etc.

the keys I know which increase more than 1, also only increase on each interaction but by an iirc more or less semi-random amount (which basically is supposed to make it harder to track the yubis). the whole idea with my lockout idea was just a quick idea which could use heuristics and stuff to go with how many counter increases can be expected between logins, where obviously time is a factor because most users log in a few times more in a month than in a week, obviously.

the problem with a pure "counter too low" lockout is that the cloned key can gain access once, which often is one time too much as it already allows to do a lot to the account in question, and THAT is one of the big problems.

With my little idea basically for the hacker, they would have to know where the counter roughly is and in which ballpark the increase per action roughly is, so time for an example:

if I use a key which has a strict "+1 per auth" (with the service being aware of that) and have set a maximum of 10 unseen auths per day with a max of 100 auths total, the attacker has a lot less luck the more recently a key has been used, after all he needs to get the key but also hope that the victim doesnt notice and knocks the key out, but within a single day you would need to have the counter with in 10 of the value the service has last seen in order to not raise the suspicion of the service and to temp-lock the key, which leads to the user noticing and then removing that key everywhere.


this may make some attacks at least a bit harder because as said an attacker cant just go and set the counter to a million or whatever and get in.

from php-u2flib-server.

sanawu avatar sanawu commented on July 27, 2024

Nice to know I can render U2F keys denied by having hammered authentication commands and overflow that counter, thanks for the cheap implementation, 60 years use you say? Challenge accepted, you assume good behaved relying parties are always out there

Prevents cloning you say? hahaha, so I can deny accounts locking people out by simply sending non incremented counters? bwahahaha

It doesn't prevent cloning as the clone can just increment the counter massively to be sure, and the legitimate one is denied

Oh not to mention now we have a fingerprint, thanks for the "CHEAP" hardware lol

Wonder if we can wear out the memory too by command hammering, this gone be a fun one when people suddenly find their keys bricked (and accounts locked)

from php-u2flib-server.

My1 avatar My1 commented on July 27, 2024

@sanawu I dont't think you can go into overflow that easily. the counter iirc only is increased if your U2F device actually does an Auth and not just a request.

Let's get the base math out: the U2F counter is 32 bits unsigned (imo a bit little for long term but sure), that makes the max counter 2^32-1 or the safe max counter considering some languages really dont like processing unsigned numbers as 2^31-1, or 2.147.483.647.

assuming a normal U2F/Fido2 device with a global counter (meaning counter starts at zero, no backup or other places where you can play counter shenanigans) with an average increment of 300 per auth and let's say 10 uses a day that would be 3k on the counter per day, this is almost 716k days, leading to almost 1960 years, that should last a few lifetimes.

Even if I go Webdev and use the thing 100 times in a day as a kinda reasonable number we would still be 196 years about double what most humans live.


also what do you exactly mean with denying sending incremented counters right after saying that assuming good RPs is the problem?

the RP does not have anything to say about the counter except the "last seen" counter for the interaction between itself and the U2F devices. the actual counter lives in the U2F device, and in incremented in there every time the user does a successful auth as far as the device is concerned (aka every time it makes a signature), the most you can do as an RP is to deny a user his login at your site, but that's something you can do anyway as a website, no need for U2F with that.


also yes it doesnt exactly prevent cloning but most things called tamperproof nowadays is totally not tamper proof but tamper evident. like moment a low counter error with a proper signature is seen, you as a user can know that something is going on.

and if users use proper safety precautions and have either a backup key or backup method, then cloning and raising a single key's counter wont deny them anything, bonus fact, a few comments above I noted a defense against exactly this type of attack.


also what do you mean with "we have a fingerprint" thing? you mean Devices like the Trustkey G-Series (formerly eWBM Goldengate) with fingerprint readers, sorry but that data doesnt flow through Fido2.

The only thing that flows here is basically the fact that the FP has been checked (or more generally speaking that the device in some form or another verified its user) via a bitflag (aka true/false, that's it) so as said already, nothing for an RP to grab in here.

from php-u2flib-server.

emlun avatar emlun commented on July 27, 2024

Since the U2F API is now obsolete, we're archiving this repository and ceasing maintenance of the library.

from php-u2flib-server.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.