The bill was passed hours after President Hamid Karzai returned to parliament the original version that proposed a blanket amnesty.
Parliament passed the original bill last month despite calls by rights groups for war-crimes trials.
Karzai returned it to lawmakers today, saying that individuals had a right to seek justice.
Last month, thousands of former mujahedin fighters and their supporters gathered at a stadium in Kabul in support of the legislation. The stadium, which holds about 25,000 people, reportedly was filled to capacity for the rally.
Human rights groups and the UN Assistance Mission in Afghanistan said such a bill did not protect alleged war criminals from prosecution under international law.
It was not immediately clear when the revised bill would go to the upper house or be signed by Karzai.