37-year-old Adam Wainwright overcame a career-high seven walks to pitch eight shutout innings, leading his team to a three-game sweep of its NL Central rival.
Wainwright walked two of the game's first three batters before wriggling out of the jam by getting Javier Baez to ground into an inning-ending double play, one of three for the Cardinals.
The Cardinals got just four hits in their fourth straight win.
Chicago was limited to three hits, and lost for the sixth time in seven games.
Wainwright (5-5) didn't allow a hit until Kris Bryant singled with one out in the sixth. He gave up two hits and struck out eight while throwing 126 pitches.
Chicago starter Cole Hamels (4-2) gave up one unearned run on two hits over seven innings. He struck out four and walked two.
The Cubs, who swept a three-game series from the Cardinals at Wrigley Field in early May, put runners at the corners with one out in the ninth against Jordan Hicks.
John Gant relieved, retired Addison Russell on an RBI grounder and got David Bote to ground out for his third save in four chances.
The Cardinals took a 1-0 lead when Jedd Gyorko walked with one out in the fifth, stole second and went to third on an errant throw by catcher Willson Contreras. Kolten Wong, who had two hits, had a sacrifice fly.
Wong, playing second base, made a nice, over-the-shoulder catch of Anthony Rizzo's looper with two on to end the eighth.
Pinch-hitter Matt Carpenter added a two-out, RBI single off Mike Montgomery in the Cardinals eighth.
Jon Lester (3-4, 3.59) will face Los Angeles Angels RHP Trevor Cahill (2-5, 6.92) on Monday afternoon in Chicago. The game is the makeup of a contest that was postponed by snow on April 14. Lester allowed a season-high seven earned runs in 4 2/3 innings of a 9-6 loss to Houston on Tuesday. Lester is 0-3 with a 10.29 ERA over his last three starts.
Genesis Cabrera (0-1, 7.36) will face RHP Luis Castillo (5-1, 2.45) in the first of a three-game set against Cincinnati on Tuesday. Cabrera gave up three earned runs on five hits over 3 2/3 innings in his major league debut on Wednesday.
>>Sox Blank Indians
Lucas Giolito pitched five-hit ball into the eighth inning and Tim Anderson homered, lifting the Chicago White Sox to a 2-0 victory over the Cleveland Indians on Sunday.
Giolito (8-1) struck out nine and walked none while improving to 6-0 with a 1.03 ERA in his last six starts. He hasn't lost in almost two months.
Aaron Bummer got two outs in the eighth and Alex Colome finished for his 12th save in 12 chances.
Anderson led off the fourth with a drive to left-center for his ninth homer. He also doubled in Yolmer Sanchez with two out in the eighth, helping Chicago close out a 6-1 homestand.
Francisco Lindor had three of Cleveland's six hits. He led off the ninth with a double to left, but Colome retired the next three batters.
The Indians wasted a strong performance by Zach Plesac (0-1), who allowed four hits in seven innings in his second start in the majors.
The right-hander is the nephew of former major league reliever Dan Plesac, who pitched for six teams in 18 seasons.
The closest thing the Indians had to a rally came in the fifth when Greg Allen doubled down the right-field line with one out. Roberto Perez then lifted a drive to right-center in a bid for another extra-base hit, but Leury Garcia made a nice running catch on the warning track.
Giolito exited after Perez singled with one out in the eighth. Bummer came on and induced pinch hitter Jordan Luplow to bounce into an inning-ending double play.
Yoan Moncada was held out of the lineup to give him two days of rest with Monday's day off.
Reynaldo Lopez (3-5, 6.20 ERA) faces his former team Tuesday night in the opener of a two-game series at Washington. RHP Stephen Strasburg (5-3, 3.19 ERA) pitches for the Nationals.