{"action":"opened","issue":{"url":"https://api.github.com/repos/mruby/mruby/issues/4115","repository_url":"https://api.github.com/repos/mruby/mruby","labels_url":"https://api.github.com/repos/mruby/mruby/issues/4115/labels{/name}","comments_url":"https://api.github.com/repos/mruby/mruby/issues/4115/comments","events_url":"https://api.github.com/repos/mruby/mruby/issues/4115/events","html_url":"https://github.com/mruby/mruby/issues/4115","id":360395419,"node_id":"MDU6SXNzdWUzNjAzOTU0MTk=","number":4115,"title":"Missing type check in mrb_pack_pack","user":{"login":"clayton-shopify","id":11052374,"node_id":"MDQ6VXNlcjExMDUyMzc0","avatar_url":"https://avatars0.githubusercontent.com/u/11052374?v=4","gravatar_id":"","url":"https://api.github.com/users/clayton-shopify","html_url":"https://github.com/clayton-shopify","followers_url":"https://api.github.com/users/clayton-shopify/followers","following_url":"https://api.github.com/users/clayton-shopify/following{/other_user}","gists_url":"https://api.github.com/users/clayton-shopify/gists{/gist_id}","starred_url":"https://api.github.com/users/clayton-shopify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clayton-shopify/subscriptions","organizations_url":"https://api.github.com/users/clayton-shopify/orgs","repos_url":"https://api.github.com/users/clayton-shopify/repos","events_url":"https://api.github.com/users/clayton-shopify/events{/privacy}","received_events_url":"https://api.github.com/users/clayton-shopify/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-09-14T17:44:15Z","updated_at":"2018-09-14T17:44:15Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"https://hackerone.com/d4nny reported the following issue.\r\n\r\nNote: I believe this is just a functional bug and not a security issue, since mruby does not make any attempt to hide object addresses from the user.\r\n\r\n-----\r\n\r\nIntroduction\r\n============\r\n\r\nProvided PoC shows a info leak in mruby Pack gem. We can use this to leak address of any object/array/string etc\r\n\r\nProof of concept\r\n================\r\n```\r\nclass Vuln\r\n\tdef to_f\r\n\t\tself\r\n\tend\r\nend \r\n\r\nobj = Vuln.new\r\narr = [4.0,2,3]\r\narr[0]=obj\r\n#print the object address for our reference \r\nprint obj\r\nprint \"\\n\"\r\n#leak the object address \r\nprint arr.pack(\"G\").unpack(\"H*\")\r\nprint \"\\n\"\r\n\r\n```\r\n\r\nRoot cause\r\n==========\r\nThe issue is here:\r\nhttps://github.com/mruby/mruby/blob/f93734f6228e541ea4eee5f2dd208981ce6e38bd/mrbgems/mruby-pack/src/pack.c#L1130\r\n```\r\nelse if (type == PACK_TYPE_FLOAT) {\r\nif (!mrb_float_p(o)) {\r\n  o = mrb_funcall(mrb, o, \"to_f\", 0);\r\n}\r\n```\r\n\r\nWhen we are trying to pack an object to float, it checks whether the type is `MRB_TT_FLOAT` by calling `mrb_float_p`. If not the object's `to_f` is called, but the return value is never checked for type. We are abusing this and whatever object is returned, that object's address is packed as float. This can be unpacked into hex values to verify the leak.\r\n\r\nFix/Patch\r\n=========\r\nPatch is trivial. We can check for the return type and raise an exception\r\n```\r\nelse if (type == PACK_TYPE_FLOAT) {\r\nif (!mrb_float_p(o)) {\r\n  o = mrb_funcall(mrb, o, \"to_f\", 0);\r\n  if (!mrb_float_p(o)) {\r\n\tmrb_raise(mrb, E_TYPE_ERROR, \"Cannot convert object to float\");\r\n  }\r\n}\r\n```"}}
{"actor":{"display_login":"clayton-shopify"}}