API Security
Vadim Markovtsev
Head of Analytics
How many account types do we have?
Account types in our product
How many user types do we have?
User types in our product
- Auth0, e.g.
github|2793551
- Athenian -
account_users
in sdb
- GitHub -
github.api_users
in mdb
- JIRA -
jira.users
in mdb
- Segment / Intercom -
athenian_api.identifies
in growth/postgres
How many authentication ways do we have?
Our authentication ways
- JSON Web Token (JWT)
- APIKey (PAT)
- GitHub
- OpenID Connect (aka enterprise)
JWT
APIKeys
- Limited to read-only requests.
How many user access levels do we have?
User access levels
- Default
- Not authenticated
- Read-only requests
- Regular
- Read-only requests
- Edit account's work types
- Admin
- Full control over the account
- God
- Can forge identity of any user
- Allow-listed manually
How many installation links do we have?
App links
- Invitation ID is encoded inside.
- Max number of invitations: 224
- That's 33,554,432 accounts.
- Algorithm: salty aligned ffx.
- Admin or regular.
- Can be disabled/enabled.
ATHENIAN_INVITATION_KEY
GitHub links
JIRA links
The key is the account's secret.
Attack
curl https://api.athenian.co/v1/metrics/pull_requests --data {
"account": 1, # 👍
"for": [{
"repositories": [
"github.com/athenianco/athenian-api", # 👍
"github.com/client/repo" # 😱
]}]...}
Defense
- Look up GitHub account(s) in
account_github_accounts
(sdb).
- Search every repo in
github.account_repos_log
(mdb).
- Custom code on every related endpoint.
- We also have JIRA.
athenianco/athenian-api/../../client/repo
Attack
curl https://api.athenian.co/v1/metrics/pull_requests --data {
"account": 1, # 👍
"for": [{
"repositories": [
"'; SELECT * FROM github.node_repository WHERE true OR name IN('" # 😱
"github.com/athenianco/athenian-api", # 👍
]}]...}
Defense
Use ORM! We use SQLAlchemy Core.
await mdb.fetch_all(
select([PullRequest])
.where(and_(
PullRequest.acc_id == account,
PullRequest.repository_full_name.in_(repos),
)))
JSON Schema
Swagger vs. OpenAPI
- OpenAPI = specification (Swagger specification before 2015)
- Swagger = JS tools tools to develop OpenAPI
Approaches to OpenAPI
- Write code
- Generate OpenAPI spec from code
- Write OpenAPI spec
- Generate code from OpenAPI spec
- 👍Faster, easier to develop
- 👎Not in sync, poor docs
- 👍Automatic validation
- 👎Autogenerated code sucks
What we check automatically
- Structure
- Missing or extra properties
- Value types
- Min/max [length, items]
- Regexp pattern
- Enum
- Date, datetime,
date_from < date_to
Aka "manhole"
Super powers
- Reject certain requests for certain accounts, users, IPs
- Quick A/B tests
- Debugging and diagnostics
Thank you, and see you tomorrow