This is a very simple system based on sending JSON messages that seems to have a security vulnerability. There is a Python server (using JSON module included in standard library) which receives JSON objects and acts on them. If it gets {"req": "ping"}, it simply returns {"resp": "pong"}. It also has a command for setting volume, and one to change the admin password. The admin can send any JSON to this server. Here it is (server.py):

import json

import sys

def change_admin_password(p): pass # empty for test

def set_volume(v): pass # empty for test

def handle(js):

if (js["req"] == "ping"):

return {"resp": "pong"}

if (js["req"] == "change admin password"):

change_admin_password(js["args"]["password"])

return {"resp": "ok"}

if (js["req"] == "set volume"):

set_volume(int(js["args"]["volume"]))

return {"resp": "ok"}

print handle(json.load(sys.stdin))

It reads a command from stdin and processes it. Another script would read JSON objects from a network socket and pass them to this script.

Other users have to go through a proxy written in C++ using libjson. It simply blocks requests that should require admin privileges. For example, if a user tries to change the admin password, the proxy will reject the command:

known bug in libjson http://sourceforge.net/p/libjson/bugs/47/

if you punch in the JSON, you will NOT see an error, but the JSON will be reformatted and will remove the first "same" key.

A brief look-around indicates that the standard says you "should not" have duplicate key names, not "must not", so technically libjson is ok.

Your API (ie at(string), operator) is not consistent with either of those two websites (above).

jslint shows an error

jsonlint kills off the first node, leaving the node with the value 5, which I suppose is consistent with javascript's overriding behaviour.

the libjson.at(string) function will return the FIRST entry (rather than the last).

Workaround with JSONNode.find("req")

Look at the find method

JSONNode.find("req");

Returns a pointer to a array of nodes you can use to determine if it has been specified more than once. While the library should overwrite each entry on top of the subsequent one (and is a bug to not do so, per valid JSON) - you can use the find method to locate and obtain an iterator to step over the matching nodes.

note this is not the best workaround in the world as i would imagine this returns all nodes matching the argument and in a complex structure there may be more than one node with the same name nested somewhere else, for your needs this should suffice.

However you should look into another library for validating your JSON calls if this is critical, or possibly support an admin distinguished command, such as areq for an administrative request. This would allow you to scrub out any requests at the proxy that contain the areq command as only administrators would be able to generate such request (and obviously not send through the proxy).

Any standard requests containing administrative commands would just fail off.

Update

Try using the iterator as so, admittedly C++ is not my primary language and i'm not well versed with STL iterators.

illegal or not you need to scrub for this in your proxy and in your server. it is abusing a likely vulnerability in most libraries that concatenate the keys down (as you cannot have duplicate keys). Look for it and scrub it out anywhere it's not being treated as a JSON object.

OR put another layer before your proxy that takes the JSON and runs it through a parser - which would remove any duplicate keys.

EDIT

JSON lib in python is getting the first defn of req and applying it's content, then upon the second definition of req it is overwriting the first and setting the exploiters commands.

Since your python app blindly assumes that any incoming request has been pre-scrubbed (bad idea) you'll need to scrub for this at the proxy layer, and possibly look into using an API key for admin level requests, so that anything that gets through or bypasses your proxy would still need to know a KEY of some sort.