# Strange rewrite\_by\_lua outcome

**URL:** <https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877>\
**Category:** NGINX\
**Created:** [October 16, 2011, 10:12pm UTC](https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877 "2011-10-16T22:12:04Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![luislavena](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/0ea827/32.png) [@luislavena](https://www.ruby-forum.com/u/luislavena)\
**Post date:** [October 16, 2011, 10:12pm UTC](https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877/1 "2011-10-16T22:12:04Z")

</div>

This works produces a 403 Forbidden error as expected:  
#GET /submit\_links/  
if ($request\_uri ~\*  
:|[|]|--|@|^|{|}|~|\<|\>|..|++|//|%0|%A|%B|%C|%D|%E|%F|%22|%27|%28|%29|%3C|%3E|%5C|%7B|%7C|%7D|select(\s\*)(|convert(\s\*)(|/query/|function.|remoteFile|servername|&rptmode=|/(null)/|(maincore|authorize|macromates|head\_auth|submit\_links|change\_action|admin\_db\_utilities|admin.webring.docs|Table/Latest/index).|w00t|MNG/LIVE|/x[0-9][0-9]|\x[0-9][0-9]|/(cgi|https?)/|.css(|)+|/,/|{0}|eval(|\_vti\_|(null)|echo.\*kae|function(.array-rand|())  
) {  
return 403;  
}

This produces a 500 Internal server error instead:  
#GET /submit\_links/  
rewrite\_by\_lua ’  
local request\_uri = ngx.re.match(ngx.var.request\_uri,  
“:|[|]|--|@|^|{|}|~|\<|\>|..|++|//|%0|%A|%B|%C|%D|%E|%F|%22|%27|%28|%29|%3C|%3E|%5C|%7B|%7C|%7D|select(\s\*)(|convert(\s\*)(|/query/|function.|remoteFile|servername|&rptmode=|/(null)/|(maincore|authorize|macromates|head\_auth|submit\_links|change\_action|admin\_db\_utilities|admin.webring.docs|Table/Latest/index).|w00t|MNG/LIVE|/x[0-9][0-9]|\x[0-9][0-9]|/(cgi|https?)/|.css(|)+|/,/|{0}|eval(|\_vti\_|(null)|echo.\*kae|function(.array-rand|())”,  
“io”)  
if request\_uri then  
ngx.exit(ngx.HTTP\_FORBIDDEN)  
end  
';

Line 62: “23388#0: \*258 Failed to load Lua inlined code: [string  
“rewrite\_by\_lua”]:24: ‘)’ expected near ‘|’, client: xx.xxx.xx.xx,  
server: [testsite.com](http://testsite.com), request: “GET /submit\_links HTTP/1.1”, host:  
“[testsite.com](http://testsite.com)””  
[http://pastebin.com/XYNwEciX](http://pastebin.com/XYNwEciX)

---

<div class="post-metadata">

**Author:** ![Nginx\_U](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/dec6dc/32.png) [@Nginx\_U](https://www.ruby-forum.com/u/Nginx_U)\
**Post date:** [October 17, 2011, 2:56am UTC](https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877/2 "2011-10-17T02:56:17Z")

</div>

On Mon, Oct 17, 2011 at 4:11 AM, Nginx U. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> This produces a 500 Internal server error instead:  
> #GET /submit\_links/  
> rewrite\_by\_lua ’  
> local request\_uri = ngx.re.match(ngx.var.request\_uri,

“:|[|]|--|@|^|{|}|~|\<|\>|..|++|//|%0|%A|%B|%C|%D|%E|%F|%22|%27|%28|%29|%3C|%3E|%5C|%7B|%7C|%7D|select(\s\*)(|convert(\s\*)(|/query/|function.|remoteFile|servername|&rptmode=|/(null)/|(maincore|authorize|macromates|head\_auth|submit\_links|change\_action|admin\_db\_utilities|admin.webring.docs|Table/Latest/index).|w00t|MNG/LIVE|/x[0-9][0-9]|\x[0-9][0-9]|/(cgi|https?)/|.css(|)+|/,/|{0}|eval(|\_vti\_|(null)|echo.\*kae|function(.array-rand|())”,

> “io”)

I think you should escape "" here according to nginx’s string literal  
syntax (you do not need to escape "" in your previous “if” example  
because Nginx uses special regex syntax in that regex context. You’ll  
also have to escape the "" according to Lua string escaping rules  
too. That is, escaping "" _twice_.

> Line 62: “23388#0: \*258 Failed to load Lua inlined code: [string  
> “rewrite\_by\_lua”]:24: ‘)’ expected near ‘|’, client: xx.xxx.xx.xx,  
> server: [testsite.com](http://testsite.com), request: “GET /submit\_links HTTP/1.1”, host:  
> “[testsite.com](http://testsite.com)””  
> [http://pastebin.com/XYNwEciX](http://pastebin.com/XYNwEciX)

The error message indicates a Lua syntax error in your Lua source  
code. A quick solution to this is to put your code into a separate  
.lua file and use rewrite\_by\_lua\_file instead such that you do not  
have to escape "" twice (once for Nginx string escaping rules and  
another for Lua string escaping rules).

Here’s an example:  
# nginx.conf  
location /foo {  
rewrite\_by\_lua ‘ngx.re.match(“\\d+”, ngx.var.uri)’; # we’re  
using \d+ here but requires twice escaping  
}

And to use external .lua file:

```
# nginx.conf
location /foo {
    rewrite_by_lua_file conf/my.lua;
}

# conf/my.lua
ngx.re.match("\\d+", ngx.var.uri)

```

We can see that in the first example, we need to escape "" for Nginx  
string literals (so it becomes “\”) and then escape each of these two  
back-slashes again according for Lua string literals and thus got  
“\\” at last.

But in the second example, we only need to esacpe "" once according  
to Lua string literal syntax, which is a bit better looking 🙂

This gotcha is documented in ngx\_lua’s wiki page here:

```
http://wiki.nginx.org/HttpLuaModule#ngx.re.match

```

Best,  
-agentzh

---

<div class="post-metadata">

**Author:** ![Nginx\_U](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/dec6dc/32.png) [@Nginx\_U](https://www.ruby-forum.com/u/Nginx_U)\
**Post date:** [October 17, 2011, 6:48am UTC](https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877/3 "2011-10-17T06:48:06Z")

</div>

On 17 October 2011 03:55, agentzh [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> syntax (you do not need to escape "" in your previous “if” example
> 
> > 
> 
> rewrite\_by\_lua ‘ngx.re.match(“\\d+”, ngx.var.uri)’; # we’re
> 
> # conf/my.lua
> 
> This gotcha is documented in ngx\_lua’s wiki page here:
> 
> [http://wiki.nginx.org/HttpLuaModule#ngx.re.match](http://wiki.nginx.org/HttpLuaModule#ngx.re.match)

I’ll use the rewrite module for this regex since it works as is and  
try to understand the issue later.

Thanks.

---

<div class="post-metadata">

**Author:** ![Nginx\_U](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/dec6dc/32.png) [@Nginx\_U](https://www.ruby-forum.com/u/Nginx_U)\
**Post date:** [October 17, 2011, 7:04am UTC](https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877/4 "2011-10-17T07:04:42Z")

</div>

On 10/16/2011 10:50 PM, Nginx U. wrote:

> BTW this works fine even though it has "":
> 
> local query\_string = ngx.re.match(ngx.var.request\_uri,

“((php|sql)-?my-?admin/|my-?(php|sql)-?admin|(php|sql)-?manager)|(\_vpi|xAou6|db\_name|clientrequest|option\_value|sys\_cpanel|db\_connect|doeditconfig|check\_proxy|system\_user|spaw2|prx2|thisdoesnotexist|proxyjudge1|ImpEvData|proxydeny|base64|crossdomain|localhost|wwwroot|mosconfig|scanner|proc/self/environ)|.(outcontrol|rdf|XMLHTTP|cgi|asp|aspx|cfg|dll|exe|jsp|mdb|sql|ini|rar|inc|dll)|(/admin/sqlpatch.php/password\_forgotten.php?action=execute)|etc/passwd|/manager/html”,“io”)

You’re just doing “.” in that line. If Nginx strips that "", then it  
ends up in Lua as “.”, which changes the meaning but will happen to work  
in most cases (though it would match sqlpatch\_php and other similar  
strings, and not just sqlpatch.php, since the “.” will be the wildcard).

Tim

---

<div class="post-metadata">

**Author:** ![Nginx\_U](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/dec6dc/32.png) [@Nginx\_U](https://www.ruby-forum.com/u/Nginx_U)\
**Post date:** [October 17, 2011, 6:34pm UTC](https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877/5 "2011-10-17T18:34:03Z")

</div>

On 17 October 2011 08:03, Tim M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> cases (though it would match sqlpatch\_php and other similar strings, and not  
> just sqlpatch.php, since the “.” will be the wildcard).
> 
> Tim

Let me get this right. Do I need to always escape the "" inserted to  
escape “.” in “.” in lua and then add another couple of ""s? I.E.,  
do I need to do “sqlpatch\\.php” to get “sqlpatch.php” passed to  
the regex finally? IOW, do I basically replace each "" with “\\”?

If I understand agentzh, the rewrite module handles this behind the  
scenes and allows us to use familiar syntax. Is that right?

Thanks

---

<div class="post-metadata">

**Author:** ![Nginx\_U](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/dec6dc/32.png) [@Nginx\_U](https://www.ruby-forum.com/u/Nginx_U)\
**Post date:** [October 17, 2011, 7:45pm UTC](https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877/6 "2011-10-17T19:45:50Z")

</div>

On 10/17/2011 10:33 AM, Nginx U. wrote:

> Let me get this right. Do I need to always escape the "" inserted  
> to escape “.” in “.” in lua and then add another couple of ""s?  
> I.E., do I need to do “sqlpatch\\.php” to get “sqlpatch.php”  
> passed to the regex finally? IOW, do I basically replace each ""  
> with “\\”?

Yes.

> If I understand agentzh, the rewrite module handles this behind the  
> scenes and allows us to use familiar syntax. Is that right?

The rewrite module apparently changes how the string is parsed in the  
Nginx file, yes.

Tim

---

<div class="post-metadata">

**Author:** ![Nginx\_U](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/dec6dc/32.png) [@Nginx\_U](https://www.ruby-forum.com/u/Nginx_U)\
**Post date:** [October 17, 2011, 7:55pm UTC](https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877/7 "2011-10-17T19:55:08Z")

</div>

On 17 October 2011 20:45, Tim M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On 10/17/2011 10:33 AM, Nginx U. wrote:
> 
> > Let me get this right. Do I need to always escape the "" inserted  
> > to escape “.” in “.” in lua and then add another couple of ""s?  
> > I.E., do I need to do “sqlpatch\\.php” to get “sqlpatch.php”  
> > passed to the regex finally? IOW, do I basically replace each ""  
> > with “\\”?
> 
> Yes.  
> Thanks. I had done that anyway and got expected results. Not strictly  
> changing "" to “\\”. It was “\” to "\\" & "" to “\\”
> 
> > If I understand agentzh, the rewrite module handles this behind the  
> > scenes and allows us to use familiar syntax. Is that right?
> 
> The rewrite module apparently changes how the string is parsed in the Nginx  
> file, yes.  
> Very thoughtful.

Cheers.

---

<div class="post-metadata">

**Author:** ![Nginx\_U](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/dec6dc/32.png) [@Nginx\_U](https://www.ruby-forum.com/u/Nginx_U)\
**Post date:** [October 17, 2011, 6:51am UTC](https://www.ruby-forum.com/t/strange-rewrite-by-lua-outcome/212877/8 "2011-10-17T06:51:10Z")

</div>

On 17 October 2011 07:47, Nginx U. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > I think you should escape "" here according to nginx’s string literal
> > 
> > > [http://pastebin.com/XYNwEciX](http://pastebin.com/XYNwEciX)  
> > > location /foo {
> > 
> > This gotcha is documented in ngx\_lua’s wiki page here:
> > 
> > [GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/HttpLuaModule#ngx.re.match)
> 
> I’ll use the rewrite module for this regex since it works as is and  
> try to understand the issue later.
> 
> Thanks.

BTW this works fine even though it has "":

local query\_string = ngx.re.match(ngx.var.request\_uri,  
“((php|sql)-?my-?admin/|my-?(php|sql)-?admin|(php|sql)-?manager)|(\_vpi|xAou6|db\_name|clientrequest|option\_value|sys\_cpanel|db\_connect|doeditconfig|check\_proxy|system\_user|spaw2|prx2|thisdoesnotexist|proxyjudge1|ImpEvData|proxydeny|base64|crossdomain|localhost|wwwroot|mosconfig|scanner|proc/self/environ)|.(outcontrol|rdf|XMLHTTP|cgi|asp|aspx|cfg|dll|exe|jsp|mdb|sql|ini|rar|inc|dll)|(/admin/sqlpatch.php/password\_forgotten.php?action=execute)|etc/passwd|/manager/html”,  
“io”)  
if query\_string then  
ngx.exit(ngx.HTTP\_FORBIDDEN)  
end

Haven’t read the gotcha link yet to understand the intricacies yet  
though.

Cheers.
