According to an article I just read, the functions printf and strcpy are considered security vulnerabilities due to Buffer overflows. I understand how strcpy is vulnerable, but could someone possibly explain how/if printf is really vulnerable, or I am just understanding it wrong.

Here is the article: https://www.digitalbond.com/blog/2012/09/06/100000-vulnerabilities/#more-11658

The specific snippet is :

The vendor had mechanically searched the source code and found some 50,000-odd uses of buffer-overflow-capable C library functions such as “strcpy()” and “printf().”


  • 2
    If you are interested in this topics I suggest you to read Hacking: The Art of Exploitation by Jon Erickson. Chapter three contains a working exploit using the format string vulnerability of printf. – Bakuriu Oct 9 '13 at 20:07
  • Sure I understand the format string vulnerabilities, from what I've read at least. However, I was under the impression that the function itself was somehow exploitable (even if it was used as intended). – DarkMantis Oct 9 '13 at 20:58
  • 5
    Seen another way, C/C++ itself is a buffer overflow vulnerability. All that direct toying with memory... – LateralFractal Oct 10 '13 at 2:05
  • I have faced similar situation for integer buffer where I can't access main() function in C. I am searching for an answer (stackoverflow.com/questions/61715941/…) – Tajuddin Khandaker May 10 '20 at 17:28

It is possible to have issues with printf(), by using as format string a user-provided argument, i.e. printf(arg) instead of printf("%s", arg). I have seen it done way too often. Since the caller did not push extra arguments, a string with some spurious % specifiers can be used to read whatever is on the stack, and with %n some values can be written to memory (%n means: "the next argument is an int *; go write there the number of characters emitted so far).

However, I find it more plausible that the article you quote contains a simple typographical mistake, and really means sprintf(), not printf().

(I could also argue that apart from gets(), there is no inherently vulnerable C function; only functions which need to be used with care. The so-called "safe" replacements like snprintf() don't actually solve the problem; they hide it by replacing a buffer overflow with a silent truncation, which is less noisy but not necessarily better.)

  • 1
    I've even seen argued (with some merit) that gets is not inherently vulnerable either. For example, if a program calls gets to read back data that it wrote, it may be guaranteed that the data fits in the buffer. For a file this is not robust but may be correct; for a self-pipe it could even be robust. – Gilles 'SO- stop being evil' Oct 9 '13 at 18:37
  • 3
    Slightly off-topic, but I do not agree at all with your comment regarding snprintf: it is difficult to use sprintf in a secure manner (and practically impossible if you use a %s format specifier), but snprintf, when used correctly, is safe: when snprintf truncates the input, because its size exceeds the buffer, it is not silent but tells you by giving a return value equal to the buffer size. – AardvarkSoup Oct 10 '13 at 11:10

In addition to the answer by @Tom, I would also like to guide you to the OWASP code review guidelines, where some issues on using printf() are highlighted and this answer to a similar question on cs.stackexchange website.

  • +1 for OWASP reference, learned about something new & interesting :) – polynomial_donut Aug 15 '18 at 22:47

Here is an example that shows how this overflow can help you. Imagine you don't have access to the private members (pwd for example) so printf will help you see the content of this variable

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

struct SecureLogin{
    SecureLogin(const char * login_)
        strcpy(pwd,"ijk");//the user does not see this part of the source code as it is in a DLL
    char login[8];
    char pwd[8];


int main() {
    // your code goes here
    SecureLogin log("abc");
    printf("Pwd = %s\n",(&log.login[0])+8);
    // Pass a string address which is the base address of the login
    // field, but add 8 bytes, which skips onto the pwd field (we know
    // login is 8 bytes)
    return 0;


Pwd = ijk


Some printf directives (ie; %n) have side effects to addresses found on the stack, so print directives can be dangerous, even if the explicit output is implemented correctly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.