WordPress.org

Make WordPress Core

Opened 9 years ago

Last modified 3 years ago

#19707 reopened enhancement

admin-ajax.php requests via http regardless of force_ssl_admin() state

Reported by: robertaccettura Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Administration Keywords:
Focuses: Cc:

Description

Noticing these requests failing:

"NetworkError: 403 Forbidden - http://HOSTNAMEwp-admin/admin-ajax.php"

My server explicitly denies http to wp-admin. SSL only.

Looks like admin_url() is giving http rather than https. I suspect this bug actually lies somewhere in get_site_url(), but I don't have time to triage this right now.

This is technically a security bug since WP should always obey force_ssl_admin(), but I don't think anything is being leaked or compromised. You don't get access to anything, and nothing being sent over the wire is sensitive since it still obeys the rules of the protocol (cookie is secure). It's just a nuisance.

Change History (8)

#1 @robertaccettura
9 years ago

  • Type changed from defect (bug) to enhancement

Further investigation shows this is likely a plugin creating these requests using:

var ajax_url = '<?php echo admin_url("admin-ajax.php", null); ?>';

This however is indicative of the lack of a proper ajax api on the frontend forcing plugin developers to resort to using an admin_url to serve their needs. This is problematic and conflicts with things like ssl admin.

May I suggest an equivalent wp-user-ajax.php for example and wp_user_ajax_my_action action? Switching existing plugins would be as trivial as swapping a few characters. This would be more secure since it encourages separation of wp-admin from user related functions.

#2 @kurtpayne
9 years ago

  • Cc kpayne@… added
  • Keywords reporter-feedback added

Can you use a tool like firebug or Chrome/Safari developer tools to see what "action" parameter is being passed to admin-ajax.php? This will tell you if it's from the core. If it's not from the core, the action parameter should give you a clue about which plugin is making the request.

#3 @lightningspirit
9 years ago

  • Component changed from Security to HTTP
  • Keywords has-patch dev-feedback added

The admin_url() and home_url() functions can override SSL in the second parameter passing 'http' or 'https' as parameters.

I suggest to create a ajax_url() function to choose either it should use 'https' or 'http' dynamically. Something like:

function ajax_url( $url, $scheme = null ) {
  // If $scheme is passed use it, otherwise test if the current request is HTTPS
  $scheme = $scheme ? $scheme : ( is_ssl ? 'https' : 'http' );
  return admin_url( "admin-ajax.php", $scheme );
}

That could be easier for developers! :)

#4 @dd32
7 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to worksforme
  • Status changed from new to closed

Calling admin_url( 'admin-ajax.php' ); without a scheme, or passing 'admin' (the default) as the scheme, will result in it respecting the SSL-for-admin.

A plugin developer can always override these and do things badly, but that's a plugin code issue, it's not something core can support (If a plugin requests something specific, we give it just as it asked for).

#5 @dd32
7 years ago

  • Component changed from HTTP to Administration
  • Keywords reporter-feedback has-patch dev-feedback removed

#6 @DrewAPicture
6 years ago

#27737 was marked as a duplicate.

#7 @letsdogood
3 years ago

  • Resolution worksforme deleted
  • Status changed from closed to reopened

Wouldn't it be more proper/correct to deduce the right scheme by default without needing to pass additional parameters?

This really is an averse side effect only because of the wordpress-specific quirk that for whatever historical reasons Ajax is somehow a function of / belongs under Admin, which arguably shouldn't be the case to begin with.

If at least admin_url('admin-ajax.php') could have an expected default behavior of *not* respecting force_ssl_admin() and would only be messing with the scheme in other-than-expected ways only when parameters are passed, it seems to me that would make much more sense from a web development / web application framework perspective.


Technicality question
Would such a change (making admin_url('admin-ajax.php') deduce the correct & expected scheme rather than force_ssl_admin()) break many websites?

Last edited 3 years ago by letsdogood (previous) (diff)

#8 @SergeyBiryukov
3 years ago

  • Milestone set to Awaiting Review
Note: See TracTickets for help on using tickets.