The International Monetary Fund's (IMF) representative in Afghanistan and four United Nations staff were among the dead, who included 13 foreign nationals, police said.
Islamist Taliban insurgents claimed responsibility for the attack on a Lebanese restaurant in the capital's central Wazir Akbar Khan district, which hosts many embassies and restaurants catering for expatriates.
"Such targeted attacks against civilians are completely unacceptable and are in flagrant breach of international humanitarian law," U.N. spokesman Farhan Haq said. "They must stop immediately."
The stutter of gunshots rattled the district for several minutes after the blast around 7.30 p.m., a busy dining time when expatriates in Kabul tend to eat out.
One of the survivors, Suleiman, who worked as a cook at the restaurant, said he escaped from the gunmen after hearing the explosion outside.
"I went to the roof and stayed with my back to the chimney for two or three hours. Later Afghan police came and took me out."
A clearance operation continued for several hours after the attack as until midnight police were still unsure whether more bombers might be lurking in the dark, dusty streets.
IMF representative Wabel Abdallah, a 60-year-old Lebanese national, was killed in the explosion, the IMF said. He had been leading the Fund's office in Kabul since 2008.
"This is tragic news, and we at the Fund are all devastated," Managing Director Christine Lagarde said in a statement. "Our hearts go out to Wabel's family and friends, as well as the other victims of this attack."
Security sources said other victims included civilians from Europe, Britain and Russia.
Canadian Foreign Affairs Minister John Baird said two Canadians died in the attack but it was not clear if this figure was in addition to the deaths reported by the IMF and United Nations.
State Department spokeswoman Jen Psaki said none of the dead included U.S. Embassy staff in Kabul.
After the explosion, two gunmen stormed into the restaurant and started shooting at diners, security sources said, adding that foreign casualties had been taken to an international military camp in eastern Kabul.
Outside a morgue at a nearby hospital, Afghans screamed and cried as they mourned attack victims, some pressing scarves to their faces to stifle sobs. One young man, grieving for his dead father, kicked a wall and howled.
"One of the restaurant's cooks was injured," said a doctor, Abdul Bashir. "Two dead bodies have been taken to the morgue."
A Taliban spokesman said on Twitter that the attack was revenge for an airstrike that had killed civilians in Parwan province this week.
Afghanistan's President Hamid Karzai, who quickly condemned the reported deaths of eight civilians, had not made a statement by Saturday morning.
The attack came as most foreign forces prepare to leave Afghanistan this year after more than a decade of war and almost daily attacks.
Security concerns have been rising ahead of an April presidential election when Afghans will choose a successor to President Hamid Karzai, an event likely to be targeted by the Taliban insurgents.
Security remains a major concern as Afghanistan and the United States struggle to agree on a key bilateral security pact, raising the prospect that Washington may yet pull out all of its troops this year unless differences are ironed out.
Two years ago, the United States ended its military mission in Iraq with a similar "zero option" after the failure of talks with Baghdad.
Karzai is still deliberating whether to allow some U.S. troops to stay to help his nation regain calm and stability after years of conflict. If no agreement is reached, Afghan forces would be left to fight the insurgents on their own.