Luis Gonzalez had opened the scoring in the 41st minute for Vitor Pereira's side, who remain unbeaten in all competitions in a run stretching back to a League Cup defeat at Benfica in March.
Despite an early blocked effort from Zagreb's Duje Cop, Porto took control from the start at the Stadion Maksimir on Tuesday, pressing the home defence with a series of set-pieces which were booted clear from deep in their own box.
James Rodriguez flashed a long-range shot just wide before Zagreb had their first chance, Jorge Sammir getting on the end of Arijan Ademi's free-kick but having his shot blocked by Roque Maicon.
Cop fired just wide as the hosts gained in confidence, but clear-cut chances were not easy to come by for either side until Gonzalez struck in the 41st minute, firing home low from the centre of the box.
Porto pressed for a second and almost got it just before the hour when Adrian Calello fouled Joao Moutinho and from the resulting free-kick, Moutinho sent a 25-yard drive over the bar.
A mistake from Porto keeper Da Silva Helton almost helped Zagreb back into it in the 62nd minute when he spilled a Sammir corner only to recover to save Antonio Tonel's acrobatic overhead kick.
Helton saved a 20-yard shot from Cop two minutes later before the action swung to the other end where home keeper Ivan Kelava tipped a Rodriguez shot over the bar, then held a header from Nicolas Otamendi.
Domagoj Vida should have done better with a header from Sammir's corner in the 69th minute, and Bryan Carrasco had a point-blank effort superbly tipped round the post by Helton eight minutes later.
Kelava saved brilliantly from Atsu at the other end but he was stranded for Porto's second deep into injury time, when Atsu found Defour to lob the ball home from 12 yards from the centre of the box.