|
| 1 | +<!-- Remove Badge if it does not have fix--> |
| 2 | +## Fix Format String Vulnerability <Badge type="tip" text="Has Fix" /> |
| 3 | + |
| 4 | +* [Playground Link](/playground.html#eyJtb2RlIjoiQ29uZmlnIiwibGFuZyI6ImNwcCIsInF1ZXJ5IjoiIiwicmV3cml0ZSI6IiIsInN0cmljdG5lc3MiOiJzbWFydCIsInNlbGVjdG9yIjoiIiwiY29uZmlnIjoiaWQ6IGZpeC1mb3JtYXQtc2VjdXJpdHktZXJyb3Jcbmxhbmd1YWdlOiBDcHBcbnJ1bGU6XG4gIHBhdHRlcm46ICRQUklOVEYoJFMsICRWQVIpXG5jb25zdHJhaW50czpcbiAgUFJJTlRGOiAjIGEgZm9ybWF0IHN0cmluZyBmdW5jdGlvblxuICAgIHsgcmVnZXg6IFwiXnNwcmludGZ8ZnByaW50ZiRcIiB9XG4gIFZBUjogIyBub3QgYSBsaXRlcmFsIHN0cmluZ1xuICAgIG5vdDpcbiAgICAgIGFueTpcbiAgICAgIC0geyBraW5kOiBzdHJpbmdfbGl0ZXJhbCB9XG4gICAgICAtIHsga2luZDogY29uY2F0ZW5hdGVkX3N0cmluZyB9XG5maXg6ICRQUklOVEYoJFMsIFwiJXNcIiwgJFZBUilcbiIsInNvdXJjZSI6Ii8vIEVycm9yXG5mcHJpbnRmKHN0ZGVyciwgb3V0KTtcbnNwcmludGYoJmJ1ZmZlclsyXSwgb2JqLT5UZXh0KTtcbnNwcmludGYoYnVmMSwgVGV4dF9TdHJpbmcoVFhUX1dBSVRJTkdfRk9SX0NPTk5FQ1RJT05TKSk7XG4vLyBPS1xuZnByaW50ZihzdGRlcnIsIFwiJXNcIiwgb3V0KTtcbnNwcmludGYoJmJ1ZmZlclsyXSwgXCIlc1wiLCBvYmotPlRleHQpO1xuc3ByaW50ZihidWYxLCBcIiVzXCIsIFRleHRfU3RyaW5nKFRYVF9XQUlUSU5HX0ZPUl9DT05ORUNUSU9OUykpOyJ9) |
| 5 | + |
| 6 | +### Description |
| 7 | + |
| 8 | +The [Format String exploit](https://owasp.org/www-community/attacks/Format_string_attack) occurs when the submitted data of an input string is evaluated as a command by the application. |
| 9 | + |
| 10 | +For example, using `sprintf(s, var)` can lead to format string vulnerabilities if `var` contains user-controlled data. This can be exploited to execute arbitrary code. By explicitly specifying the format string as `"%s"`, you ensure that `var` is treated as a string, mitigating this risk. |
| 11 | + |
| 12 | +<!-- Use YAML in the example. Delete this section if use pattern. --> |
| 13 | +### YAML |
| 14 | +```yaml |
| 15 | +id: fix-format-security-error |
| 16 | +language: Cpp |
| 17 | +rule: |
| 18 | + pattern: $PRINTF($S, $VAR) |
| 19 | +constraints: |
| 20 | + PRINTF: # a format string function |
| 21 | + { regex: "^sprintf|fprintf$" } |
| 22 | + VAR: # not a literal string |
| 23 | + not: |
| 24 | + any: |
| 25 | + - { kind: string_literal } |
| 26 | + - { kind: concatenated_string } |
| 27 | +fix: $PRINTF($S, "%s", $VAR) |
| 28 | +``` |
| 29 | +
|
| 30 | +### Example |
| 31 | +
|
| 32 | +<!-- highlight matched code in curly-brace {lineNum} --> |
| 33 | +```cpp {2-4} |
| 34 | +// Error |
| 35 | +fprintf(stderr, out); |
| 36 | +sprintf(&buffer[2], obj->Text); |
| 37 | +sprintf(buf1, Text_String(TXT_WAITING_FOR_CONNECTIONS)); |
| 38 | +// OK |
| 39 | +fprintf(stderr, "%s", out); |
| 40 | +sprintf(&buffer[2], "%s", obj->Text); |
| 41 | +sprintf(buf1, "%s", Text_String(TXT_WAITING_FOR_CONNECTIONS)); |
| 42 | +``` |
| 43 | + |
| 44 | +### Diff |
| 45 | +<!-- use // [!code --] and // [!code ++] to annotate diff --> |
| 46 | +```js |
| 47 | +// Error |
| 48 | +fprintf(stderr, out); // [!code --] |
| 49 | +fprintf(stderr, "%s", out); // [!code ++] |
| 50 | +sprintf(&buffer[2], obj->Text); // [!code --] |
| 51 | +sprintf(&buffer[2], "%s", obj->Text); // [!code ++] |
| 52 | +sprintf(buf1, Text_String(TXT_WAITING_FOR_CONNECTIONS)); // [!code --] |
| 53 | +sprintf(buf1, "%s", Text_String(TXT_WAITING_FOR_CONNECTIONS)); // [!code ++] |
| 54 | +// OK |
| 55 | +fprintf(stderr, "%s", out); |
| 56 | +sprintf(&buffer[2], "%s", obj->Text); |
| 57 | +sprintf(buf1, "%s", Text_String(TXT_WAITING_FOR_CONNECTIONS)); |
| 58 | +``` |
| 59 | + |
| 60 | +### Contributed by |
| 61 | +[xiaoxiangmoe](https://github.com/xiaoxiangmoe) |
0 commit comments