-
Notifications
You must be signed in to change notification settings - Fork 448
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
Let OJS honor HTTP_X_FORWARDED_PROTO instead of trying to discover it #6851
Comments
Note that any solution that relies on request headers to determine the protocol will need to consider URL generation from command-line tools e.g. when a CRON job sends off review reminder emails containing URLs. |
Hummm... didn't though in this. :_-( I'm unsure if getProtocol() will be able to get the right one based on SCRIPT_URI, but in worst of cases cron will send a mail with an http petition that will be redirected to httpS when it arrives to the server. But I understand cron is just an example and it could be a problem in other situations. Jumping to a different approach... why "force_ssl" is not forcing the protocol in getProtocol()? |
The https://github.com/pkp/pkp-lib/blob/stable-3_3_0/classes/handler/PKPHandler.inc.php#L275..L279 If |
I really thought this was going to be an easy one. :-( Tomorrow I will take a look but because I suspect command-line tools will take the protocol properly even without headers, or we won't mind much if they are going through http... What other features of ojs are not reading headers apart of command-line tools? Trying to evaluate if a a non perfect implementation would be better than nothing. |
Checking what other CMS are doing: In WP they are aware of the issue and offer a couple of workarounds:
First workaround is adding a condition to their wpconfig.php to check the X_FORWARDED_PROTO. References:
In the other hand, in drupal they full honor X-FORWARDED* tags since long time ago: https://www.drupal.org/project/drupal/issues/313145 They use config variables to full cover those tags. Said that... We can not apply WP solutions directly, because we can't add a condition to our config.inc.php, but (even is not nice because it means branching your code) we can force it at the top of index.php. From Drupal, I know we are trying to reduce variables in config.inc.php but we crossed that river when we added "trust_x_forwarded_for", isn't it? I mean, why implementing "X-Forwarded-For" but not implementing the other three X_FORWARDED main tags too? Or why not a new "force_protocol" config variable that will work with command-line tools (and any piece of code that is not reading headers)? Not sure if I'm biased, but as far as infrastructures are becoming more complex, I think this is not a minor issue. |
This post let me understand part of the problem: |
I'm struggling with the exact same problem. My installation is behind a proxy who handles SSL and then passes the request to a Traefik server that points to a correct docker container. Traefik was always retuning a 404 even when ojs service was up and running, later I figured it had something to do with So basically the thing are like this: if I set I don't get why the request to static assets are being made over HTTP and not HTTPS. I tought Tomorrow I'll try again with SSL disabled both on the proxy and ojs server and see if it works, regardless that this isn't the ideal thing to do. |
Just in case something is useful for your case... I will publish my full configuration. Let me say that I'm not proud (because it's a dirty solution) but it works. The trick (for me), apart of the proper variables in config.inc.php is overwriting index.php to force the contexts. Notice I use single-tenant OJS, so it won't probably work in multi-tenant journal. This is my index.php I use when is a directory. Example: https://foo.org/journalContext
Overwriting "REQUEST_URI" caused more trouble than help so this is why it's commented. Said that, relevant variables in config.inc.php are:
Not proud either about my apache virtual host (could be simplified and fails with some site-admin pages), but does the job:
|
@marcbria I’ll try your workaround in a different branch and build a new docker imagem from it but I’ll say I totally agree with you that this doesn’t seems like a minor issue. In my specific case, our infrastructure doesn’t support alternatives to it. All of our systems are behind a proxy and docker based. We already have a journal system and we’re trying to migrate to OJS, but I don’t know if without I’m being able to handle this problem the project manager will let this fly. I’ll try this solution and will keep you posted. Thanks in advance |
I started the tests to move to OJS 3.3 and I'm hit again with this issue. To recall (so long since I deal with it) this happens when OJS ask for an API resource with httpS, because behind the proxy OJS is still running with http and this generates a "mixed content" issue in frontend. Right now, my error is this
Wired thing is now, when I force "https" in getProtocol() funcion (or even in getBaseUrl), OJS keep asking for "http". @nunesvictor did you manage to find a solution? I'm quite sure it could be adressed with extra mod_rewrite black magic, a little bit of ojs tunning (like the trick in index.php to force the journalContext) combined with ojs settings in config.inc.php... but at same time I feel we are overcomplicating the system configuration and I feel that would be nice to make OJS a little bit more friendly with proxies when not all runs over httpS (that is not an inusual scenario). @asmecher any idea about how could we simplify the this to force OJS to use "https" protocol all the time? Thanks you all for your time, |
hey @marcbria, I found a workaround for this, it's a little messy but for now is getting the job done. I found this at the PKP forums, but I lost the link for the original post. Here we go, the protocol selection is made here: pkp-lib/classes/core/PKPRequest.inc.php Line 351 in cdda6f7
All I did was, while the apps was running, use Like I said, that's a messy way to do that but, for now, is working fine. I'll keep you posted if I found some new issues related to that. It would be nice see this done by simply setting an env variable or by respecting the forwarded protocol, until there I think I'll have to do that. Hope that helps. PS. I'm building a Docker image from scratch and I'm using OJS 3.3.0-X tarball as source, not git. So, the related file was found under |
Thank you for taking the time to write with your feedback Victor. I'm also patching my dockerized OJS with volumes from docker-compose. It doesn't seem elegant to me but it works and at the moment I haven't thought of anything better. Maybe adding an entrypoint that overwrites (if the folders are maintained, a cp would do) everything that the "patch" directory finds? Actually the problem is that the philosophy of containers clashes with the idea of patches, since containers are immutable... so if you have to patch, you have to generate a new image. Keep in touch! |
Not sure when this was implemented or if this was working since the very begining but adding a
Does it means the other X-Forward tags are also implemented? Funny part is...
I have been dealing with this bug for years, and let me say this is really frustrating because it's extremely difficult to degug. You got caches everywhere (browser, proxy, OJS...) and, in general, apache rules are a nightmare. I spend a lot of hours in a trial and error process and I still don't have a rock-solid set of mod_rewrite rules for each url (domain, subdomain or folder installations), for dirty and clean urls, or for both protocols. @asmecher how could I help PKP to improve this? What do you need? |
Describe the problem you would like to solve
Over httpS, when you are behind a reverse proxy/loadbalancer or on complex networks architectures OJS have some trouble to discover the right protocol and it could generate some different issues like:
If httpS in forced in function
getProtcolol()
at "lib/pkp/classes/core/PKPRequest.inc.php" all problems are gone...Describe the solution you'd like
This is supossed to be fixed with protocol relative URLs (allowProtocolRelative directive) but this is not yet full implemented in OJS... and (according to Alec) "We can't just enable protocol-relative URLs globally because of URLs that are delivered to outside mechanisms, e.g. API interactions, emails, etc."
So an alternative (and also to make OJS more flexible) the easiest solution is letting OJS honor the protocol specified at HTTP_X_FORWARDED_PROTO (if exists) instead of keep asking about the protocol to SCRIPT_URI.
It could be done here:
pkp-lib/classes/core/PKPRequest.inc.php
Line 351 in c5f40d7
Adding a condition to check if "HTTP_X_FORWARDED_PROTO" exists, and if yes, set the protocol to be whatever you find in the variable.
What I tried?
In my specific case, the problem was a reverse proxy (traefik) converting http petitions to httpS, so I tried with:
All cases except the last one, results in "Mixed content" due JS references.
Last one (force_ssl) falls in an "infinite redirection loop" because "OJS sees an HTTP request (not knowing it’s coming from the reverse-proxy) and redirects the browser to the HTTPS location. So the browser makes a new request (using HTTPS as before) to the reverse-proxy resulting in a new HTTP request to the OJS backend which redirects to HTTPS again. And so on and so forth."
When protcolo is forced to httpS in getProtocol() ("lib/pkp/classes/core/PKPRequest.inc.php") problems are gone...
Who is asking for this feature?
Additional information
Variations of this same issue are described here:
And also in the following github issues:
Example of mixed content:
The text was updated successfully, but these errors were encountered: