Comments (15)
I wonder if there are any Axiom applications that are using a non-plaintext authentication method (Quotient, maybe?); those would be broken by this change, right?
from axiom.
So, from a cryptographic standpoint, a KDF pretty much has to block. While the standard for what counts as acceptable blocking or not differs for each application, we're talking order of magnitude 10-100ms here, and that is definitely not acceptable for some, if not most, applications.
FWW, this wouldn't have broken my stuff, but only because I totally dodged the whole Axiom user model thing for precisely this reason.
@mithrandi Not sure what you mean; don't they just upgrade some objects to some interfaces? ISTR IUsernameHashedPassword
is synchronous, but that just means that interface is broken too, which might mean that this ticket is a bit of a rabbit hole :-) If that's what you mean, then yes; we can't fix things that want to use that interface.
from axiom.
Also, I think there's a twisted ticket for that...
from axiom.
My question doesn't have anything to do with synchronous vs asynchronous.
Authentication methods that don't send the password over the transport in cleartext typically require the password in cleartext locally so that they can perform some kind of challenge-response handshake with it. For example, CRAM-MD5 (which I think is a commonly-used POP3/IMAP authentication method?) has the server send a challenge C
, and the client respond with HMAC-MD5(C, password)
, which requires the server to know password
in order to calculate the expected value to compare it against what the client sent.
In terms of interfaces, these authentication methods require IUsernamePassword
and cannot use IUsernameHashedPassword
.
from axiom.
@mithrandi That sort of question is exactly how we got into this mess
CRAM-MD5 can "protect" your credentials on the wire and on your server. But I put "protect" in quotes for two reasons:
- the way we do it, and the way most clients do it is by storing the plain text, rather than
i_key_pad
ando_key_pad
anyway, so the server gets to see the credentials regardless - the protection doesn't actually work; it's reversible due to weaknesses in MD5 by capturing either the server's state or the wire conversation.
Therefore Quotient (et. al.) should just stop using it and having the pretense that it can protect credentials on the wire. You have to use TLS. It also can't protect credentials on the server because the crypto simply isn't good enough.
There are protocols that can effectively offer protection in all three places (on the wire, in the server's memory, on the server's disk), such as TLS-SRP but those are not widely deployed enough to use in practice. However, if we have a protocol where you have to give the server your plaintext credentials anyway, it's always possible to upgrade to a better protocol when it's available by doing so on login.
We should just switch over to a cred thing that authenticates only via PLAIN
, and only operates over TLS.
from axiom.
@lvh -
So, from a cryptographic standpoint, a KDF pretty much has to block
I should mention that this isn't all that serious of a problem. Cred has Deferred
s returned from all the relevant integration points for specifically that reason, and I don't think we have to break any compatibility at that integration point. We will have to break the .password
field, obviously; that's sort of the point, and have an upgrade process which spins the reactor. But anyone calling something that relies on non-blocking auth in any fundamental way is broken regardless.
from axiom.
@lvh - I know that keybase has a thing that says "scrypt" when you log in, and it's presumably using some fancy javascript to avoid sending my real actual password to the server. Is there something one can do to make scrypt itself work as a challenge-response protocol?
from axiom.
I just had a many-hour-long conversation with @lvh about threat models and I believe the conclusion was this:
It's possible to use extra fancy authentication mechanisms with help from the client (browser-side javascript to compute a pre-hashed scrypt key, or better yet using a KDF to derive a public key to sign a server challenge) to mitigate a very slightly more sophisticated threat model and reduce the opportunity for password re-use attacks. The other approaches would be a prohibitive amount of additional work and, based on vagaries of client security, might not practically provide anything more secure (i.e. any attacker who can do X can do Y, and we'd just be adding a defense against X without defending against Y).
So, fundamentally "just use txscrypt" is the best compromise between providing an acceptable level of security for users and maintaining our own sanity.
from axiom.
(according to github timestamps that was only an hour but it felt like daaaaaays)
from axiom.
Now, regarding @mithrandi's question about whether anything will break, since I guess I didn't answer that:
Yes. Quotient will break any clients which have selected the CRAM-MD5 authentication mechanism, because it incorrectly, unconditionally advertises CRAM-MD5. However, clients may happily select LOGIN. https://github.com/twisted/quotient/blob/95f2515219da99a77905852bc01deeb27e93466e/xquotient/mail.py#L317-L322
While I was investigating this I realized that the whole way it does this is totally undocumented. There are some IMAP-specific credentials:
https://github.com/twisted/twisted/blob/trunk/twisted/mail/imap4.py#L384-L413
which are weirdly randomly manipulated with no explanation:
https://github.com/twisted/twisted/blob/trunk/twisted/mail/imap4.py#L1036-L1040
commented (but not documented) to implement an interface that doesn't actually exist anywhere:
https://github.com/twisted/twisted/blob/trunk/twisted/mail/imap4.py#L520-L521
and the way you turn on CramMD5 is to use this thing:
https://github.com/twisted/twisted/blob/trunk/twisted/cred/credentials.py#L378-L408
and appears to depend on this one weird method:
https://github.com/twisted/twisted/blob/trunk/twisted/mail/imap4.py#L390-L391
from axiom.
The place it advertises the wrong list is here: https://github.com/twisted/twisted/blob/trunk/twisted/mail/imap4.py#L541-L542
from axiom.
Or rather, it's not advertising the wrong list there, it's advertising the list that it's given, but ... Quotient unconditionally CramMD5Credentials in its challengers map, and that adds it as a capability there.
The correct thing to do architecturally within cred would be to check the credentialInterfaces of each checker in the portal's checker list.
Unfortunately, to make this "easy", IUsernamePassword
also specifies a checkPassword(password)
where password
is supposed to be a plain-text password gotten out of a database. Ugh. However, luckily, this is merely aesthetically unfortunate. IUsernamePassword
also specifies a password
attribute which is the plain-text password from the wire, and we could easily write a checker which could check IUsernamePassword
without ever calling checkPassword
, ignoring it entirely.
from axiom.
To be more specific, when I say "check the credentialInterfaces of each checker in the portal's checker list", I mean, imap4 itself ought to select which challengers to use because a challenger may only be used with a checker that is a provider of one of the interfaces that the given challenger (i.e. callable that returns a credential).
This is a bit of an implementation accident, but since there's no documentation anywhere of what goes in the challengers
attribute, just about anything is an implementation accident.
from axiom.
Sorry, a checker whose credentialInterfaces
contain an interface that a given challenger is an implementer of. The checker should just provide ICredentialsChecker
.
from axiom.
PR up! Reviews desperately desired.
from axiom.
Related Issues (20)
- Python 3 support HOT 5
- Release artifacts are broken
- `axiom.attributes.bytes` shadows builtin name
- In memory powerup is only able to register a single item.
- pyenv us a newer PyPy on Travis
- Switch to Codecov for coverage
- Helper for declaring legacy items HOT 1
- Intermittent failure in reactor selection tests
- Question: raw queries? HOT 1
- NEWS.txt isn't shipped in sdist
- Store API for setting the journal mode
- Decorator for installables HOT 4
- Default log rotation is bad
- Update PyPy
- Setting typeName to unicode produces bizarre errors
- axiomatic analyze
- axiomatic vacuum
- Store flags for journal_mode and autovacuum_mode
- Creating and deleting an item in the same transaction leaves a ghost item
- Store._loadedItem returns stale Item from Store.objectCache
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from axiom.