27

I am creating an API strcutured web application and in this application we have different layers which are doing their own job.

First layer is Validation layer which validate user input and if it passes the validation we move that to second layer (which is Access Control layer ) otherwise return the error message

Second layer is Access Control which checks if user has permission to perform the task it wants to perform, If user has permission it moves the request to next layer otherwise return error message

Third Layer is Controller Layer where we have the logic of application

My question is that is that ok to have validation layer before access control ? What if user are trying to perform a task which user doesn't have permission to and we are sending back validation error message ? User would be sending requests to an endpoint and talking with validation layer and once it passes the validation only then he would see the message You can't access this!

It feels strange to me so is it fine like this or what could be my other options in infrastructure this?

Muhammad
  • 399

6 Answers6

59

It depends on whether knowing the validity of some input for a task that you aren't permitted to do is a security leak. If it is, you really should to do it the other way round.

The only safe response to an unauthorised user is "access denied". If sometimes the response is "bad request" and other times "access denied", you are sending information to an unauthorised user.

As an example, you could have a check in the validation of the "delete document" task that the named document exists. Someone with no permissions would be able to discern whether something exists by attempting to delete it, and comparing which error they receive back. A particularly determined attacker could enumerate all document names (under a certain length), to see which exists.

Caleth
  • 12,190
25

Well, there are multiple types of validation:

  1. Cheap basic sanity-checking, which verifies that the request is not obviously malformed.

    This is typically at least partially duplicated client-side, to avoid futile round-trips.

    Anyway, it should be done before access-control to make things easier and less error-prone, as it doesn't risk any information-leak.

  2. More expensive validation which still does not depend on any protected application-data.

    If there is such extra-validation, it might be after access-control not to avoid leaking data, but to hinder DOS-attacks.
    Sometimes simply executing the request does some of that validation implicitly at reduced or no cost, so it might be left out here.

    If all the validation of the first step is duplicated, it might make sense to duplicate parts of this client-side too.

  3. Additional validation depending on the protected application-data.

    Doing it before access-control obviously risks information-leaks. Thus, first do access-control.

Deduplicator
  • 9,209
15

There must be some validation before access control. Let's say SO's API has an endpoint "edit answer", then whether the user can edit a particular answer can depend on the answer (below a certain reputation, a user can only edit his own answers). So the "answer ID" parameter being well-formed must be verified before the access control layer comes into play; possibly also that the answer exists.

OTOH, as Caleth and Greg mention, putting more extensive validation before access control is a potential security risk.

So the hard rules are

  1. You must not disclose any information through validation that the user is not supposed to be otherwise able to find out.
  2. You must validate data before access control can use it to the extent that access control needs it.

Following both these rules may mean that you have to have some validation before and some after access control.

6

In addition to the possible frustration of receiving an 'access denied' after validating input; also keep in mind that the Validation layer, unless it is a very simple one, can always need information from the Controller. Keeping this in mind, I believe positioning Validation behind Access Control, closer to Controller makes more sense.

simurg
  • 322
2

That depends on what you mean by validation layer - if by that you just mean checking the syntax of the request, that's safe and something you have to do anyway. If your 'validation' uses any information that an unprivileged user does not have access to, it is no longer safe.

You definitely should have a sanity checker before attempting access control, but you should take care to communicate very clearly to all maintainers (current and future) that this part must not use privileged information; Any such checks should be done in a separate validation step after authentication.

As a sanity check for the sanity checker, it should not actually have any code dependencies on any part of your code lower down the pipeline and should be separable into its own package that should be publicly publishable without any problems (other than possible legal issues). If you can't do that, your 'validation layer' is doing too much (or your codebase is a mess).

Cubic
  • 301
1

No. It is not ok.

If you have a bug in your validation layer it might bypass the security layer.

Its a common mistake to consider security as part of business requirements. "only users with the role sales, should be able to see the quarterly figures" seems like a business rule.

But if you want to be secure, you have to read such a rule as "only users in the sales role, should be able to run code on this endpoint" You have make sure your server always returns "access denied" before it gets to any kind of code you have written or files on the server.

Ewan
  • 83,178