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
Update IP-based security configurations to more sane defaults (now that CORS + CSRF are enabled) #3171
Conversation
Since I was the developer who orginally implemented the security measures, let me provide a bit more context on why they where added and why they are different than CORS and CSRF. The The Note that both measures are not related to CSRF: https://owasp.org/www-community/attacks/csrf . Trusted proxies or ip-locked session tokens will not prevent a user from clicking on an maliciously-crafted link. CORS is a pure browser-based security measure, see https://owasp.org/www-community/attacks/CORS_OriginHeaderScrutiny:
So for non-browser based API access (malicious scripts), CORS does not offer any protection. Since I'm not active anymore, I don't have all the context on why this PR was created so I will leave it up to the community if the above two security measures are still relevant in the current DSpace implementation. But I wanted to make sure that everyone understands with which purpose they were originally added. |
@tomdesair : I appreciate your feedback here. However, both of these settings have become problematic in early user testing of DSpace 7, which is why we are looking to remove them:
|
If it is decided that If we find no good solution to the problems with |
As I noted in today's meeting, overnight I rethought my response to @tomdesair 's kind feedback. I still think we can remove However, we may want to keep Therefore, I'm temporarily flagging this as WIP until I rework that configuration. |
6431d32
to
32f6ed3
Compare
@mwoodiupui and @abollini : I've removed the I've updated the description of the PR to describe the new implementation.
|
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.
Hi Tim,
This PR looks good in general, but I'd prefer a few small change to reduce the odds of mistakes being made with the setup. I've included the details inline
dspace-api/src/main/java/org/dspace/service/impl/ClientInfoServiceImpl.java
Show resolved
Hide resolved
dspace-api/src/main/java/org/dspace/service/impl/ClientInfoServiceImpl.java
Outdated
Show resolved
Hide resolved
dspace-api/src/main/java/org/dspace/service/impl/ClientInfoServiceImpl.java
Outdated
Show resolved
Hide resolved
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.
hi @tdonohue the code looks good to me. I agree with the suggestion from @benbosman , please apply them before to merge this PR. I have only another concern about the use of mockito-inline, we could avoid it in this case just introducing a new utility class not final/static
dspace-api/src/main/java/org/dspace/service/impl/ClientInfoServiceImpl.java
Outdated
Show resolved
Hide resolved
…ocks authentication from untrusted origins
…ce tests in AnonymousAdditionalAuthorizationFilterIT to show it works with proxies on or off.
…o determine whether UI IP lookup is done. More tests to prove it works
baf831a
to
b3088fc
Compare
@benbosman and @abollini : This PR is now ready for re-review. The test failures I mentioned in the meeting were temporary failures. (Completely unrelated to the changes in this PR, apparently a few of our Statistics ITs can fail if the tests run at the exact time when the month changes...and by random chance, the tests yesterday ran while the date changed from March 31 -> April 1. I reran all tests today and they all succeeded.) In any case, I've addressed all your prior feedback (see comments above), so I think this should be rather easy to review. @benbosman : As mentioned in today's meeting, the changes in this PR (around determining trusted IPs) might also be useful in determining when we accept a |
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.
@tdonohue I've tested this implementation, and noticed a problem depending on the setup
I was able to create a setup with:
- A call performed by Angular
- Apache configured using mod_http (adding a proxy header)
This caused getClientIp(String remoteIp, String xForwardedForHeaderValue)
to receive:
- remoteIp: 127.0.0.1 (from Apache connecting to REST)
- xForwardedForHeaderValue: containing
my ip
,the server's ip
from the Angular proxy
The trustedProxies contains 127.0.0.1 and the server's ip
, but getXForwardedForIpValue() has returned the server's ip
, loosing my ip
This is due to a missing trim
Can you adjust this, and also add a test?
dspace-api/src/main/java/org/dspace/service/impl/ClientInfoServiceImpl.java
Show resolved
Hide resolved
dspace-api/src/main/java/org/dspace/service/impl/ClientInfoServiceImpl.java
Show resolved
Hide resolved
dspace-api/src/main/java/org/dspace/service/impl/ClientInfoServiceImpl.java
Show resolved
Hide resolved
Thanks @benbosman for your review. I've updated this PR again based on your feedback (see also my answers to your comments). |
…s test correction fails without the code change)
0023cf6
to
f33a502
Compare
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.
Thanks @tdonohue
I've reviewed the code and tested again.
I was able to identify it did see my IP correctly, even when using Apache with mod_http, and Angular.
When requesting the main page "/", Angular did proxy the request to Apache (using Angular's public IP), which proxied the request to tomcat (using localhost). This all worked correctly.
When trying to spoof my IP by adding another "X-Forwarded-For" in Curl (also including a cookie to ensure this code is called:
curl 'https://dspace7-test.atmire.com/' --header "X-Forwarded-For: 192.168.0.2"
org.dspace.service.impl.ClientInfoServiceImpl#getXForwardedForIpValue
will first read my IP as192.168.0.2
- Hereafter it will read it as my real IP
- Hereafter it will read the Angular IP, but skip it (keeping my real IP)
- This will return my actual IP
I also couldn't spoof it by:
- Using the Angular server's IP in the X-Forwarded-For header
- Using multiple IPs in the X-Forwarded-For header
- Using a combination of a spoofed IP and the Angular server's IP in the X-Forwarded-For header
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.
code and tests look good thanks @tdonohue
References
proxies.trusted.ipranges
setting to the IP address ofdspace.ui.url
, determined dynamically). This change also fixes Unable to login/create session when dspace 7 angular is in production mode dspace-angular#1036jwt.*.token.include.ip
settings)Description
This PR includes the following changes:
proxies.trusted.ipranges
- This setting has now been commented out by default. When commented out, the ONLY trusted IP is localhost (127.0.0.1), and (possibly) the IP address ofdspace.ui.url
(see next configuration). Therefore, this setting should ONLY be used or changed if you need to add additional trusted proxies.proxies.trusted.include_ui_ip
- This is a new configuration which decides whether to automatically trust the UI as a proxy. When enabled (which is default), the backend determines the IP address ofdspace.ui.url
and adds it to the list of trusted proxies.jwt.*.token.include.ip
- This setting has been removed entirely. These settings allowed you to store your IP address in your JWT auth token, therefore disabling token reuse across IP addresses. However, this has the side-effect of forcing you to login again if your IP changes (and if you have a non-static IP, it's possible your IP could change during your session.testCannotAuthenticateFromUntrustedOrigin()
test toAuthenticationRestControllerIT
, alongside the existing testtestCannotReuseTokenFromUntrustedOrigin()
.mockito-inline
in order to use the new support for mocking static methods.rest.cors.allowed-origins
setting over into ourlocal.cfg.EXAMPLE
to make that setting more prominent.Instructions for Reviewers