# Nginx Cache and WP canonical URL create infinite loop (bug ?)

**URL:** <https://www.ruby-forum.com/t/nginx-cache-and-wp-canonical-url-create-infinite-loop-bug/214167>\
**Category:** NGINX\
**Created:** [November 23, 2011, 5:27pm UTC](https://www.ruby-forum.com/t/nginx-cache-and-wp-canonical-url-create-infinite-loop-bug/214167 "2011-11-23T17:27:17Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [November 23, 2011, 5:27pm UTC](https://www.ruby-forum.com/t/nginx-cache-and-wp-canonical-url-create-infinite-loop-bug/214167/1 "2011-11-23T17:27:17Z")

</div>

Hello everybody.

Just want to report this to all people who have an NGINX that cache  
request in front a Wordpress installation

Scenario

- Nginx is configured as reverse proxy in front of an Apache that run  
Wordpress.
- proxy\_cache\_key is not defined so is $scheme$proxy\_host$request\_uri;

Let’s say a client require the page [http://www.mysite.com/my-page//](http://www.mysite.com/my-page//) (yes  
double slash at the end) that is not cached

1. Nginx pass the request to Apache/Wordpress
2. Apache/Wordpress process the request and reply with a 301 and sends  
the client to [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/) because is the canonical  
URL
3. Nginx save in the cache the response with these data  
KEY: [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/)  
HTTP/1.0 301 Moved Permanently  
[…]  
Location: [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/)  
[…]  
As you can see the KEY is equal to Location
4. The user/browser send a request for [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/)  
(just one slash)
5. Nginx find the key in the cache and so redirect the browser to  
[http://www.mysite.com/my-page/](http://www.mysite.com/my-page/) causing an infinite loop

Conclusions

- All the users that require the page [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/)  
while is cached are send in the loop
- This happen of course also for requests with a number of slashes at  
the end \> 2
- I can’t call this bug but is just an “unexpected” behaviour, for sure  
a malicious user can overload your site or make pages un-available with  
these kind of requests.
- There are probably other type of URL that create this situation. Have  
found any until now, can someone point one out ?
- Is there a way to avoid this ?

Thanks

–  
Simone

---

<div class="post-metadata">

**Author:** ![hpatoio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a9adbd/32.png) [@hpatoio](https://www.ruby-forum.com/u/hpatoio)\
**Post date:** [November 23, 2011, 6:05pm UTC](https://www.ruby-forum.com/t/nginx-cache-and-wp-canonical-url-create-infinite-loop-bug/214167/2 "2011-11-23T18:05:07Z")

</div>

Hello!

On Wed, Nov 23, 2011 at 05:26:54PM +0100, Simone F. wrote:

> 1. Nginx find the key in the cache and so redirect the browser to  
> [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/) causing an infinite loop
> 
> Conclusions
> 
> - All the users that require the page [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/) while is  
> cached are send in the loop
> - This happen of course also for requests with a number of slashes at the end \>  
> 2
> - I can’t call this bug but is just an “unexpected” behaviour, for sure a  
> malicious user can overload your site or make pages un-available with these kind  
> of requests.
> - There are probably other type of URL that create this situation. Have found  
> any until now, can someone point one out ?
> - Is there a way to avoid this ?

Could you please show your config? By default nginx will use the  
same uri in cache as it will use in request to upstream, and this  
shouldn’t happen.

There are some nuances though, at least when using proxy\_pass with  
variables (see [#34 (Allow rewrites in case of proxy\_pass backend is configured as variable) – nginx](http://trac.nginx.org/nginx/ticket/34), patch is  
awaiting Igor’s review).

Maxim D.

---

<div class="post-metadata">

**Author:** ![hpatoio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a9adbd/32.png) [@hpatoio](https://www.ruby-forum.com/u/hpatoio)\
**Post date:** [November 23, 2011, 6:11pm UTC](https://www.ruby-forum.com/t/nginx-cache-and-wp-canonical-url-create-infinite-loop-bug/214167/3 "2011-11-23T18:11:59Z")

</div>

> Could you please show your config?

Nothing special, here we go (only important parts)

server {

server\_name [www.mysite.com](http://www.mysite.com)  
listen 1.2.3.4:80

proxy\_redirect off;  
proxy\_set\_header Host $host;  
proxy\_set\_header X-Real-IP $remote\_addr;  
proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;  
proxy\_store\_access user:rw group:rw all:r;

location / {

```
# If logged in, don't cache.
if ($http_cookie ~* 

```

“comment\_author\_|wordpress\_(?!test\_cookie)|wp-postpass\_” ) {  
set $do\_not\_cache 1;  
}

```
# Response in not cached
proxy_no_cache $do_not_cache;

# Response is not taken from the cache
proxy_cache_bypass $do_not_cache;

proxy_cache MY_CACHE;
proxy_pass http://ALL_backend;

```

}

location ~ /purge(/.\*) {  
proxy\_cache\_purge MY\_CACHE “$scheme://$host$1$is\_args$args”;  
}

}

> By default nginx will use the same uri in cache as it will use in request to  
> upstream, and this shouldn’t happen

AFAIK when I require [http://www.mysite.com/my-page//](http://www.mysite.com/my-page//) the key for the  
cache is set to [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/)

Ciao

–  
Simone

---

<div class="post-metadata">

**Author:** ![hpatoio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a9adbd/32.png) [@hpatoio](https://www.ruby-forum.com/u/hpatoio)\
**Post date:** [November 24, 2011, 9:50am UTC](https://www.ruby-forum.com/t/nginx-cache-and-wp-canonical-url-create-infinite-loop-bug/214167/4 "2011-11-24T09:50:56Z")

</div>

On 11/23/2011 06:41 PM, Maxim D. wrote:

> With this config, the cache key for the request to  
> “[http://www.mysite.com/my-page//](http://www.mysite.com/my-page//)” will be  
> “http://ALL\_backend/my-page//”.

Well, I was wrong. In another file, on main level, I’ve

proxy\_cache\_key “$scheme://$host$request\_uri”;

–  
Simone

---

<div class="post-metadata">

**Author:** ![hpatoio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a9adbd/32.png) [@hpatoio](https://www.ruby-forum.com/u/hpatoio)\
**Post date:** [November 24, 2011, 11:18am UTC](https://www.ruby-forum.com/t/nginx-cache-and-wp-canonical-url-create-infinite-loop-bug/214167/5 "2011-11-24T11:18:07Z")

</div>

Hello!

On Thu, Nov 24, 2011 at 09:50:10AM +0100, Simone F. wrote:

> On 11/23/2011 06:41 PM, Maxim D. wrote:
> 
> > With this config, the cache key for the request to  
> > “[http://www.mysite.com/my-page//](http://www.mysite.com/my-page//)” will be  
> > “http://ALL\_backend/my-page//”.
> 
> Well, I was wrong. In another file, on main level, I’ve
> 
> proxy\_cache\_key “$scheme://$host$request\_uri”;

With this proxy\_cache\_key the key (for the same request) will be  
“[http://www.mysite.com/my-page//](http://www.mysite.com/my-page//)”.

Maxim D.

---

<div class="post-metadata">

**Author:** ![hpatoio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a9adbd/32.png) [@hpatoio](https://www.ruby-forum.com/u/hpatoio)\
**Post date:** [November 23, 2011, 6:41pm UTC](https://www.ruby-forum.com/t/nginx-cache-and-wp-canonical-url-create-infinite-loop-bug/214167/6 "2011-11-23T18:41:41Z")

</div>

Hello!

On Wed, Nov 23, 2011 at 06:11:41PM +0100, Simone F. wrote:

> proxy\_set\_header Host $host;
> 
> location ~ /purge(/.\*) {  
> proxy\_cache\_purge MY\_CACHE “$scheme://$host$1$is\_args$args”;  
> }
> 
> }
> 
> > By default nginx will use the same uri in cache as it will use in request to  
> > upstream, and this shouldn’t happen
> 
> AFAIK when I require [http://www.mysite.com/my-page//](http://www.mysite.com/my-page//) the key for the cache is  
> set to [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/)

With this config, the cache key for the request to  
“[http://www.mysite.com/my-page//](http://www.mysite.com/my-page//)” will be  
“http://ALL\_backend/my-page//”.

Maxim D.

---

<div class="post-metadata">

**Author:** ![hpatoio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a9adbd/32.png) [@hpatoio](https://www.ruby-forum.com/u/hpatoio)\
**Post date:** [November 24, 2011, 2:35pm UTC](https://www.ruby-forum.com/t/nginx-cache-and-wp-canonical-url-create-infinite-loop-bug/214167/7 "2011-11-24T14:35:32Z")

</div>

On 11/24/2011 11:17 AM, Maxim D. wrote:

> With this proxy\_cache\_key the key (for the same request) will be  
> “[http://www.mysite.com/my-page//](http://www.mysite.com/my-page//)”.

Well, actually when I require [http://www.mysite.com/my-page//](http://www.mysite.com/my-page//) the key  
I’ve in the cache is [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/)  
I’m on NGINX 0.8.54 and I’ve installed “Cache purge” module  
[FRiCKLE Labs / nginx / ngx\_cache\_purge](http://labs.frickle.com/nginx_ngx_cache_purge/)

Also when I require a URL like [http://www.mysite.com/my-page/######](http://www.mysite.com/my-page/######) in  
the cache the KEY is [http://www.mysite.com/my-page/](http://www.mysite.com/my-page/)

If I’ve an entry in the cache with the key  
[http://www.mysite.com/my-page/](http://www.mysite.com/my-page/) and I require  
[http://www.mysite.com/my-page/######](http://www.mysite.com/my-page/######) the request hit the cache

Regards

–  
Simone
