-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Java: add SSRF sink model for the third parameter of RestTemplate.getForObject
#18153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
No attempt to stop FPs.
9f884b4
to
2c061b0
Compare
i <= | ||
max(int occurrenceIndex, int occurrenceOffset | | ||
exists( | ||
hsp.getStringValue().regexpFind("\\{[^}]*\\}", occurrenceIndex, occurrenceOffset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not immediately familiar, but is there an escaping for literal {
in these strings that ought to be checked and disregarded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The strings will be something like "http://{domain}.com/users/{userid}". Depending on which overload of getForObject
you are calling the placeholders are then replaced with either (a) the arguments corresponding to the varargs parameter, in order (ignoring the string in the placeholder), or (b) the value in the provided map, where the key is the string in the placeholder.
In this particular part of the code we're trying to find how many placeholders there are before the first character which lets us know that the hostname is over("?", "#", unescaped "/"). I guess it would be possible that someone would put an escaped "{" in there. I'm not sure how it would be interpreted. I guess we could first replaceall "{" and "}" with some other string with the same number of characters, say " ". I'll do that.
i <= | ||
max(int occurrenceIndex, int occurrenceOffset | | ||
exists( | ||
hsp.getStringValue().regexpFind("\\{[^}]*\\}", occurrenceIndex, occurrenceOffset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull this out as something like
class GetForObjectTemplateStringConstant extends CompileTimeConstantExpr {
GetForObjectTemplateStringConstant() { this = any(Method m | ... is a getForObject method ... ).getACall().getArgument(0) }
predicate hasPlaceholderAtOffset(int idx, int offset) { ... }
}
@smowton I've addressed the review comments. What about the cyclic imports I've created? Is it okay because I've added a private import? |
@owen-mc that is a normal pattern, and in this case
Ideally |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I ran MRVA for the ssrf query restricted to only this new sink (before I had added the commit to reduce FPs) and got no alerts. So I don't think this is a commonly used sink.
Note to reviewers: currently I have had to make
HostSanitizingPrefix
public to make this work, and I have introduced a bidirectional import between Spring and RequestForgery. I am very open to suggestions for how to do this better.