Once a user authenticates wrong (sends a basicAuth string that does not match the database), the 403 (forbidden) page is cached for all subsequent calls to the token url. Also when the credentials are valid.

I've installed the Cache Exclude module for this https://drupal.org/project/cacheexclude
But that seems like overkill for only an authentication url.

I'll try to come up with a patch in the following days, with the method described below.

Use hook_boot() to be ahead of all modules and themes.
Check the path using drupal_match_path()
Set drupal_page_is_cacheable(FALSE)

Comments

klausi’s picture

Status: Active » Postponed (maintainer needs more info)

You don't need the token URL if you are using Basic Authentication. Getting a token is only required for requests using session cookies to protect against CSRF attacks.

So caching that 403 is correct, since the page cache is only used for anonymous users and they do not need a token either.

Neograph734’s picture

Maybe we've misunderstood the concept then. I was assuming that I'd set the base64 header once, the basic_auth modules logs me in, and from there I could use the token and the session cookie. That seemed like a safer approach then sending decodable credentials on every request. Besides, we have an LDAP provisioning module running on login, so I'd rather prevent that from fetching all data over and over again.

I understand that when someone sends wrong credentials to the server it responds with a 403. Expected behavior. But when I send wrong credentials the whole token function is not accessible anymore and Drupal immediately jumps to the 403 page.

(It makes sense because when I send credentials in base64 I basically login on every request. So at the time I make the request I am in fact anonymous.)

Every request will result in the cached 403 even if the credentials are valid. One could deliberately lock down the whole API with this. Therefor I think this page should never be cached.

klausi’s picture

The concept of Basic Authentication is that you send the credentials on every request. Yes, that will result in a user login on every request.

If you want to use cookie authentication then you should not use the restws_basic_auth module. Just send a login POST request to /user with 'form_id' => 'user_login_form' + user + password and you will get back a session cookie that you can then use in subsequent requests. A Guzzle example how to do this is available in the Drupal 8 REST documentation: https://drupal.org/node/2076725

Neograph734’s picture

Thanks! We'll look into that.

We took this approach because of the comment below your documentation page: https://drupal.org/node/1860564 where this is described.
I've added a comment with links to this page and the D8 page for reference.

But as I stated before, I still believe there is a vulnerability here where one could send a random base64 string to the token url locking down all future request. Please test this.

klausi’s picture

Category: Bug report » Support request
Status: Postponed (maintainer needs more info) » Fixed

No vulnerability here, since the 403 is only cached for anonymous users, which don't need the token anyway.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.