Has anyone considered adding support for sites that require basic HTTP authorization?

We enforce HTTP auth on our site using the Secure Site module. If you configure linkchecker to ignore "401 authentication required" responses, the module is still usable. Basically, it still detects URLs which are broken vs. ones which require access; however, our logs are filled with 'access denied' warnings.

I started hacking around a bit. See attached patch.

NOTE: I tried to use drupal_http_request's ability to pass the user name and password prepended to the URL; however, it was failing upon re-tries for redirection. I'm not sure if that is a bug with drupal_http_request() or what.?.? Passing the credentials as part of the header instead seems to work though.

Feedback or thoughts?

CommentFileSizeAuthor
linchecker_httpauth.diff4.58 KBstacysimpson

Comments

hass’s picture

Status: Active » Needs review
hass’s picture

Version: 6.x-2.x-dev » 7.x-1.x-dev
Status: Needs review » Needs work

For getting a better understanding, why are you not adding an exception to Apache to pass localhost/known hosts without auth? However this sounds like a serious security problem... sending the passwords unencrypted on non-SSL sounds like a problem.

I have invalidated this patch with a few changes I made some minutes ago and it need to be done for D7 first.

hass’s picture

Found this in core drupal_http_request that looks like your patch do not need to handle this:

  // If the server url has a user then attempt to use basic authentication
  if (isset($uri['user'])) {
    $defaults['Authorization'] = 'Authorization: Basic ' . base64_encode($uri['user'] . (!empty($uri['pass']) ? ":" . $uri['pass'] : ''));
  }
hass’s picture

+++ includes/linkchecker.admin.inc	(working copy)
@@ -153,6 +153,13 @@
+  $form['check']['linkchecker_server_authentication_credentials'] = array(
+    '#default_value' => variable_get('linkchecker_server_authentication_credentials', ''),
+    '#type' => 'textarea',
+    '#title' => t('Use the specified credentials for various domains'),
+    '#description' => t('Use the following syntax: <servername>=<user>[:<password>]. (Ex. drupal.org=johndoe or drupal.org=johndoe:password)'),
+    '#wysiwyg' => FALSE,
+  );

The syntax should be more like the URLs are.

Example:

http://username:password@www.example.com/*
https://username:password@www.example.com/*

or:

http://username:password@www.example.com/
https://username:password@www.example.com/

This way we may just use string replace on urls and fire them with user credentials. However this would be limiting... We also need to handle other password in other directories... In this case root folder credentials (/*) will be used in any other folder except /foo and /bar. I believe we have some re-usable regexes for path matching in core blocks module.

https://username0:password0@www.example.com/*
https://username1:password1@www.example.com/foo/*
https://username2:password2@www.example.com/bar/*
stacysimpson’s picture

We haven't looked into the Apache by-pass alternative.

You are correct about security though...our site requires SSL, so it wasn't a big deal for us.

With regard to your suggestion to use the http://username:password@www.example.com/ format. Per my comments in the original submission, that technique doesn't seem to work with redirection due to the use of node aliases created by pathauto.

Or, at least I think that is the contributing factor.?.? Adding the HTTP Auth credentials directly to the header without relying on drupal_http_request() to do so does work. Seems like a bug in drupal_http_request() to me.

hass’s picture

Seems like a bug in drupal_http_request() to me.

Maybe, but otherwise it may be a critical security problem. It sounds wrong to me if the password get automatically send to the redirected link. Therefore I wonder why it works with the header... additional the drupal_http_request() has the same logic of sending your username/password than you have implemented... that is why I wonder that it does not work.

Only thinking out loud; If I ask your server for https://username:password@www.example.com/foo/bar and it answers with a 301 and url https://username:password@www.passwordsniffingdomain.com/foo.cgi and than you will have a critical security issue... this sounds like a big security hole to me. I think it's not correct way!

The redirect rule may need to take care of this password redirection. As you are the owner of your server you can create a redirect rule that also include the username/password... never done this, but it should be possible.

Above feature was just an idea to replace the URL and send the password to a domain... but now after more thinking I think this will add only security holes.

hass’s picture

http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_ht...

  // If the server URL has a user then attempt to use basic authentication.
  if (isset($uri['user'])) {
    $options['headers']['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (isset($uri['pass']) ? ':' . $uri['pass'] : ''));
  }
stacysimpson’s picture

Thanks for the feedback and I agree the security ramifications are a bit concerning. We used a built-in, internal account for this purpose as not to expose any actual account credentials.

We are using Drupal 6 and in that revision, http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_ht..., the $defaults object is not passed recursively to the drupal_http_request() method when performing re-tries (it only passes the redirected url and the original headers object). In Drupal 7, the $options object seems to be passed recursively, so I could foresee that alternative working. Haven't tried it though.

hass’s picture

I haven't tried it, but you say - it works in D7? How about backporting the required changes? Maybe core maintainers accept a patch as refactoring/bugfix...? Otherwise patch core and publish the patch... Let me know the case number, please. I guess it should not be difficult to backport the D7 version details and make it api compatible to D6... Maybe there is already a case open...

hass’s picture

Status: Needs work » Closed (won't fix)

Issue seems to be solved.