# Denial of service due to invalid memory access in mrb_ary_concat

Malformed mruby source with `*case` splat in a method call/assignment reaches mrb_ary_concat with a non-array self, causing invalid memory access and segfault in mruby and mruby-engine.

- Payout: $8,000
- Severity: high
- Program: shopify-scripts
- Credited: haquaman
- Disclosed: 2016-12-17
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/184712
- Library page: https://bugbountylibrary.com/r/h1%3A184712
- Tags: domain:oss impact:dos kind:bounty platform:hackerone sev:high tech:ruby technique:fuzzing technique:source-review vuln:dos vuln:memory-corruption

**Target:** mruby interpreter / mruby-engine sandbox (mrb_ary_concat)
**Root cause:** mrb_ary_concat assumes both self and other are arrays and calls mrb_ary_ptr without type checks; the compiler emits a concat opcode with a non-array operand for the malformed `*case` splat, leading to invalid memory access in ary_modify.
**Steps:**
1. Save `case ""\n when 0\nend\nx *case\n when true\n  * = 0\nend` to crash-1.rb
2. Run `./dev/bin/mruby crash-1.rb` -> segfault in ary_modify via mrb_ary_concat
3. Variant: `x = *case\n when 0\n  * = 0\nend` also segfaults
4. Load same script via mruby-engine sandbox_eval -> Ruby [BUG] segfault in mrb_ary_concat
5. Patch mrb_ary_concat to mrb_raisef E_TYPE_ERROR when !mrb_array_p(self) or !mrb_array_p(other)
**How found:** Fuzzing mruby with malformed syntax; minimized crashing inputs to a `*case` splat construct, then used lldb backtrace to pinpoint ary_modify/mrb_ary_concat and read src/array.c to derive a type-check patch.
**Exploitation:** Attacker submits crafted mruby script to a service embedding mruby-engine (e.g. Shopify Scripts); the sandbox process segfaults, denying service.
**Insight:** Splat/argument-prefix parsing edge cases (`*case`, `x *case`) can emit concat opcodes with non-array operands; fuzz grammar corner cases around splat and case, and audit C API entry points like mrb_ary_concat that trust caller types.
