Allowing paypal to bypass password protection in .htaccess

I have a password protected ecommerce site. I am having difficulty with my .htaccess file allowing Paypal to send back the IPN. (I did learn that I needed the site to have SSL - so got that installed.)

Here is what I am using.

#allow access from paypal only
SetEnvIf Referer "^https://www\.paypal\.com" auth_referral
Order Allow,Deny
Deny from all

AuthType Basic
AuthName "FRBSF"
AuthUserFile "/path/to/my/.htpasswds/public_html/passwd"
Require valid-user
Allow from paypal.com
Allow from env=auth_referral
Satisfy any

Open in new window


I've tried dozens of combinations of code over the past 4 days and I end up with either the password protection not working and PayPal IPN working fine or vice versa. I need them both to work ASAP!

I've also tried using SetEnvIf HOST.

Thanks in advance!
LVL 1
techbotsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

techbotsAuthor Commented:
I have also tried

SetEnvIf Request_URI "^/wc-api/WC_Gateway_Paypal/." auth_referral

since PayPal might not send back referrer info.
Steve BinkCommented:
Please verify your Apache version.

Have you tried turning on debug logging to find out how the requests are being handled?
techbotsAuthor Commented:
How do I find the Apache version? (Site is hosted on HostGator).

I also just tried adding an .htaccess file to the Woocommerce plugin folder to allow all. That didn't work either.
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

Steve BinkCommented:
The Apache version information should be available somewhere in your account.  You can also try using phpinfo(), though it may be disallowed by your host.

Realistically, I'm not sure this is the route you want to go.  The referer is set by the user, so it can be manipulated by an attacker.  It is not a good idea to base your security on its value.  Using "Allow from" might be OK, but you'll need to find out the name/IP under which the request is being made.  It needs to be an exact match.

In any case, the whole strategy is a little wonky.  The Paypal system is not set up to log in via HTTP authentication, and authentication (and associated security) for e-commerce is generally done at the application level.  What circumstances imply using HTTP-based authentication is the way to go here?  In an ideal system, Paypal posts a form to an SSL form on your site, and you use that information to verify the transaction.
techbotsAuthor Commented:
Apache version 2.2.29. The site uses SSL.

The first few lines in the access logs are:
 [30/Nov/2015:06:59:19 -0600] "POST /wc-api/WC_Gateway_Paypal/ HTTP/1.1" 401 - "-" "PayPal IPN ( https://www.paypal.com/ipn )"
173.0.81.1 - - [30/Nov/2015:07:00:18 -0600] "POST /wc-api/WC_Gateway_Paypal/ HTTP/1.1" 401 - "-" "PayPal IPN ( https://www.paypal.com/ipn )

Can I use a POST in the .htaccess? If so, would it be something like:

<Limit POST /wc-api/WC_Gateway_Paypal/ HTTP/1.1>
      Satisfy Any
</Limit>

The site is already live so I don't have an option to redo the whole way it works. But I do urgently need a way to get the payment info back to Woocommerce.
Steve BinkCommented:
Try removing the quotes from your regex:
SetEnvIf Referer "^https://www\.paypal\.com" auth_referral

Open in new window

You can also try SetEnvIfNoCase.  That may help the referer get picked up.

Still, that's a distant second in how you should approach this.  If you're set on this strategy, "Allow from" is the proper way to do it.  I've found a hint in the docs:
Hosts whose names match, or end in, this string are allowed access. Only complete components are matched, so the above example will match foo.apache.org but it will not match fooapache.org. This configuration will cause Apache to perform a double reverse DNS lookup on the client IP address, regardless of the setting of the HostnameLookups directive. It will do a reverse DNS lookup on the IP address to find the associated hostname, and then do a forward lookup on the hostname to assure that it matches the original IP address. Only if the forward and reverse DNS are consistent and the hostname matches will access be allowed.

The notes regarding DNS are important, since large organizations are likely to have multiple servers doing this type of work.  Try detecting via IP instead of hostname.
techbotsAuthor Commented:
From my understanding, PayPal hides it's Referrer URL when communicating back to the site. IP addresses would be better, but there are many for PayPal and I can't find them anywhere.  I can only find the sandbox ones, but this is a live site. A reverse DNS lookup wouldn't give me all the possible IP addresses PayPal uses.
Steve BinkCommented:
>>> A reverse DNS lookup wouldn't give me all the possible IP addresses PayPal uses.

Which is why I maintain this is not the proper way to do this.  Again, what conditions exist that imply HTTP authentication is preferred for the entire site?  As an e-commerce site, don't you want people to buy things?

The better route here would be to disable authentication on the Paypal listener, at a minimum.  Your application should be verifying anything received through that endpoint, and Paypal will not log in anyways.  Perhaps use a second .htaccess file in the directory to disable authentication.  Otherwise, start building your list of IPs from the server's logs.  Anytime you find a denial to that URL, check if the IP belongs to Paypal, and if so, add it to the list.
techbotsAuthor Commented:
I finally got a response from PayPal with the IPN IP addresses. So this is the code I am using now.

# password protection except for PayPal
AuthType Basic
AuthName "FRBSF"
AuthUserFile "/home4/w3ndy321/.htpasswds/public_html/frbsf/passwd"
Require valid-user

Allow from 64.4.248.8
Allow from 64.4.249.8
Allow from 173.0.84.40
Allow from 173.0.84.8
Allow from 173.0.88.40
Allow from 173.0.88.8
Allow from 173.0.92.8
Allow from 173.0.93.8

Open in new window


However this still isn't sending back the payment information.
Steve BinkCommented:
Try adding "Satisfy any", or removing the user-based authentication.
techbotsAuthor Commented:
If I add "Satisfy Any", it takes off the password protection which I can't do. Also removing the valid user authentication isn't an option either since that is a requirement of the client that the site be password protected. This can't be the only online shop that uses PayPal that is password protected. Surely there is a way to make the two work together.
Steve BinkCommented:
>>> This can't be the only online shop that uses PayPal that is password protected.

It may very well be.  :)  Most e-commerce sites needing security do so through the application layer, e.g., user accounts and such.  HTTP authentication is a different beast, and much more basic.

The fact is that Paypal doesn't implement HTTP-based user authentication.  If you require it, Paypal is not going to work.  The two states appear to be mutually exclusive.  By adding "Satisfy Any", you're essentially telling the server "either a valid user account, OR coming from Paypal".  I think that is as close as you're going to get.

You mentioned previously that there's no time to redo how this works.  I believe the core problem is a single bad design decision (HTTP authentication, instead of application-based authentication).  Unless you correct that decision, you'll be stuck with the consequences.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
techbotsAuthor Commented:
I understand. However doing it this way was not my decision, or is it in my authority to change this. I will likely have to just tell the client that what they want, or rather the way they want it, cannot be done. At least I have explored it thoroughly. Thank you for your time.
Steve BinkCommented:
Was there more information you needed?  "Can't be done" is a valid answer, and does not merit a "B" grade.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Apache Web Server

From novice to tech pro — start learning today.