1

Do I need to use check_plain (or something else) when displaying a user supplied JSON string, when I have previously checked it successfully parses with json_decode?

4

TL;DR: You should check_plain it.

Because the json-enoded string itself can contain insecure code.

This is our example. $data[1] and $data[2] should not be executed.

$data = array(
  'Hukana Matata',
  '<script>alert("Oh no!")</script>',
  '<a href="#" onclick="javascript:alert(\"Oh no!\')">CLick here</a>',
);

You encode this with json_encode. If you json_decode($data_str), and it's a perfectly valid JSON.

$data_str = json_encode($data);

Now, if you print this:

print $data_str;

Now, you will see that the forward slash is escaped.

["Hukana Matata","<script>alert(\"Oh no!\")<\/script>","<a href=\"#\" onclick=\"javascript:alert(\\\"Oh no!')\">CLick here<\/a>"]

json_encode encodes strings for JSON notation. In the example above, we encoded using json_encode from PHP's implementation. But depending on the flags, you can prevent PHP from doing do.

$data = array(
      'Hukana Matata',
      '<script>alert(document.title)</script>',
      '<a href="#" onclick="javascript:alert(\"Oh no!\')">CLick here</a>',
    );
$data_str = json_encode($data, JSON_UNESCAPED_SLASHES);
print $data_str;

Notice how the script tag sneaked in:

["Hukana Matata","<script>alert(document.title)</script>","<a href=\"#\" onclick=\"javascript:alert(\\\"Oh no!')\">CLick here</a>"]
| improve this answer | |
  • Awesome answer. check_plain it is. (I assumed this was the case, but wanted a definitive answer, which this looks to be!). Thanks! – Paul Apr 20 '15 at 17:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.