What exactly is a "Format String Vulnerability" in a Windows System, how does it work, and how can I protect against it?
A format string attack, at its simplest, is this:
char buffer[128];
gets(buffer);
printf(buffer);
There's a buffer overflow vulnerability in there as well, but the point is this: you're passing untrusted data (from the user) to printf (or one of its cousins) that uses that argument as a format string.
That is: if the user types in "%s", you've got an information-disclosure vulnerability, because printf will treat the user input as a format string, and will attempt to print the next thing on the stack as a string. It's as if your code said printf("%s");. Since you didn't pass any other arguments to printf, it'll display something arbitrary.
If the user types in "%n", you've got a potential elevation of privilege attack (at least a denial of service attack), because the %n format string causes printf to write the number of characters printed so far to the next location on the stack. Since you didn't give it a place to put this value, it'll write to somewhere arbitrary.
This is all bad, and is one reason why you should be extremely careful when using printf and cousins.
What you should do is this:
printf("%s", buffer);
This means that the user's input is never treated as a format string, so you're safe from that particular attack vector.
In Visual C++, you can use the __Format_string annotation to tell it to validate the arguments to printf. %n is disallowed by default. In GCC, you can use __attribute__(__printf__) for the same thing.
In this pseudo code the user enters some characters to be printed, like "hello"
string s=getUserInput();
write(s)
That works as intended. But since the write can format strings, for example
int i=getUnits();
write("%02d units",i);
outputs: "03 units". What about if the user in the first place wrote "%02d"... since there is no parameters on the stack, something else will be fetched. What that is, and if that is a problem or not depends on the program.
An easy fix is to tell the program to output a string:
write("%s",s);
or use another method that don't try to format the string:
output(s);
a link to wikipedia with more info.
Related
In our code we again and again have the issue that somebody forgot to adapt the usage of placeholders when switching between the use of the logger and String.format(...) methods.
For log statements one has to use '{}' as placeholders, like so:
logger.info("File {} successfully opened: {} bytes read, {} objects created", file, nrBytes, nrObjects);
But when using String.format(...) to compose a message one has to use '%s' as placeholders for strings and the statement has to read:
logger.info(String.format("File %s successfully opened: %s bytes read, %s objects created", file, nrBytes, nrObjects));
The second form is often used, when logging an error where the second argument is the Throwable that one wants to log.
Too often people forget about this details and then we end up with wrong log statements that output nothing reasonable.
I know and agree that this is absolutely not an architecture issue but rather a simple programming error, but it would be great if one could (ab-)use ArchUnit to check for the use of '%s' (or the absence of '{}') in the first String argument of the String.format()-method. Is something like that possible?
The ArchUnit, currently in version 0.16.0, does not analyze parameter values for method calls.
The sonar rule "Printf-style format strings should be used correctly" might however catch these bugs.
As already noted ArchUnit can't do this - PMD's [invalidlogmessageformat][1] rule is useful though (and I find PMD easier to deal with than sonar).
for my $item (#array) {
if (index($item, '$n') != -1) {
print "HELLO\n";
}
}
Problem is: Perl critic gives below policy violation.
String may require interpolation at line 168, near '$item, '$n''. (Severity: 1)
Please advise how do I fix this?
In this case the analyzer either found a bug or is plain wrong in flagging your code.
Are you looking for a literal "$n" in $item, or for what $n variable evaluates to?
If you want to find the literal $n characters then there is nothing wrong with your code
If you expect $item to contain the value stored in $n variable then allow it to be evaluated,
if (index($item, $n) != -1)
If this is indeed the case but $n may also contain yet other escaped sequences or encodings which you need as literal characters (so to suppress their evaluation) then you may need to do a bit more, depending of what exactly may be in that variable.
In case you do need to find characters $ followed by n (what would explain a deliberate act of putting single quotes around a variable) you need to handle the warning.
For the particular policy that is violated see Perl::Critic::Policy::ValuesAndExpressions
This policy warns you if you use single-quotes or q// with a string that has unescaped metacharacters that may need interpolation.
To satisfy the policy you'd need to use double quotes and escape the $, for example qq(\$n). In my opinion this would change the fine original code segment into something strange to look at.
If you end up wanting to simply silence the warning see documentation, in Bending The Rules
A comment. The tool perlcritic is useful but you have to use it right. It's a static code analyzer and it doesn't know what your program is doing, so to say; it can catch bad practices but can't tell you how to write programs. Many of its "policies" are unsuitable for particular code.
The book that it is based on says all this very nicely in its introduction. Use sensibly.
When I look at the question where this comes from it appears that you are looking for index at which substrings were matched, so you need the content of $n variable, not literal "$n". Then perlcritic identified a bug in the code, good return for using it!
Is there a way to prevent the program from executing characters in "Menu" type program where you choose options while running console and enter numbers only to do steps and browse data.
My program is a book catalog where you can review, change, add or delete information.
Things wouldn't be as bad but the the thing is, that when you enter a letter or non-number character the program gets messy and stuck.
I am not adding my code since I think that there should be a universal command to get rid of my problem + it would take some time to translate my code into EN.
The easiest way to do it is use the getline function I think. Instead of using cin >> num; for example, you would use getline(cin,value); where "value" is a string that you first store your input in. Then you can do num = atoi(value.c_str()); to save the string input as an integer value into "num". If "num" is a float, then just use atof instead of atoi. This way if the string is not a number, it just sets the value to 0. You could then use an if statement to display an error message if the value of num == 0. Hope that helps. Good luck!
If your application runs in a console and you are worried about wrong (non-number) input, perhaps you should the input not as a number, but as a text and then parse it to see it is really a number. If not, tell the user the input is incorrect and let them enter it again.
String a = keyboard.nextLine().ignoreUpperCase()
is this a valid line?
It depends on your intention. The code you shared isn't clear about what you intend to do with the line you are reading from the keyboard.
Like it already has been suggested you could, in Java:
String a = keyboard.nextLine().toLowerCase();
or
String a = keyboard.nextLine().toUpperCase();
The intention here is that all lines you are getting are in upper or lower case. Ok if you want to treat all Strings you read from the keyboard as equals regardless of capitalization.
If your real intention is to match strings regardless of case, then the code reads better as:
String a = "Hello World";
a.equalsIgnoreCase("hello world");
now future maintainers of your code will understand what you're trying to do instead of trying to guess why you are converting to lower/upper case.
I have an EditText object (et_travel) on my screen that's asking for miles traveled. I grab that data like this:
float travel = Float.parseFloat(et_travel.getText().toString());
if(travel > 40000){
I just discover that if someone puts 40000 in the EditText, everything works fine, but if they put 40,000 (adding a comma to the number), I force close on the float travel = ...statement.
How can I evaluate the number without having a problem from the user adding a comma?
Is this in Java? It appears to be, but I'm wondering if I'm mistaken. Regardless, I would suggest you remove all of the characters from the string that are not of a numeric type. A way to do this may be using a regular expression.
A way to do this in Java may be the following:
String input = et_travel.getText().toString();
input = input.replaceAll("[^0-9]", "");
float travel = Float.parseFloat(input);
...
This way, you strip anything that is a non-numeric value from the string first, and then attempt to do your work. Obviously do some error checking before this (like input is not null and such). One change that is needed however is that you may need to maintain the '.' character (if you're given non-integer values). This would require changing the first regex a bit.
Check here: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#replaceAll(java.lang.String, java.lang.String)
What you need is some validation on the input. Before converting the string into a float parse the string. If there are any ','s then remove them. If there is just junk then reject the input, otherwise someone could put a word or anything else in the input and cause havoc in your program.
Check out
inputType to restrict user input
android:inputType="number"