Just so we're on the same page, you should have stated the method you're talking about—something like (rewritten from link) (disclaimer: none of the code in this answer has been tested):
vec3 diff_dir = normalize( normal + rand_unit_vec() );
vec3 mirr_dir = reflect( ray_in, normal );
vec3 spec_dir = normalize(mix( mirr_dir,diff_dir, roughness ));
vec3 ray_out = mix( diff_dir,spec_dir, specular_enabled );
Fundamentally, your question is how you can cheaply remove directional "bias" from this.
The reason there's bias here should be apparent from what the code is doing—it's blending the specular reflection with the diffuse reflection—the diffuse reflection being random and in the upper hemisphere, and the specular reflection being the mirror direction.
The effect is that the specular gets blurred, but the diffuse being in only the upper hemisphere also pulls the result upward. They probably did it this way because it prevents having to check that the specular direction is above the plane.
A simple way to change that would be to do something else. E.g. maybe instead calculate
vec3 mirr_dir=reflect( ray_in, normal ), spec_dir;
spec_dir = normalize( mirr_dir + roughness*rand_unit_vec() );
} while ( dot(spec_dir,normal) < 0.0 );
That'll do a "fuzzy" specular reflection that's centered around the reflection direction and clipped (with rejection sampling) against the plane.
However, I do not recommend you do this.
First, a good specular BRDF should have this sort of biased-upward behavior, so this is a feature, not a bug. A more familiar but still basic example will be the Phong BRDF (which is centered around the reflection direction) and the Blinn–Phong BRDF (which has more upward bias). Although both BRDFs are obsolete for production purposes, the Blinn–Phong BRDF is widely considered to be superior for this biasing behavior—it leads to important perceptual effects like smearing out highlights lengthwise at glancing angles (see e.g. "Crafting Physically Motivated Shading Models for Game Development" for discussion and examples).
Second and more fundamentally, this is this is not a proper BRDF anyway and messing with its shape is not productive. It was broken before you started. Sampling the diffuse ray like this will not give you (e.g.) Lambertian, and this specular distribution is a poorly concealed blurred mirror. You would be much better with a microfacet model like you were thinking of doing—and it's not even that much more difficult to implement! Please just do that instead.