Score:0

NginX: how to rewrite response body and headers?

in flag

Context

I have a collection of static HTML pages (~10k pages) generated by some application over which I have no control. These pages are served by NginX from a location block.

Pages may contain sensitive data. I would like to be able to block page display depending on user identity and "flags" in the page.

These flags can be implemented by a <meta name=keyword content="flag1 flag2 flagn"> element. When such an element is present, "credentials" should be checked.

My idea is to scan the request response before letting it be returned to the user. For this, I need

  • a way to pass the full response (header + body) to some custom code so that the <head> element can be parsed If there are no flags, the response is returned unaltered
    If there are flags and user has no credentials, he is asked to identify himself
    If there are flags and user has right to see, the response is returned unaltered
    If there are flags and user has no right to see, an error page is returned instead of the response


    Eventually, the flag <meta> element is erased to avoid leaking filter hints.

  • some way to pass to this user code information about the current credentials (user name, challenge value, any useful information like identification time-stamp, …)

The user code would rely on a "database" (this term doesn't necessarily imply the use of a true DB engine) containing user privileges and implement a timeout function.

Can the user code be implemented as a FastCGI script? If so, what are the directives to pass it the full response?

Preliminary trials

Presently user identification can't be conditional: when auth_basic is enabled in a location, users must identify themselves, even to access public pages. I can mitigate this by having a guest/guest user/password but I can't have a warning page before requesting credentials.

So, authentication is always required. Afterwards, an Authorization: Basic some_hash header is sent with the request. This hash needs to be captured when authentication occurs for future access to privilege properties of users.

How can I do it?

I am aware that in the present state, this specification offers no real security at all (vulnerable to replay attacks among others). I want to create a proof of concept before going further. Does my goal make sense?

Is there a simpler way to handle it? XSLT? (though the current user credentials must be fed into the patterns)

djdomi avatar
za flag
even if the question is good, i believe it is not suitable for serverfault.com, i think the web dev site that i am unfamiliar with, would be a better fit for you
Score:1
us flag

I think the only way to implement this is to use some front-end controller that checks the access logic requirements, and then sends the HTML files from disk.

You would not use any auth dirctives from nginx. The authentication process would be handled by the front-end controller.

The front-end controller can be implemented in several ways, for example Node.JS application, PHP, Ruby on Rails and Python.

ajlittoz avatar
in flag
This is what a friend suggested: handling the request through a "script" (Perl, Python, C, …) which retrieves the static page, decides whether credentials are needed and returns a "page" (either the requested page or a 401-page). I hope returning 401-code is enough to trigger browser identification dialog which will send a `Authentication:` header. This header will be used to store "live" information in the server and further `Authentication:` headers can be ignored. It all boils down to sending back an opaque one-time cookie for subsequent requests.
us flag
Yes, that is the approach. And yesm HTTP status code 401 triggers an authentication window in the browser.
ajlittoz avatar
in flag
I made a test: I send a `Status: 401 Unauthorized` header with no payload (but sending a complete `<html>` block makes no difference) and this doesn't trigger the authentication dialog in the browser. What should I do then?
ajlittoz avatar
in flag
To trigger authentication prompt, send `WWW-Authenticate: xxx` header.
ajlittoz avatar
in flag
But `xxx` must be `basic` to have an effect and NginX manifestly intercepts the authentication because the request with the `Authentication:` header never makes its way to my script.
us flag
You need to make sure nginx doesn't have any authentication directives in its config.
ajlittoz avatar
in flag
Because of the lack of details in documentation about processing of `WWW-Authenticate:` and interaction between browser and server, I'm considering handling this authentication phase myself. I'm presently focusing on security measures to prevent replay attacks and crafting fake authentication tokens. My main concern is designing an exchange such that for the same user/password, the message is never the same on successive attempts.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.