0

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)

ajlittoz
  • 111
  • 3
  • 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 – djdomi Dec 25 '21 at 15:39

1 Answers1

1

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.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63
  • 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. – ajlittoz Dec 25 '21 at 16:49
  • Yes, that is the approach. And yesm HTTP status code 401 triggers an authentication window in the browser. – Tero Kilkanen Dec 26 '21 at 08:42
  • I made a test: I send a `Status: 401 Unauthorized` header with no payload (but sending a complete `` block makes no difference) and this doesn't trigger the authentication dialog in the browser. What should I do then? – ajlittoz Dec 27 '21 at 18:01
  • To trigger authentication prompt, send `WWW-Authenticate: xxx` header. – ajlittoz Dec 27 '21 at 18:57
  • 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. – ajlittoz Dec 27 '21 at 19:05
  • You need to make sure nginx doesn't have any authentication directives in its config. – Tero Kilkanen Dec 28 '21 at 08:12
  • 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. – ajlittoz Dec 30 '21 at 17:28