CWE-303 applies when requirements call for an established authentication algorithm, but the implementation of that algorithm is incorrect. MITRE notes that the flaw may allow authentication to be bypassed.
It is a reminder that "we use a standard method" and "we use it correctly" are different statements.
How it happens
Authentication code is full of small decisions: compare these two values, reject if either check fails, stop at the first error. A slip in any of them changes the outcome without making the code look wrong.
MITRE's observed example is short and instructive. In CVE-2003-0750, a conditional should have been an "or" and instead was an "and". A check meant to fail if either condition was bad now failed only if both were.
# Intended: reject if the signature is bad OR the token is expired
# Bug: AND means a bad signature alone is accepted
if not signature_valid and token_expired:
reject()
Other ways to get the implementation wrong include hand-writing a protocol from a description, skipping a verification step, and using a library function with the wrong arguments.
What an attacker gains
The listed consequence is bypass of the protection mechanism, meaning access without valid credentials.
How to find it
MITRE gives no detection methods for this entry. These work in practice:
- Write negative tests. For each authentication rule, build an input that violates only that rule and assert that it is rejected.
- Use known-answer test vectors from the algorithm's specification.
- Have a second person review the logic with the specification open.
How to fix it
- Use a maintained, widely reviewed library for the algorithm rather than writing it yourself.
- Follow the specification step by step, and keep the steps visible in code, one check per step.
- Fail closed: authentication succeeds only when every required check passes.
- Keep the library updated, since flaws in authentication code are fixed by upgrades.
Quick check
What made CVE-2003-0750 possible?
A conditional used the wrong logical operator, so a check that should have rejected on either failure rejected only on both.