Java: Add additional taint steps for java.lang.String methods#10092
Conversation
Click to show differences in coveragejavaGenerated file changes for java
- Java Standard Library,``java.*``,3,572,130,28,,,7,,,10
+ Java Standard Library,``java.*``,3,580,130,28,,,7,,,10
- Totals,,217,6433,1474,117,6,10,107,33,1,84
+ Totals,,217,6441,1474,117,6,10,107,33,1,84
- java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
+ java.lang,13,,66,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,54,12 |
cb70ab4 to
119c708
Compare
Click to show differences in coveragejavaGenerated file changes for java
- Java Standard Library,``java.*``,3,572,130,28,,,7,,,10
+ Java Standard Library,``java.*``,3,580,130,28,,,7,,,10
- Totals,,217,6433,1474,117,6,10,107,33,1,84
+ Totals,,217,6441,1474,117,6,10,107,33,1,84
- java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
+ java.lang,13,,66,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,54,12 |
Click to show differences in coveragejavaGenerated file changes for java
- Java Standard Library,``java.*``,3,572,130,28,,,7,,,10
+ Java Standard Library,``java.*``,3,580,130,28,,,7,,,10
- Totals,,217,6433,1474,117,6,10,107,33,1,84
+ Totals,,217,6441,1474,117,6,10,107,33,1,84
- java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
+ java.lang,13,,66,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,54,12 |
|
@aschackmull @atorralba As discussed. I did not yet add any release notes, as I want to get some feedback from you before I do any further work on this. I recommend commit-by-commit review. |
Click to show differences in coveragejavaGenerated file changes for java
- Java Standard Library,``java.*``,3,572,130,28,,,7,,,10
+ Java Standard Library,``java.*``,3,580,130,28,,,7,,,10
- Totals,,217,6433,1474,117,6,10,107,33,1,84
+ Totals,,217,6441,1474,117,6,10,107,33,1,84
- java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
+ java.lang,13,,66,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,54,12 |
|
After initial investigation:
I have a feeling that those changes will change our results on several projects. So perhaps it would be wise to further test this. Do we have a larger-scale test harness? |
It is.
In this specific case, it seems that the single quote replacement makes the statement safe from further injections (although the logged query that is inserted in the database is already injectable, so it doesn't matter much). I think it's acceptable to have FP like this, because they are very context-dependent. In general, using
You're discarding any string that uses any negative regex to make a replacement, which I think is a little too generous. Normally, response splitting is sanitized by removing carriage return ( Also, instead of |
|
Wonderful, thanks for the feedback! I'll incorporate those suggestions tomorrow and add a release note. |
Click to show differences in coveragejavaGenerated file changes for java
- Java Standard Library,``java.*``,3,572,130,28,,,7,,,10
+ Java Standard Library,``java.*``,3,580,130,28,,,7,,,10
- Totals,,217,6433,1474,117,6,10,107,33,1,84
+ Totals,,217,6441,1474,117,6,10,107,33,1,84
- java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
+ java.lang,13,,66,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,54,12 |
|
@atorralba I addressed some of your comments, however:
|
atorralba
left a comment
There was a problem hiding this comment.
I presume those are just the url-encoded versions of \r and n.
Yes, I was just paraphrasing OWASP guidelines. Normally you'd expect sanitizers acting on URL-decoded strings, so only sanitizing with \r and \n seems fine.
The current implementation of the sanitizer does not consider replaceFirst(), since in the general case, this function wouldn't replace all instances of line breaks. But if you feel strongly about it, then I am happy to add it.
You're absolutely right. I mindlessly mentioned all the current taint steps related to replace* without thinking about how valid they are as sanitizers. replaceFirst should totally not be a valid sanitizer.
I still allow for a whitelisting-based sanitization approach, since we already had a test case for it.
👍
There are two false positives in the test cases
Do you mean the chained replace[All] calls? I'd not get into that right now either — although it's an interesting concept for sanitization in general, it seems out of this PR's scope. I'd mark those cases as false positives in the test case though.
| ma.getMethod().hasQualifiedName("java.lang", "String", methodName) and | ||
| target = ma.getArgument(0) and | ||
| ( | ||
| methodName = "replace" and target.getIntValue() = [10, 13] |
There was a problem hiding this comment.
I think this deserves a comment mentioning that 10 and 13 are the code point values of \n and \r, otherwise this looks a bit confusing.
Yep, chained or generally scattered. Ok, I'll leave the implementation as is and change the comments. |
Those are false negatives for the query though, that's why I named them as such. I guess they are false positives from the point of view of the sanitizer... |
Wait. Are you referring to this: // GOOD: replace all line breaks
response.setHeader("h", t.replace('\n', ' ').replace('\r', ' '));or this? // FALSE NEGATIVE: replace only some line breaks
response.setHeader("h", t.replace('\n', ' '));I think you refer to the second one, because the first one picks up any of the replace calls as sanitizers even if they aren't complete by themselves. Ok, now I get it. Yes, false negatives 😄 Nothing to change then. |
Yep, that's what I was referring to. It doesn't appear in the expected file, that's why I would have labeled it as FN. It seems that we do this on various occasions and it helped my understand test case breakage when I implemented this PR |
160b1b6 to
4f9b9c1
Compare
|
Added release notes and rebased. |
|
|
||
| * Improved analysis of the Android class `AsyncTask` so that data can properly flow through its methods according to the life-cycle steps described here: https://developer.android.com/reference/android/os/AsyncTask#the-4-steps. | ||
| * Added a data-flow model for the `setProperty` method of `java.util.Properties`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance. | ||
| * Added data-flow models for the `java.lang.String.(charAt|getBytes)` methods. Improved data-flow models for the `java.lang.String.(replace|replaceFirst|replaceAll)` methods. Additional results may be found where users do not properly sanitize their inputs. |
There was a problem hiding this comment.
This shouldn't go under released, but rather you'll need to create a new change-note file under lib/change-notes. See https://github.com/github/codeql/blob/main/docs/change-notes.md.
There was a problem hiding this comment.
I labeled it as minorAnalysis. Not sure whether that's the correct category.
There was a problem hiding this comment.
Sounds good, that's what I would've labeled it as too.
Click to show differences in coveragejavaGenerated file changes for java
- Java Standard Library,``java.*``,3,572,130,28,,,7,,,10
+ Java Standard Library,``java.*``,3,580,130,28,,,7,,,10
- Totals,,217,6433,1474,117,6,10,107,33,1,84
+ Totals,,217,6441,1474,117,6,10,107,33,1,84
- java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
+ java.lang,13,,66,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,54,12 |
4f9b9c1 to
da79ad8
Compare
Click to show differences in coveragejavaGenerated file changes for java
- Java Standard Library,``java.*``,3,572,130,28,,,7,,,10
+ Java Standard Library,``java.*``,3,580,130,28,,,7,,,10
- Totals,,217,6433,1474,117,6,10,107,33,1,84
+ Totals,,217,6441,1474,117,6,10,107,33,1,84
- java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
+ java.lang,13,,66,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,54,12 |
|
I think the addition of the |
👍 for the time being I've launched a DCA run, we'll see if too many new alerts pop up. I feel inclined to stay optimist and think that, when applications only pick one char out of a tainted string, it would get filtered out by our usual default sanitizers, or the sinks would not be of the appropriate type ( The only dangerous case (FP-wise) I can think of would be taking a single char from a tainted string and then concatenating it to another string that ends up reaching a sink — we could even write a query for that and see how often it happens in a big sample. |
|
Do we have any results for this yet? Also, is there are place I can read up on "DCA"? I presume this is some test harness for performance or also for query results? |
|
If there are concerns over this being merged, I am happy to split out the |
I'll let @atorralba decide on that - I just wanted to make sure that some conscious thought was given to this. |
atorralba
left a comment
There was a problem hiding this comment.
I finally got time to review the DCA results.
Performance looks mostly unchanged. There are a few new results, including the WebGoat ones we already discussed. I reviewed them individually, and all look reasonable. Also, regarding @aschackmull's concern, charAt and getBytes don't seem to be causing any spurious flow — the new results are mostly caused by the replace* steps.
So I'd say this is good to go!
|
@atorralba Thanks for taking the time to double-check this! |
No description provided.