Arkadiusz Milik had a shot saved and Robert Lewandowski sent an effort over as Poland missed two early chances.
Ukraine, who were already out, went close when Andriy Yarmolenko shot wide.
Jakub Blaszczykowski curled in a left-foot shot for the winner after 54 minutes and Poland will now play Switzerland in the last 16 on Saturday.
However, Bartosz Kapustka will miss the match in Saint-Etienne after picking up his second yellow card of the tournament.
Lewandowski concern for Poland
A win by a bigger margin could have seen Poland leapfrog Germany, who beat Northern Ireland, to top the group but they rarely looked like adding to their lead.
And while they will celebrate their progress, they will also have concerns over the form of striker Lewandowski.
He scored 42 goals for Bayern Munich in 2015-16 and was the top scorer in Euro 2016 qualifying with 13 goals.
The 27-year-old was rightly regarded as Poland's key man for the tournament, but has not had a shot on target in his three games so far - and is without a goal or assist in 523 minutes of European Championship finals action since a scoring against Greece at Euro 2012.
Lewandowski should have ended that run early on when he was found by a right-wing cross only to sidefoot wide from eight yards, while he also produced some clever footwork before scuffing a shot wide.
His strike partner Milik did not fare much better, having an early shot saved when through on goal, and he also headed wide later on when he stole in at the near post.
"It will only be a matter of time before Lewandowski and Milik start to score," said Match of the Day pundit Mark Lawrenson. "I don't think you would want to play against them."
WATCH FULL GOALS VIDEO BELOW: