Archived

This topic is now archived and is closed to further replies.

Ultima

ATTENTION WEBUI DEVELOPERS: Support token authentication

Recommended Posts

This sticky is here to address all developers using the WebUI API to communicate with µTorrent:

For those of you that don't know what the token authentication system is in µTorrent, please read this Github wiki. Basically, token authentication was implemented as a measure to protect µTorrent users from CSRF attacks. Unless the WebUI API reliant application is token authentication aware, enabling webui.token_auth in µTorrent will break backwards compatibility with applications.

Sadly, after a short audit of some of the more popular projects that I was able to test, I have yet to see any projects besides Directrix's WebUI, davidraso's iPhone UI, and my own MiniUI support token authentication properly (as of this writing). Keep in mind that the token authentication system has been implemented in µTorrent for well over a year now, so it's not as if this is a new development.

The reason this system was disabled by default in the first place was to give developers time to implement support for the system. Instead, it seems the leeway has made developers complacent, and the result is that we have tons of projects, almost none of which realize (or care enough?) that their userbase's security is at risk. This unfortunate state of affairs is holding µTorrent back, and is leaving µTorrent users open to potential attacks.

We are planning on enabling webui.token_auth by default somewhere in the future. I don't know when we'll be flipping the switch, but don't be surprised if you neglect to implement token authentication support, and your application suddenly stops working after a µTorrent upgrade.

Consider this to be a reaffirmation of our original intentions with webui.token_auth, and a final warning to WebUI developers: IF AT ALL POSSIBLE, SUPPORT TOKEN AUTHENTICATION IN YOUR APPLICATIONS.

If you have any questions about the token authentication system, feel free to ask. Don't let a lack of clarity or understanding keep you from doing what's important.

Lord Alderaan has graciously posted his recommendations for using token authentication.


Those curious as to which projects currently support token authentication can take a look at this thread.


Edit (2009-12-28): As of µTorrent 2.0, webui.token_auth is enabled by default.

Share this post


Link to post
Share on other sites
If you have any questions about the token authentication system, feel free to ask.

I do have one. On the Wiki page, it says:

This token value:

* is URL safe, and should not be further escaped or encoded

But what if the token contains an equal sign? I've had web UI requests randomly failing until I started escape()ing the token, so I'm suspecting it's only URL safe most of the time. (Just guessing with the equal sign, might be any character that can occur in that token).

Share this post


Link to post
Share on other sites

I've definitely never run into any such problem with token encoding in all the time that I've used it. And indeed, the equals sign doesn't need encoding. Admittedly, I have thought it slightly odd to find an equals sign in a token that's supposed to be a GET variable value.

Edit: I've updated the first post with a list of projects that have token authentication support, either by my own testing, or by the developer's confirmation.

Share this post


Link to post
Share on other sites

It looks like that in the newest 2.1 falcon builds the token is also tied to a GUID cookie... of course this is going to improve security even further but it will again break many community projects.

In any case. Can any of the staff confirm this?

Share this post


Link to post
Share on other sites

µTorrent 2.1 implements HTTP cookie support in order to better accommodate multi-session support (I don't expect that it'd affect security much at all, really). As far as I can tell, it shouldn't break existing projects. It's just that existing projects sitting on top of communication backends that do not automatically support cookies won't automatically benefit from improved multi-session handling. Of course, handling cookies would be a good idea if only purely for scalability's sake, so any projects that have to be manually forced to use cookies probably should. Just as a counterexample, browsers do automatically handle cookies, so browser-based UIs should automatically be able to handle the new cookie-based multi-session support.

I can't say I personally know the answer to your particular question (whether tokens are tied to cookies), but I'd say I wouldn't be all that surprised if that were the case -- it wouldn't be nice if expired tokens for one session clashed with good tokens for another.

Share this post


Link to post
Share on other sites

I agree with all the benefits. I'm not criticizing the functionality just asking for information or confirmation :)

Because it seems the webui API now refuses my token if I omit the cookie from the request.

Share this post


Link to post
Share on other sites

Oh, I wasn't saying you were criticizing -- I was just explaining. I don't know a whole lot about the cookie-related changes because I haven't really touched 2.1, so I may very well be wrong. It's just that it's kind of stupid to break backwards compatibility unnecessarily when it could just default to old behavior without cookies.

Will ask a dev.

Share this post


Link to post
Share on other sites

Any chance someone can be an actual example of code regarding this token authentication up here?

I've googled it,read the referenced token authentication page, and have attempted multiple ways of getting it.

Tried it with AutoIT3, and also with winhttp. I'm also familiar with VB and Perl - so whatever language you want- I'd be happy to take!

Thanks a million!

Share this post


Link to post
Share on other sites

Ok, imho a proper process for any app to contact the Web API is:

[h]Step 1:[/h]

Request token.html WITHOUT http authentication.

This is standard practice to prevent accidentally sending your credentials to a wrong recipient.

You could skip this step if you wanted to.

You send:

GET /gui/token.html HTTP/1.1Host: 192.168.0.1:12345

The response should be:

If you do not get a 401 Unauthorized with an authenticate request for realm uTorrent you should abort the process.

HTTP/1.1 401 UnauthorizedConnection: closeWWW-Authenticate: Basic realm="uTorrent"

[h]Step 2:[/h]

Request token.html with http authentication.

You send:

GET /gui/token.html HTTP/1.1Host: 192.168.0.1:12345Authorization: Basic dGVzdDp0ZXN0

The response should be:

This response has all the info you need for any future connection. First it has the GUID cookie in the Set-Cookie line. Secondly it has the token in a div in the actual HTML.

HTTP/1.1 200 OKConnection: keep-aliveContent-Length: 117Content-Type: text/htmlSet-Cookie: GUID=AGgH5qhf2K4NU9o9QVLo; path=/Cache-Control: no-cache<html><div id='token' style='display:none;'>n0Y7ezLlIYA8R0K54rEmHaTOraBQVSPDjQaGlQxlGso4jdVN1kRxtcfskEs=</div></html>

[h]Step 3:[/h]

Now you can (for example) request the torrent list.

You send:

GET /gui/?list=1&token=n0Y7ezLlIYA8R0K54rEmHaTOraBQVSPDjQaGlQxlGso4jdVN1kRxtcfskEs= HTTP/1.1Host: 192.168.0.1:12345Cookie: GUID=AGgH5qhf2K4NU9o9QVLoAuthorization: Basic dGVzdDp0ZXN0

The response should be:

This example shows the 2.1 Web API JSON response which has more info then the 2.0 one.

HTTP/1.1 200 OKConnection: keep-aliveContent-Length: 254Content-Type: text/plainCache-Control: no-cache{"build":18304,"label": [],"torrents": [["2895ECDD79A4E8D5CF69DF9FABF013D6001DCA3F",136,"OOo_3.2.0_Win32Intel_install_wJRE_nl.exe",154056488,0,0,0,0,0,0,0,"",0,0,0,0,0,1,154056488,"",""]],"torrentc": "2111264392","rssfeeds": [],"rssfilters": []}

[h]invalid request[/h]

invalid request is the response from µTorrent when authentication fails. The token you were using will be invalidated and you have to redo the whole process from step 1.

Keep in mind that there might also be other reasons for the invalid request to pop up as listed in this topic.

The invalid request response:

HTTP/1.1 400 ERRORConnection: keep-aliveContent-Length: 15Content-Type: text/htmlinvalid request

I will update this post with some code examples soon™.

Share this post


Link to post
Share on other sites

It would be better return the token in JSON or XML format. Don't you think?

It's better to parse with a program.

You could add a variable, to the URL request, with the desired format.

Share this post


Link to post
Share on other sites

Nice summary. I'll have to think about adding step 1.

Although the token comes back in HTML format and the content type is tagged that way, it can be parsed as XML. JSON seems a bit like overkill and not as widely supported, but I guess if you're going to do anything with the token you probably need to understand JSON anyway :) I vote for keeping it the same as being more important than adding bells and whistles.

Share this post


Link to post
Share on other sites

I'm trying to write a piece of code in Python, using urllib2, that would use that WEB API. My Bittorrent server is running on a Buffalo NAS; the realm I needed to use to authenticate is uTorrentEmbedded.

I manage to authenticate, and get back a page with <!-- /* Torrent Add Dialog --> on it when I call /gui/; I manage to call /gui/token.html, and get back a token.

WebUI runs flawlessly, and uses the same token throughout the session. However, when I try to use a token obtained from /gui/token.html, for list=1, or action=add-url, I get invalid request.

All my tokens end with = . Tried encoding, but no good. Any ideas what could be going wrong?

Share this post


Link to post
Share on other sites

It does work, I promise, with a wide range of server versions including 3.0 alpha and beta. Cookies sounds like a candidate for your problem. Not a lot else can go wrong. All tokens seem to end with "=", not sure why.

Share this post


Link to post
Share on other sites
It does work, I promise, with a wide range of server versions including 3.0 alpha and beta. Cookies sounds like a candidate for your problem. Not a lot else can go wrong. All tokens seem to end with "=", not sure why.

It was indeed the cookies. I failed to understand (in my lack of experience with web applications) that it is actually the combination of cookie+token that protects you from CSRF. Many thanks for pointing it out!

Share this post


Link to post
Share on other sites

I have an odd problem that is probably really simple to fix, but I have banged my head long enough without resolution.

I wrote a program in VB.Net that accesses the WebUI. In 2.21 it worked perfectly, Pulled the token from the token.html and allowed me to authenticate and send commands and receive status etc.

Once I installed 3.12, it broke. I cannot for the life of me see what the difference is but I keep getting a 400 error stating my request was invalid.

I ran firebug and looked at the token string and commands being send and I don't see what has changed

Any help or direction would be greatly appreciated!!!

Share this post


Link to post
Share on other sites