Issue information

Issue ID
#7070
Status
Fixed
Severity
None
Started
Ancyker
Feb 12, 2013 17:19
Last Post
Ind
Feb 16, 2013 20:39
Confirmation
N/A

Ancyker - Feb 12, 2013 17:19

The `online` columns sole purpose is to act as a sort of lock on characters to inform any external applications (control panels, etc) that the character is logged in and should not be modified. As it stands now any external application which relies on this data can be mislead into assuming it can make changes when it cannot. This makes any website relying on this column vulnerable to an exploit.

[b]Currently all Athena forks are subject to this vulnerability.[/b] The bug is straight forward and the solution is surprisingly simple. Currently upon character select (case 0x66) mmo_char_fromsql() is called upon prior to set_char_online(). In fact, set_char_online() is called at the very end of this case. While this makes sense when thinking of the `online` column for simply display purposes, when you think of it in the way people are using it an obvious problem emerges. Between those two functions an external application may write or remove data, which will then be overwritten later by the server when the character is saved.

This is what the server does:
Calls mmo_char_fromsql() which loads inventory, cart_inventory, storage, etc.
Does some processing.
Calls set_char_online() which sets `online`=1

Imagine a control panel that does this:
Reads `char` for online=0, all are 0 so the user is offline
Reads `storage` for items, finds one it's looking for
Removes said item.

Now imagine they overlap like this:
[CP] Reads `char` for online=0, all are 0 so the user is offline
[Server] Calls mmo_char_fromsql() which loads inventory, cart_inventory, storage, etc.
[CP] Reads `storage` for items, finds one it's looking for
[Server] Does some processing.
[CP] Removes said item.
[Server] Calls set_char_online() which sets `online`=1

In this situation, the server will never check back with the database, the removal of the item will be undone the next time map server pushes data to be saved.

The fix is quite simple, the online column is never used by the server other than in UPDATE statements. This is a feature purely for the benefit of external applications.

Simply change set_char_online() to occur prior to mmo_char_fromsql(). It seems that this works fine:[code=auto:0]... case 0x66: ... Sql_FreeResult(sql_handle); set_char_online(-2,char_id,sd->account_id); mmo_char_fromsql(char_id, &char_dat, true); ... [/code]It may also be a good idea to run set_char_offline() in the cases of failure inside of that switch. I've tested this lightly and it seems to work.

malufett - Feb 12, 2013 17:35

[quote]
The bug is straight forward and the solution is surprisingly simple. Currently upon character select (case 0x66) mmo_char_fromsql() is called upon prior to set_char_online(). In fact, set_char_online() is called at the very end of this case. While this makes sense when thinking of the `online` column for simply display purposes, when you think of it in the way people are using it an obvious problem emerges. Between those two functions an external application may write or remove data, which will then be overwritten later by the server when the character is saved.[/quote]
its because the server make sure all data are loaded to the client before setting it to online..


[quote]

Imagine a control panel that does this:
Reads `char` for online=0, all are 0 so the user is offline
Reads `storage` for items, finds one it's looking for
Removes said item.[/quote]
its still depends on the implementation and used..and why CP should do '[size=3][background=rgb(247,247,247)]Removes said item.' ??[/background][/size]

:meow:

Ancyker - Feb 12, 2013 17:54

[quote name="malufett" timestamp="1360690554"]
its because the server make sure all data are loaded to the client before setting it to online..[/quote]The character is online the moment character server decides to load it.[quote name="malufett" timestamp="1360690554"]
its still depends on the implementation and used..and why CP should do '[size=3]Removes said item.' ??[/size][/quote]There are many reasons a CP might remove an item. For example, say a GM is manually editing a player to remove a hacked item, a broken item, etc. This also applies to adding items and could happen accidentally. If your CP adds an item (ie from donation) and the user accidentally logs in at the same time the change (item) will be lost.

It also applies to editing the character itself. Say you modify the rename column to be 1, so that a player can rename. If they happen to hit this bug they will lose the ability to rename. This bug hits on anything related to a characters data, not just the inventory.

Ind - Feb 12, 2013 18:17

There is a exploit yes o-o one very rare, may it be point out, which is open for a couple miliseconds window

Ind - Feb 16, 2013 20:39

Fixed in [url="https://github.com/HerculesWS/Hercules/commit/d7ce0c1ce8c4d9118d1340e48424ad9deae0da09"]https://github.com/HerculesWS/Hercules/commit/d7ce0c1ce8c4d9118d1340e48424ad9deae0da09[/url]

This post has been edited by Ind on Feb 17, 2013 2:38