Nginx lua modify html response after proxy_pass - nginx

What I'm trying to do for a PoC and is to add a href to web pages coming from a dynamic backend server. Adding the href is easy using "subs_filter", but I need to use information embedded within the response to construct the href.
Is it possible to use LUA to process the response from proxy_pass, modify it and return to requester (client)?
Any and all suggestions welcome.
Below is the code I'm looking at, now I understand Lua better and how nginx uses it I see that 'body_filter' is the correct way to. However the code seems simple enough but i can't get the regex to work.
Further background, I'm trying to parse the returned proxy_pass response, parse it for a start and end time, then construct a JS script url placed into the head.
Example response that I want to regex against.
Informações Adicionais
Horário de início: 08H50
Horário de término: 09H14
The code from within the 'location {}'
body_filter_by_lua '
-- my regex which is validate but doesn't seem to be within LUAJIT
--local from, to, err = ngx.re.find(ngx.arg[1], "(.início: *\d{2}H\d{2})", "jo")
local from, to, err = ngx.re.find(ngx.arg[1], "início", "jo")
replacestr = string.sub(ngx.arg[1], to, 5)
replaceme = "<script></script></head>"
ngx.arg[1] = ngx.re.sub(ngx.arg[1],"</head>", replaceme)
';
Changing "início" to "head" for example works, so I'm assuming it is the accented char but I'm unable to find confirmation of this.
Changing "início" to "\d{2}H\d{2}" fails, with "body_filter_by_lua:5: invalid escape sequence near '"'"

I discovered what I mentioned in the comments regarding 'nix.header.content_length' and importantly nginx and lua require double escaping see: lua-nginx-module special pcre sequences for more details.
The accented chars needed the flag 'u' adding to 'jo' of the 'ngx.re.find'

user "body_filter_by_lua_file"
Equivalent to body_filter_by_lua, except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the Lua/LuaJIT bytecode to be executed.
When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server.
This directive was first introduced in the v0.5.0rc32 release.

Related

Attack via filename passed in url query?

I wrote a small service in go (although I don't think this would be a language specific issue), that caches some results by saving it to a file, and writing a URL query parameter into the filename with "prefix" + param + ".json" using ioutil.WriteFile. The service runs on Ubuntu.
Is it possible to do something malicious, by passing an unexpected string via the query?
Relevant attacks that come to mind are called path injection. For example what if the query parameter is something like ../../etc/passwd (okthis would probably not work as the user running this service would have no permissions, but you get the point). For example it could be possible to overwrite your service code itself.
You should sanitize the parameter before adding it to the filename. The best would be a strict whitelist of letters and numbers that are allowed, anything else should ve removed from the parameter. That way injection would not be possible.
You can also check whether the path you are writing to is actually under an explicitly allowed directory.
I will make a test in python, here is the struct of the project
app1/main.py
while True:
a = input() # passing query
with open("{}.json".format(a), "w") as f:
f.write("Hello world")
now i am a hacker, and i want to change "yourfile.json"
so i passed this
and than, the content of yourfile.json become: Hello world

Is it better to use a "?" or a ";" in a URL?

In my application, I redirect an HTTP request and also pass a parameter. Example:
http://localhost:9000/home;signup=error
Is it better to use a ; or shall I use a ? i.e. shall I do http://localhost:9000/home;signup=error or http://localhost:9000/home?signup=error?
Are the above two different from each other semantically?
The ? is a reserved character; I have read that this is both valid and invalid, but I have used it for 'slugs' when templating.
Should you choose to use it, percent-encode the query string using %3F which is not human readable, but will produce the ?. (An encoder is recommended)
Perhaps you will find a more suitable solution for your redirects by adding an .htaccess file to your project.

Go http: difference between serving /static and /static/

I have a terrible confusion concerning http.FileServer and slashes.
I need to serve a script to a html page. In the directory I'm working I have the page index.html and I have a static directory with myscript.js inside of it.
First question: is it correct to write
<script src="/static/myscript.js"></script>
? I have also seen src="static/myscript.js" and I don't know if there is a reason for using one or the other (but I guess it influences the handler we have to write on the server).
Let's suppose we settle for the first version. Second question: on the server side, I want to register the handler for directory static. Inspired by this example, I do:
fs := http.FileServer(http.Dir("./static"))
http.Handle("/static", http.StripPrefix("/static", fs))
but I get a 404. However, if I use:
fs := http.FileServer(http.Dir("./static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
with the ending slashes, it works fine!
I'm really new to web servers, so I would appreciate any explanation that includes what are the actual addresses passed around by functions. For example, I don't know (and I can't figure it out from the net/http documentation ) what is the address that is passed to the handler when serving a /static request. I guess it's /static/myscript.js since we are using http.StripPrefix but I have no actual way of proving it.
http.Handle("/static", http.StripPrefix("/static", fs)) registers a fixed name pattern.
http.Handle("/static/", http.StripPrefix("/static/", fs)) registers a rooted subtree pattern.
The former matches only requests where URL.path = "/static". The latter matches every path that starts with "/static/". The 404 indicates that it could not match any pattern for the given request, not that the requested file wasn't found. (It does not even get to execute the FileServer's handler!)
And to answer your first question:
<script src="/static/myscript.js"></script>
URLs starting with a slash / are absolute. That means it does not matter on what page you are, it will always append to the domain name e.g. example.com/some/page + /static/myscript.js = example.com/static/myscript.js
<script src="static/myscript.js"></script>
Is a relative path. That means it will be appended to URL of the currently visited page e.g. example.com/some/page + static/myscript.js = example.com/some/page/static/myscript.js

Running Go from the command line nested JSON

I can think of workarounds on how to get this working however I'm interested in finding out if there's a solution to this specific problem.
I've got a go program which requires a json string arguement:
go run main.go "{ \"field\" : \"value\" }"
No problems so far. However, am I able to run from the command line if one of the json values is another json string?
go run main.go "{ \"json-string\" : \"{\"nestedfield\" : \"nestedvalue\"}\" }"
It would seem that adding escape characters incorrectly matches up the opening and closing quotes. Am I minuderstanding how this is done or is it (and this is the side I'm coming down on) simply not possible?
To reiterate, this is a question that has piqued my curiosity - I'm aware of alternative approaches - I'm hoping for input related to this specific problem.
Why don't you just put your json config to the file and provide config file name to your application using flag package
Based on the feedback from wiredeye I went down the argument route instead. I've modified the program to run on:
go run main.go field:value field2:value json-string:"{\"nestedfield\":nestedvalue}"
I can then iterate over the os.Args and get the nested json within my program. I'm not using flags directly as I don't know the amount of inputs into the program which would have required me to use duplicate flags (not supported) or parse the flag to a collection (doesn't seem to be supported).
Thanks wiredeye

URL just removes parameters

I've created an API for use on my website.
The API I made strips everything using mysql_real_escape_string then puts it into the database.
But the problem I'm having is the URL that my php scripts are using to access the API is cut short sometimes...
Which I have narrowed down to one of the parameters...
When its Ford Mondeo 22' the URL that is passed to simplexml_load_file is
http://mydomain.com/api/create.xml?api_number=brho15p6z1dhqwf5tsff&env=live&number=AJ20023232&title=Ford Mondeo 22'&image=http://mydomain.com/wp-content/uploads/2012/10/914955-150x150.jpg
but the API reports back the URL accessed as
http://mydomain.com/api/create.xml?api_number=brho15p6z1dhqwf5tsff&env=live&number=AJ20023232&title=Ford
If I remove the single quote then everything works fine, any idea how to correct this I suspect there's something I've overlooked when passing variables in the URL
It is the spaces in the "Ford Mondeo 22'" value that is causing the problem. You cannot have a spaces in the URL. You need to use escape characters. The encoded version of the parameter should be
Ford%20Mondeo%2022'
%20 is the escape character for space
I.e. the whole URL should read as follows:
http://mydomain.com/api/create.xml?api_number=brho15p6z1dhqwf5tsff&env=live&number=AJ20023232&title=Ford%20Mondeo%2022'&image=http://mydomain.com/wp-content/uploads/2012/10/914955-150x150.jpg
EDIT:
Your comment indicates that you use PHP. In PHP, you can use urlencode($foo) and urldecode($foo) to switch between the normal string and the encoding string.

Resources