An Azure networking service that is used to provision private networks and optionally to connect to on-premises datacenters.
A good practice is to create 1 NSG per subnet. Then use application security groups (ASGs) to logically define/group VMs. In each NSG create the rules that should define what traffic is allowed.
Be aware that a default low priority rule allows traffic from "Virtual Network": that is the virtual network AND all other "connected" (routed) networks. That means that the default DenyAll rule won't block traffic between the subnets. The only way to get what you want is to define your own low priority Deny rule. I typically have a Deny from * on * to * rule on 4000 in every NSG, and then define all desired flows into/inside the subnet in the NSG rules.
If you look at effective routes in an Azre NIC resource, you'll see why your 0.0.0.0/0 route didn't apply. A more "accurate" (bitmap) route to the prefix of your VNet applied. Remember that in a s/w-defined network, traffic routes from A-B directly by default. The next hop was your destination VM. Of course, you could force the traffic to the prefix of another subnet via the firewall - if you really wanted to. That will require a more accurate UDR in addition to your 0.0.0.0/0 route.