-
Notifications
You must be signed in to change notification settings - Fork 29
TokenSystem
The Token System is a method for preventing cross-site request forgery attacks which use the authenticated browser session to issue commands to µTorrent. Use of this system is REQUIRED to use the WebAPI.
For example, http://badsite.com/index.html could contain:
<img src="http://localhost:1234/gui/?action=setsetting&s=webui.password&v=badmin" />
and users that view that site, who have logged in to their webui recently from that browser, and run on port 1234, would have their password changed.
Here is what is currently implemented:
index.html includes somewhere in it, ##TOKEN##, for example:
<div id='token' style='display:none;'>##TOKEN##</div>
It's important that this be placed somewhere accessible from Javascript, but invisible to the user. uTorrent will replace ##TOKEN## when it sends the file, with an opaque token value:
<div id='token' style='display:none;'>PF6L4VWuwWvyzYNh6Bng7ZeQxLOSG4f5zA-7sK78bSqNjN4J7wZYXrLDUgA</div>
This token value:
- is URL safe, and should not be further escaped or encoded
- must be passed in &token=HERE for every command
- for painful reasons can occur no later than the position after the "action" or "list" parameter
- can be retrieved from /gui/token.html at any time (while authenticated)
- works forever on the same HTTP connection
- works for 30 minutes after creation for any connection except:
- is invalidated when uTorrent is restarted
Ok: http://localhost:1234/gui/?list=1&token=PF6L4VWuwWvyzYNh6Bng7ZeQxLOSG4f5zA-7sK78bSqNjN4J7wZYXrLDUgA
Ok: http://localhost:1234/gui/?token=PF6L4VWuwWvyzYNh6Bng7ZeQxLOSG4f5zA-7sK78bSqNjN4J7wZYXrLDUgA&list=1
Not Ok: http://localhost:1234/gui/?list=1
If you always read the token out of index.html, browser caching will cause you to eventually get failures when uTorrent restarts, or 30 minutes after the connection is remade for any reason. The right thing to do is: if a backend request ever fails (currently I send HTTP 300, with "invalid request" in the body, but I'm open to suggestions here) you should fetch /gui/token.html, replace your old token with it, and retry the request.