Safeguard
Application Security•

ASVS 5.0 V1.3.10: Keep User Input Out of Format Strings

ASVS V1.3.10 requires sanitizing format strings that may resolve in unexpected ways. See safe printf, str.format and logging patterns and a quick test.

Safeguard Security Team
2 min read

ASVS 5.0 V1.3.10 (Level 2) requires that format strings which might resolve in an unexpected or malicious way are sanitized before processing. The simple rule: user input is an argument to a format function, never the format string itself.

Why it matters

In C, printf(user_input) lets an attacker read stack memory with %x and write with %n. In Python, user_input.format(obj) lets a template like {0.__class__.__init__.__globals__} walk object attributes and leak secrets. Java's String.format can throw on a stray % and leak details through the error.

How to implement it

Fix the format, pass data as arguments:

printf("%s", user_input);          /* not printf(user_input) */
msg = "Hello, {}".format(name)      # name is an argument
# never: name_template.format(user_obj) where name_template came from a user

If users must supply a template with placeholders, use a restricted engine such as string.Template, which only substitutes simple names, and pass a dictionary with plain values. Enable compiler warnings for non literal format strings (-Wformat-security in GCC and Clang).

How to test it

Submit %s%s%s%s, %x, %n and {0.__class__} in every field that reaches logging, messages or formatting. The output must show the text unchanged. Run your compiler with format warnings turned into errors.

Common mistakes

  • Passing a user value as the first argument of a logging call.
  • Using f strings or format on text that came from configuration users can edit.
  • Ignoring compiler warnings about non literal formats.

Where this goes wrong in practice

The bug often arrives through logging helpers. A developer writes logger.error(message) where message includes request data, and the logging library treats a percent sign as a placeholder. In C and C++ the consequence is memory disclosure or corruption. In managed languages the usual damage is an exception that hides the real log entry, or leaked object data when a template language is involved. Make a habit of passing a constant format and variables, in every language, and let the linter enforce it.

Quick check

What is the safe call for printing user text in C?

printf("%s", text). The format is a constant and the user text is an argument.

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.