Safeguard
Application Security•

CWE-683 Wrong Argument Order in Function Calls: Small Typo, Real Impact

Swapping two arguments is easy to do and easy to miss when the types match. CWE-683 shows how it can bypass access checks and how to catch it.

Safeguard Security Team
2 min read

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:

  1. Add tests for both the allowed and the denied outcome of every access check.
  2. Use named or keyword arguments where the language supports them.
  3. 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.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.