Containers isolate an application on a shared OS, VM's isolate an OS on shared hardware. With those different levels of abstraction, you have different exploits and protections.
A successful kernel level exploit on a container will affect the shared kernel, and therefore breakout of the container isolation. Think meltdown and spectre.
A successful VM driver exploit could break out of the VM to the hypervisor running the VM's. I've heard of exploits on things like the floppy driver in VMs. These are much more rare than kernel exploits, so I'd give the advantage to VM's here.
It is possible to change the container runtime to spin up containers in small VM's. Projects like Kata Containers are working on this. So you could get the security of VM's while still getting some of the features of containers.
Containers do have a huge different advantage over VM's. They run in a minimal environment with reduced capabilities, seccomp, and optionally selinux/apparmor configured. You can lock down that environment in ways you couldn't easily lock down a VM, with a read-only filesystem, and not including any of the tools like shells, interpreters, and libraries that an attacker may need to exploit your system to try attacking the kernel or horizontally pivot their attack.
As a result, there's no clear winner. The best answer is likely a combination of both, running a handful of containers with similar security requirements on their own VM.