Documentation Mercado Libre

Check out all the necessary information about APIs Mercado Libre.
circulos azuis em degrade

Documentation

Last update 06/04/2026

Access control and authorization

The application integrating with Mercado Libre handles data from multiple sellers that must be protected. Without proper access control, a user could access data from sellers that do not belong to them, or perform actions for which they have no permission.

That is why we need to ensure:

Authorization principles

  • Least privilege: grant only the strictly necessary permissions.
  • Deny by default: if there is no explicit permission, access must be denied.
  • Backend verification: verifications must always be done on the server side, never trusting frontend validations. They must be performed through trusted sources such as the session, and not from parameters easily manipulated by a user.
  • Verification on each request: permissions must be validated on each operation before executing it.

Let's look at an example of each principle:

Least privilege:

INCORRECT:

All operators have administrator access
"Just in case they need something"

Problem: A compromised operator = full access

CORRECT:

Role "Orders Operator":
   ✅ View orders
   ✅ Update shipping status
   ❌ Modify prices
   ❌ Delete listings
   ❌ Manage users

Only has access to what is needed for their work.

Deny by default:

INCORRECT:

if (user.role == "blocked") {
    denyAccess();
}
// If not blocked, has access

Problem: New roles have access by default

CORRECT:

if (user.hasPermission("view_orders")) {
    allowAccess();
} else {
    denyAccess();  // By default, deny
}

If there is no explicit permission, there is no access.

Backend verification:

INCORRECT:

// Frontend (JavaScript)
if (user.role === "admin") {
    showAdminButton();
}

// Backend: Verifies nothing, trusts the frontend

Problem: Attacker can modify the JavaScript or call
directly to the API without going through the frontend.

CORRECT:

// Frontend (JavaScript)
if (user.role === "admin") {
    showAdminButton();
}

// Backend (on each request)
if (!user.hasPermission("admin_action")) {
    return error(403, "Unauthorized");
}

// Process only if permission granted

Verification on each request:

INCORRECT:

User logs in → Verified once → Has access to everything

Problem: If permissions change after login,
they are not reflected

CORRECT:

Each request:
   1. Verify that the session is valid
   2. Verify that the user has permission for
      this action
   3. Verify that the user has access to this seller
   4. Only then, process the request

Seller segregation

The integrating app must ensure that each user can only access the sellers assigned to them.

  • Establish a roles and permissions scheme that allows sellers to be assigned explicitly, so that each user can only manage the sellers they have been permitted to access.
  • Validate on each operation, before displaying or modifying data, that the account in question has access to that seller.
  • Validate the ability to answer the questions: "Who did what, from where, when and with what result?" with the logs available in each application feature.

Let's use the following example for greater clarity:

WITHOUT SEGREGATION:

YOUR SYSTEM
+-------------------------------------------+
|                                           |
|  John (op.) --> Seller A    OK            |
|             --> Seller B    [X] no perm.  |
|             --> Seller C    [X] no perm.  |
|                                           |
+-------------------------------------------+
Problem: John accesses sellers not assigned to him

WITH SEGREGATION:

YOUR SYSTEM
+-------------------------------------------+
|                                           |
|  John (op.) --> [Seller A] --> ALLOWED    |
|      |                                    |
|      +--[X]--> [Seller B] --> DENIED      |
|      |                                    |
|      +--[X]--> [Seller C] --> DENIED      |
|                                           |
+-------------------------------------------+
Only accesses the sellers assigned to them

Permissions management

  • Periodic review: audit permissions and perform access re-certification.
  • Immediate revocation: when a collaborator is removed, revoke access immediately.
  • Change log: document who granted/revoked what permission and when.
  • Separation of duties: the person who approves permissions should not be the one who requests them.

How can we verify that we follow the authorization principles?

  1. Create 2 test user accounts.
  2. Assign seller A to user 1.
  3. Assign seller B to user 2.
  4. Log in as user 1.
  5. Try to access seller B's data.
Note:
You can run this same test to iterate through the different roles and permissions you use.
Result Meaning
You can see seller B's data ❌ Your authorization scheme failed, you must adjust it until it no longer allows this
You can perform actions with a role that does not have specific permissions to do so ❌ Your authorization scheme failed, you must adjust it until it no longer allows this
Error 403 / 401 "Access denied" ✅ Your authorization scheme works
Error 404 "Not found" ✅ Your authorization scheme works with error handling that hides the existence of the resource

Prevention of unauthorized resource access (IDOR)

IDOR (Insecure Direct Object Reference) is one of the most common vulnerabilities. It occurs when a user can access another user's resources simply by changing an identifier in the URL or request.

Example: if the application shows orders at /orders/12345, an attacker could try /orders/123456 to view another seller's orders.

VULNERABLE TO IDOR:

# ❌ VULNERABLE TO IDOR:

@app.get("/orders/{order_id}")
def get_order(order_id: int):
    order = database.get_order(order_id)
    return order  # Does not verify if the user has access

# Problem: Anyone can view any order by changing the ID

Ideally, it should always be validated that the user making the request actually has permission to do so:

PROTECTED AGAINST IDOR:

# ✅ PROTECTED AGAINST IDOR:

@app.get("/orders/{order_id}")
def get_order(order_id: int, current_user: User):
    order = database.get_order(order_id)

    # Verify that the order belongs to the user's seller
    if order.seller_id not in current_user.allowed_sellers:
        raise HTTPException(403, "You do not have access to this order")
    return order

It is important to keep in mind the following protection mechanisms for this type of vulnerability:

  • Always validate ownership: before displaying or modifying a resource, verify that it belongs to the user/seller. In the case of employees or collaborators, ensure they have the necessary permissions to query resources for the corresponding seller.
  • Server-side validation: validation must always be on the backend side, not on the client (frontend).
  • Validate each endpoint: do not assume that if authentication passed, authorization is also granted.
  • Use session context: obtain the seller_id when resolving the session token and never from request parameters.

Resources to protect:

  • Purchase orders and sales information.
  • Listings.
  • Questions.
  • Messages.
  • Shipments.
  • Payments.
  • Any information or other non-public function exclusive to the seller.
FOR EACH TYPE OF RESOURCE, TEST:

  ( 1 ) Log in as User A
    |
    v
  ( 2 ) Access your own resource (e.g.: /orders/123)
    |
    v
  ( 3 ) Copy the URL
    |
    v
  ( 4 ) Log in as User B (in another browser)
    |
    v
  ( 5 ) Paste the URL of User A's resource

References


Glossary

Term Meaning
Authorization Verifying WHAT an already authenticated user can do (permissions, roles, resources)
RBAC Role-Based Access Control - Access control based on roles (admin, operator, viewer, etc.)
ABAC Attribute-Based Access Control - Access control based on attributes (department, location, schedule, etc.)
Principle of least privilege Giving each user only the strictly necessary permissions for their function
Privilege escalation Attack where a user obtains permissions they are not entitled to
Horizontal escalation Accessing resources of another user at the same level (e.g.: viewing another seller's orders)
Vertical escalation Obtaining permissions of a higher role (e.g.: regular user acts as admin)
Object-level authorization Verifying permissions at the level of each individual object/resource, not just at the endpoint level
Authorization bypass Evading access controls to perform unauthorized actions
Authorization middleware Code layer that verifies permissions before executing the endpoint logic
Access audit Recording who accessed what resource and when, to detect unauthorized access


Next: Application security.