Stop IIS decoding %2f in URL - iis

There is an API endpoint in my application that accepts a string as a URL parameter that may contain a / encoded as %2f.
For example, GET http://localhost:5000/api/foo/some%2fstring
The controller action receives this parameter in its encoded state (some%2fstring), and is able to handle this as it sees fit.
However, once deployed to IIS, this breaks. IIS seems to decode the URL before passing it to Kestrel. The logs show something like this:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://example.com/api/foo/some/string application/json
Obviously, that pattern does not match the route, and the request 404s.
How can I prevent IIS from manipulating the URL before sending it to Kestrel?

Related

Express JS redirect with headers

Using express JS I'm trying to add some headers to the redirection I'm returning
However, everything I tried just work for the response headers and not for the request headers of the redirection. I.E., when inspecting it with the developer tools I can see the response headers but when the next call is made, I can not see the request headers
req.headers['x-custom-header'] = 'value'
res.setHeader('x-custom-header', 'value')
res.redirect('example.com')
Does anybody could explain how the response and request headers work on ExpressJS?
A redirect just does a redirect. It tells the browser to go to that new location with standard, non-custom headers. You cannot set custom headers on the next request after the redirect. The browser simply doesn't do that.
The usual way to pass some type of parameters in a redirect is to put them in a query string for the redirect URL or, in some cases, to put them in a cookie. In both cases of query string parameters and data in a cookie, those will be available to your server when the browser sends you the request for the redirected URL.
It also may be worth revisiting why you're redirecting in the first place and perhaps there's a different flow of data/urls that doesn't need to redirect in the first place. We'd have to know a lot more about what this actual operation is trying to accomplish to make suggestions there.
If your request is being processed by an Ajax call, then you can program the code receiving the results of the Ajax call to do anything you want it to do (including add custom headers), but if it's the browser processing the redirect and changing the page URL to load a new page, it won't pay any attention to custom headers on the redirect response.
Can anybody explain how the response and request headers work on ExpressJS?
Express is doing exactly what you told it to do. It's attaching the custom headers to the response that goes back to the browser. It's the browser that does not attach those same headers to the next request to the redirected URL. So, this isn't an Express thing, it's a browser thing.

Get absolute-form request target of HTTP request using WAI

The Request type provides accessors for the request method and the request version but not for the bit in between.
So if I have the following request:
GET http://www.example.org/index.html HTTP/1.1
I want the http://www.example.org/index.html in between
RFC7230 Section 5.3.2 allows for this when making a request to a proxy. Section 5.4 says that the Host header should be overriden by the proxy with the host in the URI if the request is in absolute-form. This seems good enough for me, I don't know if WAI would handle this correctly if a client was not behaving correctly and sending a Host header different from the absolute-form URI.
Alternatively, if this is not possible: I'd like to ask if there is a more low level HTTP library than WAI available in Haskell?
The rawPathInfo accessor method will provide this. See https://hackage.haskell.org/package/wai-3.2.2.1/docs/Network-Wai.html#v:rawPathInfo for details.
If you want the query string too, it's available via the rawQueryString accessor.
As for the host, HTTP requests don't normally look like your example (HTTP/1.1 clients will only look like that if they're connecting to a proxy, rather than to the destination Web server). Instead, they often look like this:
GET /index.html HTTP/1.1
Host: www.example.org
If you want http://www.example.org too, then you'll have to rebuild it yourself from the host and protocol information.

redirect and masking a domain on a restful api

so I'm very new to node.js and back-end.
I've just deployed a restful api on AWS just as a little test, it really does nothing special, only some get-post requests updating a json.
It works as expected.
Problem is: the address is of course very long so i also wanted to redirect the requests from a domain easy to remember.
And so i did.
If the domain is unmasked, it works fine, and i can for example get a json:
apiunmasked.pileoni.site/all
Settings on namecheap:
If i do try to mask it, it still works but the browser don't format it as a json:
api.pileoni.site/all.
Also there is something weird in the marging that happen with the masked version on the main page:
api.pileoni.site
apiunmasked.pileoni.site
I guess is some wrong setting on namecheap?
Thanks
Direct request to the EC2 do not adds the Content-Type header in HTTP response, so the browser tries to guess the datatype and correctly recognize and manages it as JSON.
The Namecheap forward service adds the header, probably falling back to "text/html", and the browser display the content as HTML.
Eventually, try to enforce the Content-Type header to "application/json" in your Node application with setHeader().

Node.js on OpenShift: Apache returns 404 for URLs with percent-encoded '/' characters

I have a very simple Node.js blog system running on OpenShift. When it reads metadata for a blog entry, it saves the title after passing it through encodeURIComponent. That percent-encoded string is then used as the post "key" in the URL.
For example:
I write a blog post, titled "post/with/slashes"
My blogging system reads the title from the metadata, and saves the blog post udner "post%2Fwith%2Fslahes"
My loving readers go to my-blog.io/post/post%2Fwith%2Fslahes in their web browsers
I'm using Express, and first of all I noticed that Express decodes the URL string before passing to my app (that is, my code finds the string "post/with/slashes" in the request parameters). So I pass it through encodeURIComponent again before looking up the post. I don't think that's relevant, but I've mentioned it just in case.
My problem: When I run a local instance (this is "standalone" Node.js, no Apache going on), this works fine. Express passes me "post/with/slashes", I pass that string through encodeURIComponent and I look up the post. But when I deploy to OpenShift, the request does not reach my app at all. I am served OpenShift's default 404 page, which says "The requested URL /post/post/with/slashes was not found on this server."
In summary: it looks like Apache is decoding the percent-encoded URL before passing it to Node.js. Since there are now slashes in the URL, Express doesn't know how to route the request to my app. Is this expected (and if so why)? If not, why might it be happening and what could I do about it?

Using http protocol between servers

I have a configuration of two servers working in intranet.
First one is a web server that produces html pages to the browser, this html sends requests to the second server, which produces and returns reports (also html) according to some GET parameter's value.
Since this solution is un-secured (the passed parameter is exposed) I thought about having the html (produced by the first server) sending the requests for report back to the first server, there, a security check will be made, and the request for report will be sent to the reports server using http between the servers, instead of from browser to server.
The report's markup will be returned to the first server (as a string?), added to the response object and presented in the browser.
Is this a common practice of http?
Yes, it's a common practice. In fact, it works the same when your webserver needs to fetch some data from a database (not publically exposed - ie not in the webserver DMZ for example).
But you need to be able to use dynamic page generation (not static html. Let's suppose your webserver allows PHP or java for example).
your page does the equivalent of an HTTP GET (or POST, or whatever you like) do your second server, sending any required parameter you need. You can use cURL libraries, or fopen(http://), etc.
it receives the result, checks the return code, can also do optionnal content manipulation (like replacing some text or URLs)
it sends back the result to the user's browser.
If you can't (or won't) use dynamic page generation, you can configure your webserver to proxy some requests to the second server (for example with Apache's mod_proxy).
For example, when a request comes to server 1 for URL "http://server1/reports", the webserver proxies a request to "http://server2/internal/reports?param1=value1&param2=value2&etc".
The user will get the result of "http://server2/internal/reports?param1=value1&param2=value2&etc", but will never see from where it comes (from his point of view, he only knows http://server1/reports).
You can do more complex manipulations associating proxying with URL rewriting (so you can use some parameters of the request to server1 on the request to server2).
If it's not clear enough, don't hesitate to give more details (o/s, webserver technology, urls, etc) so I can give you more hints.
Two others options:
Configure the Internet facing HTTP server with a proxy (e.g.
mod_proxy in Apache)
Leave the server as it is and add an Application Firewal

Resources