By modifying the start of that string, you can begin reading and writing to various parts of the stack.
Whilst implementations may inline that string into a RO memory region - that's not defined behaviour, so you shouldn't depend on it.
[0] https://owasp.org/www-community/attacks/Format_string_attack
In order to modify that string, even in RW pages, the attacker already has to have access, at which point the point is moot. It's like saying "if you can change memory, then you can change memory"....
printf("Hello, World!\n");
really any safer than this? printf("%s\n", "Hello, World!");The article’s author (posting here on HN) is grossly mistaken.
Function isn't everything though. One example shows an awareness of the security issue and good habit being used despite the low impact. I'd argue that there is a security benefit to using one over the other.
Additionally, it's not as simple as saying "if you can change memory, then you can change memory". Memory exploits are quite often chains of small issues these days and not the simple buffer overflow of old.
For example, being able to overwrite one byte somewhere could lead to the ability to change only part of a variable address. That could be used to redirect a write to the constant string in memory.
Sure it's contrived, but scenarios like this do happen.
Yes,
printf("Hello, World!\n");
shows an awareness of the security issue and good habit being used. printf("%s\n", "Hello, World!");
shows that you think "%s\n\0Hello, World!" (or however the compiler decides to lay out those strings) can't be overwritten with "%p%nHello, World!" (or something to that effect), but "Hello, World!\n" somehow can.We've spent the last 20 years cleaning up after the shoddy work of this exact attitude.
And breaking up constants into misordered, mishmashed fragments isn't even a good habit in the first place.
Edit: Come to think of it, given that the original complaint was:
> > printf("Hello, World!\n");
> [...] All this requires is a modification to one string in memory and you have an injection vulnerability.
There's also the fact that it's you who is arguing in bad faith, since a: habit wasn't part of it to begin with, and b: you haven't given any example of a case where a habit of writing `printf("%s\n","<some text>");` rather than `printf("<some text>\n");` is useful for anything whatsoever, security or otherwise.
> Originally thought harmless, format string exploits can be used to crash a program or to execute harmful code.
They are not the same as puts. Puts can allow you to potentially read memory.
A format string attack can allow you to write to memory.
[0] https://en.wikipedia.org/wiki/Uncontrolled_format_string
So their ability to write to a limited range of addresses can be extended to a larger range.
Nothing.
Neither is more secure, all modern compilers put both “%s” and “Hello, world!” in rodata sections.
Your understanding of practical format string attacks is misguided.