wake-up-neo.net

Verstecken von WordPress REST API v2-Endpunkte können öffentlich angezeigt werden

Ich möchte die WordPress REST API v2 verwenden, um Informationen von meiner Site abzufragen. Ich habe festgestellt, dass ich beim direkten Aufrufen einer Endpunkt-URL alle Daten öffentlich sehen kann. Ich habe auch gesehen, dass in vielen Tutorials die Verwendung von Test- oder lokalen Servern anstelle von Live-Sites erwähnt wird.

Meine Fragen sind:

  • Soll dies an Standorten in der Produktion eingesetzt werden?
  • Besteht ein Sicherheitsrisiko, wenn Endpunkte von anderen Benutzern angezeigt werden, z. B. /wp-json/wp/v2/users/, in dem alle auf der Site registrierten Benutzer angezeigt werden?
  • Ist es möglich, nur autorisierten Benutzern den Zugriff auf einen Endpunkt zu erlauben?

Ich möchte sicherstellen, dass ich die Best Practices in Bezug auf die Sicherheit befolge. Daher sind Tipps hilfreich. Die API-Dokumente erwähnen die Authentifizierung, aber ich bin nicht sicher, wie ich den direkten Zugriff auf die URL verhindern soll. Wie richten andere Benutzer diese Daten normalerweise für den Zugriff durch externe Anwendungen ein, ohne zu viele Informationen preiszugeben?

11
Morgan

Soll dies an Standorten in der Produktion eingesetzt werden?

Ja! Viele Websites haben es bereits verwendet .

Besteht ein Sicherheitsrisiko, wenn Endpunkte von beliebigen Benutzern angezeigt werden, z. B./wp-json/wp/v2/users /, die alle auf der Site registrierten Benutzer anzeigen?

Nein! Serverantworten haben nichts mit Sicherheit zu tun. Was können Sie mit einem leeren Bildschirm/Nur-Lese-Zugriff tun? Nichts!

Wenn Ihre Websites jedoch schwache Kennwörter zulassen, gibt es einige Probleme . Es ist jedoch die Richtlinie Ihrer Website. Die REST -API weiß nichts darüber.

Ist es möglich, nur autorisierten Benutzern den Zugriff auf einen Endpunkt zu erlauben?

Ja! Sie können dies mit permission callback tun.

Zum Beispiel:

if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
    return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you cannot view this resource with edit context.' ), array( 'status' => rest_authorization_required_code() ) );
}

Wie richten andere Benutzer diese Daten normalerweise für den Zugriff durch externe Anwendungen ein, ohne zu viele Informationen preiszugeben?

Diese Frage ist schwer zu beantworten, da wir nicht wissen, was/wann zu viele Informationen ist. Aber wir verwenden alle Referenzen und Cheatsheets .

16
MinhTri

Ist es möglich, nur autorisierten Benutzern den Zugriff auf einen Endpunkt zu erlauben?

Es ist möglich, Ihrem API-Endpunkt einen benutzerdefinierten Berechtigungsrückruf hinzuzufügen, für den eine Authentifizierung erforderlich ist, um den Inhalt anzuzeigen. Nicht autorisierte Benutzer erhalten eine Fehlerantwort "code": "rest_forbidden"

Am einfachsten ist es, den WP_REST_Posts_Controller zu erweitern. Hier ist ein sehr einfaches Beispiel dafür:

class My_Private_Posts_Controller extends WP_REST_Posts_Controller {

   /**
   * The namespace.
   *
   * @var string
   */
   protected $namespace;

   /**
   * The post type for the current object.
   *
   * @var string
   */
   protected $post_type;

   /**
   * Rest base for the current object.
   *
   * @var string
   */
   protected $rest_base;

  /**
   * Register the routes for the objects of the controller.
   * Nearly the same as WP_REST_Posts_Controller::register_routes(), but with a 
   * custom permission callback.
   */
  public function register_routes() {
    register_rest_route( $this->namespace, '/' . $this->rest_base, array(
        array(
            'methods'             => WP_REST_Server::READABLE,
            'callback'            => array( $this, 'get_items' ),
            'permission_callback' => array( $this, 'get_items_permissions_check' ),
            'args'                => $this->get_collection_params(),
            'show_in_index'       => true,
        ),
        array(
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => array( $this, 'create_item' ),
            'permission_callback' => array( $this, 'create_item_permissions_check' ),
            'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
            'show_in_index'       => true,
        ),
        'schema' => array( $this, 'get_public_item_schema' ),
    ) );

    register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
        array(
            'methods'             => WP_REST_Server::READABLE,
            'callback'            => array( $this, 'get_item' ),
            'permission_callback' => array( $this, 'get_item_permissions_check' ),
            'args'                => array(
                'context' => $this->get_context_param( array( 'default' => 'view' ) ),
            ),
            'show_in_index'       => true,
        ),
        array(
            'methods'             => WP_REST_Server::EDITABLE,
            'callback'            => array( $this, 'update_item' ),
            'permission_callback' => array( $this, 'update_item_permissions_check' ),
            'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
            'show_in_index'       => true,
        ),
        array(
            'methods'             => WP_REST_Server::DELETABLE,
            'callback'            => array( $this, 'delete_item' ),
            'permission_callback' => array( $this, 'delete_item_permissions_check' ),
            'args'                => array(
                'force' => array(
                    'default'     => true,
                    'description' => __( 'Whether to bypass trash and force deletion.' ),
                ),
            ),
            'show_in_index'       => false,
        ),
        'schema' => array( $this, 'get_public_item_schema' ),
    ) );     
  }

  /**
   * Check if a given request has access to get items
   *
   * @param WP_REST_Request $request Full data about the request.
   * @return WP_Error|bool
   */
  public function get_items_permissions_check( $request ) {
    return current_user_can( 'edit_posts' );
  }

}

Sie werden feststellen, dass der Berechtigungsrückruf function get_items_permissions_checkcurrent_user_can verwendet, um zu bestimmen, ob der Zugriff zugelassen werden soll. Je nachdem, wie Sie die API verwenden, müssen Sie möglicherweise mehr über die Clientauthentifizierung erfahren.

Sie können dann Ihren benutzerdefinierten Beitragstyp bei der REST API-Unterstützung registrieren, indem Sie die folgenden Argumente in register_post_type hinzufügen.

  /**
   * Register a book post type, with REST API support
   *
   * Based on example at: http://codex.wordpress.org/Function_Reference/register_post_type
   */
  add_action( 'init', 'my_book_cpt' );
  function my_book_cpt() {
    $labels = array(
        'name'               => _x( 'Books', 'post type general name', 'your-plugin-textdomain' ),
        'singular_name'      => _x( 'Book', 'post type singular name', 'your-plugin-textdomain' ),
        'menu_name'          => _x( 'Books', 'admin menu', 'your-plugin-textdomain' ),
        'name_admin_bar'     => _x( 'Book', 'add new on admin bar', 'your-plugin-textdomain' ),
        'add_new'            => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
        'add_new_item'       => __( 'Add New Book', 'your-plugin-textdomain' ),
        'new_item'           => __( 'New Book', 'your-plugin-textdomain' ),
        'edit_item'          => __( 'Edit Book', 'your-plugin-textdomain' ),
        'view_item'          => __( 'View Book', 'your-plugin-textdomain' ),
        'all_items'          => __( 'All Books', 'your-plugin-textdomain' ),
        'search_items'       => __( 'Search Books', 'your-plugin-textdomain' ),
        'parent_item_colon'  => __( 'Parent Books:', 'your-plugin-textdomain' ),
        'not_found'          => __( 'No books found.', 'your-plugin-textdomain' ),
        'not_found_in_trash' => __( 'No books found in Trash.', 'your-plugin-textdomain' )
    );

    $args = array(
        'labels'             => $labels,
        'description'        => __( 'Description.', 'your-plugin-textdomain' ),
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => array( 'slug' => 'book' ),
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => null,
        'show_in_rest'       => true,
        'rest_base'          => 'books-api',
        'rest_controller_class' => 'My_Private_Posts_Controller',
        'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
    );

    register_post_type( 'book', $args );
}

Sie werden sehen, dass rest_controller_classMy_Private_Posts_Controller anstelle des Standardcontrollers verwendet.

Ich fand es schwierig, gute Beispiele und Erklärungen für die Verwendung der REST -API außerhalb der Dokumentation zu finden. Ich fand das großartig Erklärung für die Erweiterung des Standard-Controllers , und hier ist eine sehr gründliche Anleitung zum Hinzufügen von Endpunkten .

5
Dalton

Folgendes habe ich verwendet, um zu verhindern, dass alle nicht angemeldeten Benutzer die REST-API verwenden:

add_filter( 'rest_api_init', 'rest_only_for_authorized_users', 99 );
function rest_only_for_authorized_users($wp_rest_server){
    if ( !is_user_logged_in() ) {
        wp_die('sorry you are not allowed to access this data','cheatin eh?',403);
    }
}
1
squarecandy
add_filter( 'rest_api_init', 'rest_only_for_authorized_users', 99 );
function rest_only_for_authorized_users($wp_rest_server)
{
if( !is_user_logged_in() ) 

    wp_die('sorry you are not allowed to access this data','Require Authentication',403);
} } 
function json_authenticate_handler( $user ) {

global $wp_json_basic_auth_error;

$wp_json_basic_auth_error = null;

// Don't authenticate twice
if ( ! empty( $user ) ) {
    return $user;
}

if ( !isset( $_SERVER['PHP_AUTH_USER'] ) ) {
    return $user;
}

$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];


remove_filter( 'determine_current_user', 'json_authenticate_handler', 20 );

$user = wp_authenticate( $username, $password );

add_filter( 'determine_current_user', 'json_authenticate_handler', 20 );

if ( is_wp_error( $user ) ) {
    $wp_json_basic_auth_error = $user;
    return null;
}

$wp_json_basic_auth_error = true;

return $user->ID;}add_filter( 'determine_current_user', 'json_authenticate_handler', 20 );
0
dipen patel