Safeguard
Application Security•

CWE-1287 Improper Validation of Specified Type of Input

An ID that should be a number, a digest that should be a hash. When the type is assumed rather than checked, injection and path traversal follow.

Safeguard Security Team
4 min read

CWE-1287 covers input that is expected to be of a certain type, where the product does not validate or incorrectly validates that it is. It appears in type-unsafe languages and in any language that supports casting or converting input from one type to another.

How it happens

MITRE explains that when input does not match the expected type, attackers can trigger unexpected errors, cause incorrect actions, or exploit latent vulnerabilities that would not be reachable if the input had conformed.

The common form is a value that is supposed to be one kind of thing and arrives as another. A field expected to be numeric arrives as text containing SQL. A digest expected to be a hex hash arrives as a path.

Two recorded cases:

  • CVE-2024-37032: a large language model management tool does not validate the format of a digest value (CWE-1287) from a private, untrusted model registry, enabling relative path traversal (CWE-23). It is known as Probllama.
  • CVE-2008-2223: SQL injection through an ID that was supposed to be numeric.

Vulnerable and fixed

# Vulnerable: id is assumed to be numeric but is never checked
def get_user(cursor, user_id):
    cursor.execute("SELECT * FROM users WHERE id = " + user_id)
    return cursor.fetchone()

Check the type, then use a parameterized query:

# Safer: enforce the type and bind the value
def get_user(cursor, user_id):
    try:
        uid = int(user_id)
    except (TypeError, ValueError):
        raise ValueError("id must be an integer")
    cursor.execute("SELECT * FROM users WHERE id = %s", (uid,))
    return cursor.fetchone()

Both steps matter. The type check stops bad input early and the bound parameter stops injection if a check is ever missed.

A digest should look like a digest before it is used in a path:

import re

HEX_DIGEST = re.compile(r"^[0-9a-f]{64}$")

def blob_path(base, digest):
    if not HEX_DIGEST.fullmatch(digest):
        raise ValueError("invalid digest")
    return f"{base}/{digest}"

The 64 character length here is for a SHA-256 style value. Use the format your own system defines.

What an attacker gains

MITRE tags the consequences as varying by context. The recorded cases show SQL injection and path traversal, each of which can lead to data theft, data change or access to files outside the intended directory.

How to find it

The record lists no detection methods. Some practical checks:

  1. Identify every value that you treat as an ID, quantity, digest, date or enum, and note where its type is enforced.
  2. Send the wrong type on purpose: text for numbers, arrays for strings, objects where scalars belong, strings with path separators where hashes belong.
  3. Review dynamic languages and loosely typed JSON handling, where a type can change silently between request and use.
  4. Look at data you pull from external registries, partners and package sources, not just direct user input. The Probllama case came from an untrusted registry.

How to fix it

The record offers no mitigation text. The steps follow from the definition.

  1. Declare the expected type and format of each input in one place, such as a schema.
  2. Validate against that schema at the boundary and reject mismatches.
  3. Use strict parsing and typed models rather than permissive casting.
  4. Treat external sources of metadata as untrusted even when you chose to connect to them.
  5. Pair type checks with safe APIs such as parameterized queries and path joins that confine to a base directory.
  6. Keep third party tools current. Probllama is a flaw in a tool you may run in your own stack. The free in-browser dependency scan checks up to 100 dependencies without login, and reachability analysis shows whether your code calls the vulnerable function.

Try it yourself

Knowing which of your packages contain a flaw like this starts with an inventory. The demo shows how a dependency inventory is built.

Click through it at your own pace, or open it full screen.

Quick check

How can a missing type check lead to path traversal?

If a value expected to be a hash or digest is used to build a file path, a value containing path segments can point outside the intended directory. That is the Probllama pattern.

Why use a parameterized query if you already checked the type?

Defense in depth. If a type check is missed on one path, the bound parameter still prevents the value from being treated as SQL.

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.