CWE-683, Function Call With Incorrect Order of Arguments, describes a caller that passes the right values to a function but in the wrong order. MITRE notes the problem typically starts as a typo or a copy and paste error during implementation.
Some compilers catch it. Many cannot, especially when two parameters have the same type, when the function takes a variable number or type of arguments such as C format strings, or in languages without strong typing.
How it happens
MITRE's observed example is CVE-2006-7049: an application calls functions with arguments in the wrong order, allowing an attacker to bypass intended access restrictions.
Here is an illustration of how the swap hides in plain sight:
def can_access(user_id, resource_id):
return user_id in acl.get(resource_id, set())
# Caller has the arguments reversed. Both are strings, so nothing complains.
if can_access(resource.id, current_user.id):
serve(resource)
Both values are strings, so no type checker objects. The check now looks up the wrong thing, and the result no longer means what the surrounding code assumes.
What an attacker gains
MITRE records the consequence as quality degradation, meaning the product behaves incorrectly. The security impact depends entirely on what the function decides. When it guards access, as in the CVE above, wrong behavior means a bypass.
How to find it
MITRE says this flaw often produces visibly incorrect behavior, so it is usually found in testing or normal operation. Exercising all control paths will typically expose it, except in rare cases where the swapped call happens to give the correct result anyway. That exception matters for security checks, where a swapped call that is "mostly right" can hide for years.
How to fix it
MITRE's mitigation is blunt: use the function as specified. To make that easier:
- Add tests for both the allowed and the denied outcome of every access check.
- Use named or keyword arguments where the language supports them.
- Use distinct types for distinct things, such as a UserId and a ResourceId, so a swap fails to compile or type check.
if can_access(user_id=current_user.id, resource_id=resource.id):
serve(resource)
Quick check
Why do same-typed parameters make this bug likelier?
Because the compiler or type checker sees nothing wrong with a swap when both values have the same type.