Jump to content

ATTENTION WEBUI DEVELOPERS: Support token authentication


Ultima

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.

Link to comment
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).

Link to comment
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.

Link to comment
Share on other sites

  • 3 months later...
  • 4 months later...
  • 5 weeks later...

µ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.

Link to comment
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.

Link to comment
Share on other sites

  • 1 month later...

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!

Link to comment
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™.

Link to comment
Share on other sites

  • 1 year later...
  • 4 weeks later...

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.

Link to comment
Share on other sites

  • 2 weeks later...

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?

Link to comment
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!

Link to comment
Share on other sites

  • 3 months later...
  • 5 months later...

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!!!

Link to comment
Share on other sites

Archived

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

×
×
  • Create New...