Zenit and Lyon are on seven points apiece heading into the final matchday thanks to a precision headed finish from powerhouse forward Artem Dzyuba in the 42nd minute and a late deflected Magomed Ozdoev strike.
Lyon enjoyed the lion's share of possession, controlling the action for long periods, but lacked a cutting edge in the injury absence of Netherlands star Memphis Depay.
Sergei Semak's men responded well to consecutive defeats at the hands of Group G leaders RB Leipzig to move above their Ligue 1 opponents into the second qualifying spot by virtue of a superior head-to-head record.
Both teams had bright moments during the opening half hour but Lyon had the greater control and almost led in the 23rd minute – Zenit goalkeeper Mikhail Kerzhakov plunging bravely to prevent Ozdoev from turning Bertrand Traore's cross into his own net.
The hosts came close when Sardar Azmoun got to Daler Kuzyaev's chipped pass ahead of Lyon keeper Anthony Lopes and the bouncing ball came back off the left post.
Azmoun's towering striker partner Dzyuba found the breakthrough three minutes before the break, expertly directing Douglas Santos' corner past the despairing Lopes.
Moussa Dembele headed just wide as the hour approached, as Lyon forced their opponents on to the retreat.
Lopes leapt theatrically to gather a speculative Sebastian Driussi strike after Lyon again failed to deal with a set piece, but the threat from Zenit was increasingly sporadic.
Nevertheless, one of those raids six minutes from time was enough to seal the points as Ozdoev's deflected drive from substitute Yuri Zhirkov's lay-off left Lopes with no chance.
What does it mean? All to play for on matchday six
Zenit will remain ahead of Lyon if they match the latter's result in Leipzig when they travel to Benfica, with other permutations to be decided once Group G's first and last sides clash later on Wednesday.
Dominant Dzyuba proves decisive
A throwback centre-forward unlikely to win any marks for artistic impression, Russia international Dzyuba is a handful for any defence and Lyon never looked comfortable in his presence.
The 31-year-old's little-and-large partnership with Azmoun will always pose questions and his finish was one any classic number nine would be proud of.
Cornet fails to hit the right notes
Goals home and away against Manchester City last season served notice of Maxwel Cornet's pedigree at this level, but the Lyon winger remains a frustratingly inconsistent performer. He was too often on the margins in St Petersburg, failing to play his part in terms of filling the Memphis void.
Zenit return to their own patch on Sunday to host Spartak Moscow in the Russian Premier League, while Lyon will have to regroup in time for a Ligue 1 trip to Strasbourg.