There is, though; malloc's specification forms a contract. You are not allowed to access outside the bounds of the returned pointer. That some hardware allows it sometimes does not mean that there is "zero contract".
The function represents an interface, and an interface is a set of rules and behavior both the user & consumer of that interface expect. If you stray from that, it's UB, and the machine can do whatever at that point.
In this case, that's what matters. We don't know what hardware malloc or mmap will run on, and it isn't impossible that someone could implement a malloc() implementation that did enforce those bounds. valgrind, for example, is very close to this: it already knows when you access memory outside of the bounds of a malloc'd region (as that's its purpose: to report such accesses), and it would be a trivial modification to it to kill the program on an illegal access.
So when ever `malloc` gives you 50bytes without allocating an entire page it's just lying to you and giving you a pointer offset from another allocation. This isn't strictly being enforced by anything. There is zero contract that enforces what memory you can/cannot use.