It's not broken, and it's not Windows-specific. Passing undef for the third arg has a special meaning. This is covered in the first paragraph of the documentation, which refers to the Synopsis for how to achieve what you want.
Note that you have a deadlock potential in your code. While the parent is blocked reading from the child's STDOUT, the child could block trying to write to its STDERR. I strongly discourage the use of this low-level module if you plan on reading from both the child's STDOUT and its STDERR. Instead, try IPC::Run3 or IPC::Run.