14

Is the following dangerous?

$ myscript '<somejsoncreatedfromuserdata>'

If so, what can I do to make it not dangerous?

I realize that this can depend on the shell, OS, utility used for making system calls (if being done inside a programming language), etc. However, I'd just like to know what kind of things I should watch out for.

Conley Owens
  • 8,691
  • 5
  • 30
  • 43
  • 1
    AFAIK, this shall not be harmful since proper and valid JSON is always going to have brackets wrapping it, until and unless you are running any parameter from the JSON on the command line, you shall be safe. – Jasdeep Singh Apr 29 '11 at 04:12
  • Do you control the input and processing of it? What do you do with the json object once received? – ljkyser Apr 29 '11 at 04:13
  • In this theoretical example, once I get the input I discard it or do whatever safe thing I want with it. I just want to know how easy it is for some field inside the JSON to escape the quotes do some kind of command line injection attack. – Conley Owens Apr 29 '11 at 05:06

2 Answers2

16

Yes. That is dangerous.

JSON can include single quotes in string values (they do not need to be escaped). See "the tracks" at json.org.

Imagine the data is:

{"pwned": "you' & kill world;"}

Happy coding.


I would consider piping the data in to the program in question (e.g. use "popen" or even a version of "exec" that passes arguments directly) -- this can avoid issues that result from passing through the shell, for instance. Just as with SQL: using placeholders eliminates the need to trifle with "escaping".


If passing through a shell is the only way, then this may be an option (it is not tested, but something similar holds for a "<script>" context):

For every character in the JSON, which is either outside the range of "space" to "~" in ASCII, or has a special meaning in the '' context of a the shell such as \ and ' (but excluding " or any other character -- such as digits -- that can appear outside of "string" data, which is a limitation of this trivial approach), then encode the character using the \uXXXX JSON form. (Per the limitations defined above this should only encode potentially harmful characters appearing within the "strings" in the JSON and there should be no \\ pairs, no trailing \, and no 's, etc.)

  • 1
    Cool beans. I'm actually using the python subprocess module, so I was pretty sure I would be safe with the Popen class, but was still curious in general. – Conley Owens Apr 29 '11 at 05:02
0

It's ok. Just escape the character you use to wrap the string:

' should become '\''

So the JSON string

{"pwned": "you' & kill world;"}

becomes

{"pwned": "you'\'' & kill world;"}

and your final command, as the shell sees it, will be:

$ myscript '{"pwned": "you'\'' & kill world;"}'
fregante
  • 29,050
  • 14
  • 119
  • 159
  • The point of the question is to deal with generated output, not something actually typed on the command line. You'd have to pipe it through sed or something first to accomplish this. – Conley Owens Dec 11 '20 at 21:30