Serverless.com Security
Reading time: 17 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.
Основна інформація
Організація
Організація є найвищим рівнем сутності в екосистемі Serverless Framework. Вона представляє колективну групу, таку як компанія, відділ або будь-яка велика сутність, яка охоплює кілька проектів, команд і додатків.
Команда
Команда - це користувачі з доступом всередині організації. Команди допомагають організувати учасників на основі ролей. Співпрацівники
можуть переглядати та розгортати існуючі додатки, тоді як Адміністратори
можуть створювати нові додатки та керувати налаштуваннями організації.
Додаток
Додаток - це логічна група пов'язаних сервісів в організації. Він представляє собою повний додаток, що складається з кількох безсерверних сервісів, які працюють разом для забезпечення єдиної функціональності.
Сервіси
Сервіс є основним компонентом безсерверного додатку. Він представляє ваш весь безсерверний проект, інкапсулюючи всі функції, конфігурації та ресурси, які потрібні. Зазвичай він визначається у файлі serverless.yml
, сервіс включає метадані, такі як назва сервісу, конфігурації постачальника, функції, події, ресурси, плагіни та користувацькі змінні.
service: my-service
provider:
name: aws
runtime: nodejs14.x
functions:
hello:
handler: handler.hello
Функція
Функція представляє собою одну безсерверну функцію, таку як функція AWS Lambda. Вона містить код, який виконується у відповідь на події.
Вона визначається в секції functions
у serverless.yml
, вказуючи обробник, середовище виконання, події, змінні середовища та інші налаштування.
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
Подія
Події - це тригери, які викликають ваші безсерверні функції. Вони визначають, як і коли функція повинна бути виконана.
Звичайні типи подій включають HTTP запити, заплановані події (cron jobs), події бази даних, завантаження файлів та інше.
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
- schedule:
rate: rate(10 minutes)
Ресурс
Ресурси дозволяють вам визначити додаткові хмарні ресурси, від яких залежить ваша служба, такі як бази даних, сховища або ролі IAM.
Вони вказуються в розділі resources
, часто використовуючи синтаксис CloudFormation для AWS.
resources:
Resources:
MyDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: my-table
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
Постачальник
Об'єкт Постачальник вказує на постачальника хмарних послуг (наприклад, AWS, Azure, Google Cloud) і містить налаштування конфігурації, що стосуються цього постачальника.
Він включає деталі, такі як середовище виконання, регіон, етап і облікові дані.
yamlCopy codeprovider:
name: aws
runtime: nodejs14.x
region: us-east-1
stage: dev
Стадія та Регіон
Стадія представляє різні середовища (наприклад, розробка, тестування, продуктивність), де ваш сервіс може бути розгорнутий. Це дозволяє налаштовувати та розгортати специфічні для середовища конфігурації.
provider:
stage: dev
Регіон вказує географічний регіон, де будуть розгорнуті ваші ресурси. Це важливо для розгляду затримки, відповідності та доступності.
provider:
region: us-west-2
Плагіни
Плагіни розширюють функціональність Serverless Framework, додаючи нові можливості або інтегруючись з іншими інструментами та сервісами. Вони визначені в секції plugins
і встановлюються через npm.
plugins:
- serverless-offline
- serverless-webpack
Шари
Шари дозволяють вам упакувати та керувати спільним кодом або залежностями окремо від ваших функцій. Це сприяє повторному використанню та зменшує розміри пакетів розгортання. Вони визначені в секції layers
і посилаються на функції.
layers:
commonLibs:
path: layer-common
functions:
hello:
handler: handler.hello
layers:
- { Ref: CommonLibsLambdaLayer }
Змінні та Користувацькі Змінні
Змінні дозволяють динамічну конфігурацію, дозволяючи використовувати заповнювачі, які вирішуються під час розгортання.
- Синтаксис:
${variable}
синтаксис може посилатися на змінні середовища, вміст файлів або інші параметри конфігурації.
functions:
hello:
handler: handler.hello
environment:
TABLE_NAME: ${self:custom.tableName}
- Користувацькі Змінні: Розділ
custom
використовується для визначення змінних та конфігурацій, специфічних для користувача, які можуть бути повторно використані вserverless.yml
.
custom:
tableName: my-dynamodb-table
stage: ${opt:stage, 'dev'}
Виходи
Виходи визначають значення, які повертаються після розгортання служби, такі як ARNs ресурсів, кінцеві точки або інша корисна інформація. Вони вказуються в розділі outputs
і часто використовуються для надання інформації іншим службам або для легкого доступу після розгортання.
¡outputs:
ApiEndpoint:
Description: "API Gateway endpoint URL"
Value:
Fn::Join:
- ""
- - "https://"
- Ref: ApiGatewayRestApi
- ".execute-api."
- Ref: AWS::Region
- ".amazonaws.com/"
- Ref: AWS::Stage
Ролі та дозволи IAM
Ролі та дозволи IAM визначають облікові дані безпеки та права доступу для ваших функцій та інших ресурсів. Вони керуються в рамках налаштувань provider
або окремих функцій для визначення необхідних дозволів.
provider:
[...]
iam:
role:
statements:
- Effect: 'Allow'
Action:
- 'dynamodb:PutItem'
- 'dynamodb:Get*'
- 'dynamodb:Scan*'
- 'dynamodb:UpdateItem'
- 'dynamodb:DeleteItem'
Resource: arn:aws:dynamodb:${aws:region}:${aws:accountId}:table/${self:service}-customerTable-${sls:stage}
Змінні середовища
Змінні дозволяють передавати налаштування конфігурації та секрети вашим функціям без їх жорсткого кодування. Вони визначені в секції environment
для постачальника або окремих функцій.
provider:
environment:
STAGE: ${self:provider.stage}
functions:
hello:
handler: handler.hello
environment:
TABLE_NAME: ${self:custom.tableName}
Залежності
Залежності керують зовнішніми бібліотеками та модулями, які потрібні вашим функціям. Вони зазвичай обробляються за допомогою менеджерів пакетів, таких як npm або pip, і упаковуються з вашим пакетом розгортання за допомогою інструментів або плагінів, таких як serverless-webpack
.
plugins:
- serverless-webpack
Hooks
Hooks дозволяють вам виконувати власні скрипти або команди в певні моменти життєвого циклу розгортання. Вони визначаються за допомогою плагінів або в serverless.yml
, щоб виконувати дії до або після розгортань.
custom:
hooks:
before:deploy:deploy: echo "Starting deployment..."
Tutorial
Це резюме офіційного навчального посібника з документації:
- Створіть обліковий запис AWS (Serverless.com починається в інфраструктурі AWS)
- Створіть обліковий запис на serverless.com
- Створіть додаток:
# Create temp folder for the tutorial
mkdir /tmp/serverless-tutorial
cd /tmp/serverless-tutorial
# Install Serverless cli
npm install -g serverless
# Generate template
serverless #Choose first one (AWS / Node.js / HTTP API)
## Indicate a name like "Tutorial"
## Login/Register
## Create A New App
## Indicate a name like "tutorialapp)
Це повинно було створити додаток під назвою tutorialapp
, який ви можете перевірити на serverless.com, а також папку під назвою Tutorial
з файлом handler.js
, що містить деякий JS код з кодом helloworld
, і файлом serverless.yml
, що оголошує цю функцію:
exports.hello = async (event) => {
return {
statusCode: 200,
body: JSON.stringify({
message: "Go Serverless v4! Your function executed successfully!",
}),
}
}
- Створіть постачальника AWS, перейшовши в dashboard за адресою
https://app.serverless.com/<org name>/settings/providers?providerId=new&provider=aws
. - Щоб надати
serverless.com
доступ до AWS, буде запропоновано запустити стек cloudformation, використовуючи цей конфігураційний файл (на момент написання): https://serverless-framework-template.s3.amazonaws.com/roleTemplate.yml - Цей шаблон генерує роль під назвою
SFRole-<ID>
зarn:aws:iam::aws:policy/AdministratorAccess
для облікового запису з довірчою ідентичністю, яка дозволяє обліковому записуServerless.com
AWS отримати доступ до ролі.
Yaml roleTemplate
Description: This stack creates an IAM role that can be used by Serverless Framework for use in deployments.
Resources:
SFRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: arn:aws:iam::486128539022:root
Action:
- sts:AssumeRole
Condition:
StringEquals:
sts:ExternalId: !Sub "ServerlessFramework-${OrgUid}"
Path: /
RoleName: !Ref RoleName
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess
ReporterFunction:
Type: Custom::ServerlessFrameworkReporter
Properties:
ServiceToken: "arn:aws:lambda:us-east-1:486128539022:function:sp-providers-stack-reporter-custom-resource-prod-tmen2ec"
OrgUid: !Ref OrgUid
RoleArn: !GetAtt SFRole.Arn
Alias: !Ref Alias
Outputs:
SFRoleArn:
Description: "ARN for the IAM Role used by Serverless Framework"
Value: !GetAtt SFRole.Arn
Parameters:
OrgUid:
Description: Serverless Framework Org Uid
Type: String
Alias:
Description: Serverless Framework Provider Alias
Type: String
RoleName:
Description: Serverless Framework Role Name
Type: String
Взаємовідносини довіри
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::486128539022:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "ServerlessFramework-7bf7ddef-e1bf-43eb-a111-4d43e0894ccb"
}
}
}
]
}
- У посібнику пропонується створити файл
createCustomer.js
, який в основному створить нову точку доступу API, оброблювану новим JS файлом, і пропонується змінити файлserverless.yml
, щоб він генерував нову таблицю DynamoDB, визначив змінну середовища, роль, яка буде використовувати згенеровані lambdas.
"use strict"
const AWS = require("aws-sdk")
module.exports.createCustomer = async (event) => {
const body = JSON.parse(Buffer.from(event.body, "base64").toString())
const dynamoDb = new AWS.DynamoDB.DocumentClient()
const putParams = {
TableName: process.env.DYNAMODB_CUSTOMER_TABLE,
Item: {
primary_key: body.name,
email: body.email,
},
}
await dynamoDb.put(putParams).promise()
return {
statusCode: 201,
}
}
- Розгорніть його, запустивши
serverless deploy
- Розгортання буде виконано через CloudFormation Stack
- Зверніть увагу, що lambdas доступні через API gateway і не через прямі URL
- Протестуйте це
- Попередній крок виведе URLs, де ваші функції lambda API endpoints були розгорнуті
Огляд безпеки Serverless.com
Неправильно налаштовані IAM ролі та дозволи
Занадто широкі IAM ролі можуть надати несанкціонований доступ до ресурсів хмари, що призводить до витоків даних або маніпуляцій з ресурсами.
Коли для функції Lambda не вказані дозволи, буде створено роль з дозволами лише на генерацію журналів, наприклад:
Мінімальні дозволи lambda
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogStream",
"logs:CreateLogGroup",
"logs:TagResource"
],
"Resource": [
"arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/jito-cranker-scripts-dev*:*"
],
"Effect": "Allow"
},
{
"Action": ["logs:PutLogEvents"],
"Resource": [
"arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/jito-cranker-scripts-dev*:*:*"
],
"Effect": "Allow"
}
]
}
Стратегії пом'якшення
- Принцип найменших привілеїв: Призначайте лише необхідні дозволи для кожної функції.
provider:
[...]
iam:
role:
statements:
- Effect: 'Allow'
Action:
- 'dynamodb:PutItem'
- 'dynamodb:Get*'
- 'dynamodb:Scan*'
- 'dynamodb:UpdateItem'
- 'dynamodb:DeleteItem'
Resource: arn:aws:dynamodb:${aws:region}:${aws:accountId}:table/${self:service}-customerTable-${sls:stage}
- Використовуйте окремі ролі: Розрізняйте ролі на основі вимог функцій.
Небезпечні секрети та управління конфігурацією
Зберігання чутливої інформації (наприклад, API ключів, облікових даних бази даних) безпосередньо в serverless.yml
або коді може призвести до витоку, якщо репозиторії будуть скомпрометовані.
Рекомендований спосіб зберігання змінних середовища у файлі serverless.yml
з serverless.com (на момент написання цього матеріалу) - використовувати постачальників ssm
або s3
, що дозволяє отримувати значення середовища з цих джерел під час розгортання та конфігурувати змінні середовища lambdas з текстом без значень!
caution
Тому будь-хто з дозволами на читання конфігурації lambdas всередині AWS зможе отримати доступ до всіх цих змінних середовища у відкритому тексті!
Наприклад, наступний приклад використовуватиме SSM для отримання змінної середовища:
provider:
environment:
DB_PASSWORD: ${ssm:/aws/reference/secretsmanager/my-db-password~true}
І навіть якщо це запобігає жорсткому кодуванню значення змінної середовища у файлі serverless.yml
, значення буде отримано під час розгортання і буде додано у відкритому тексті всередині змінної середовища lambda.
tip
Рекомендований спосіб зберігання змінних середовища за допомогою serveless.com - це зберігати їх у секреті AWS і просто зберігати ім'я секрету у змінній середовища, а код lambda повинен його зібрати.
Стратегії пом'якшення
- Інтеграція з Secrets Manager: Використовуйте сервіси, такі як AWS Secrets Manager.
- Зашифровані змінні: Використовуйте функції шифрування Serverless Framework для чутливих даних.
- Контроль доступу: Обмежте доступ до секретів на основі ролей.
Вразливий код і залежності
Застарілі або небезпечні залежності можуть вводити вразливості, тоді як неналежна обробка введення може призвести до атак ін'єкції коду.
Стратегії пом'якшення
- Управління залежностями: Регулярно оновлюйте залежності та скануйте на вразливості.
plugins:
- serverless-webpack
- serverless-plugin-snyk
- Валідація введення: Реалізуйте сувору валідацію та санітизацію всіх введень.
- Огляди коду: Проводьте ретельні огляди для виявлення недоліків безпеки.
- Статичний аналіз: Використовуйте інструменти для виявлення вразливостей у кодовій базі.
Недостатнє ведення журналів і моніторинг
Без належного ведення журналів і моніторингу злочинні дії можуть залишитися непоміченими, затримуючи реагування на інциденти.
Стратегії пом'якшення
- Централізоване ведення журналів: Агрегуйте журнали, використовуючи сервіси, такі як AWS CloudWatch або Datadog.
plugins:
- serverless-plugin-datadog
- Увімкніть детальне ведення журналів: Захоплюйте важливу інформацію, не розкриваючи чутливі дані.
- Налаштуйте сповіщення: Налаштуйте сповіщення для підозрілих дій або аномалій.
- Регулярний моніторинг: Постійно моніторте журнали та метрики на предмет потенційних інцидентів безпеки.
Небезпечні конфігурації API Gateway
Відкриті або неналежно захищені API можуть бути використані для несанкціонованого доступу, атак відмови в обслуговуванні (DoS) або атак між сайтами.
Стратегії пом'якшення
- Аутентифікація та авторизація: Реалізуйте надійні механізми, такі як OAuth, API ключі або JWT.
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
authorizer: aws_iam
- Обмеження швидкості та обмеження запитів: Запобігайте зловживанням, обмежуючи швидкість запитів.
provider:
apiGateway:
throttle:
burstLimit: 200
rateLimit: 100
- Безпечна конфігурація CORS: Обмежте дозволені джерела, методи та заголовки.
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
cors:
origin: https://yourdomain.com
headers:
- Content-Type
- Використовуйте веб-додатки брандмауерів (WAF): Фільтруйте та моніторте HTTP запити на наявність шкідливих шаблонів.
Недостатня ізоляція функцій
Спільні ресурси та недостатня ізоляція можуть призвести до ескалації привілеїв або ненавмисних взаємодій між функціями.
Стратегії пом'якшення
- Ізолюйте функції: Призначте окремі ресурси та ролі IAM для забезпечення незалежної роботи.
- Розподіл ресурсів: Використовуйте окремі бази даних або сховища для різних функцій.
- Використовуйте VPC: Розгорніть функції в межах віртуальних приватних хмар для покращеної мережевої ізоляції.
provider:
vpc:
securityGroupIds:
- sg-xxxxxxxx
subnetIds:
- subnet-xxxxxx
- Обмежте дозволи функцій: Переконайтеся, що функції не можуть отримати доступ або заважати ресурсам один одного, якщо це не є явно необхідним.
Недостатній захист даних
Незашифровані дані в спокої або в процесі передачі можуть бути розкриті, що призводить до витоків даних або підробки.
Стратегії пом'якшення
- Шифруйте дані в спокої: Використовуйте функції шифрування хмарних сервісів.
resources:
Resources:
MyDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
SSESpecification:
SSEEnabled: true
- Шифруйте дані в процесі передачі: Використовуйте HTTPS/TLS для всіх передач даних.
- Забезпечте безпечну комунікацію API: Вимагайте шифрувальні протоколи та перевіряйте сертифікати.
- Безпечно управляйте ключами шифрування: Використовуйте керовані сервіси ключів і регулярно змінюйте ключі.
Відсутність належної обробки помилок
Детальні повідомлення про помилки можуть розкрити чутливу інформацію про інфраструктуру або кодову базу, тоді як необроблені виключення можуть призвести до збоїв у додатку.
Стратегії пом'якшення
- Загальні повідомлення про помилки: Уникайте розкриття внутрішніх деталей у відповідях на помилки.
javascriptCopy code// Приклад у Node.js
exports.hello = async (event) => {
try {
// Логіка функції
} catch (error) {
console.error(error);
return {
statusCode: 500,
body: JSON.stringify({ message: 'Внутрішня помилка сервера' }),
};
}
};
- Централізована обробка помилок: Керування та санітизація помилок послідовно по всіх функціях.
- Моніторинг і ведення журналів помилок: Відстежуйте та аналізуйте помилки внутрішньо, не розкриваючи деталей кінцевим користувачам.
Небезпечні практики розгортання
Відкриті конфігурації розгортання або несанкціонований доступ до CI/CD конвеєрів можуть призвести до розгортання шкідливого коду або неправильних налаштувань.
Стратегії пом'якшення
- Забезпечте CI/CD конвеєри: Реалізуйте суворі контролі доступу, багатофакторну аутентифікацію (MFA) та регулярні аудити.
- Зберігайте конфігурацію безпечно: Тримайте файли розгортання без жорстко закодованих секретів і чутливих даних.
- Використовуйте інструменти безпеки інфраструктури як коду (IaC): Використовуйте інструменти, такі як Checkov або Terraform Sentinel, для забезпечення політик безпеки.
- Незмінні розгортання: Запобігайте несанкціонованим змінам після розгортання, приймаючи практики незмінної інфраструктури.
Вразливості в плагінах і розширеннях
Використання неперевірених або шкідливих сторонніх плагінів може ввести вразливості у ваші безсерверні додатки.
Стратегії пом'якшення
- Ретельно перевіряйте плагіни: Оцінюйте безпеку плагінів перед інтеграцією, віддаючи перевагу тим, що з надійних джерел.
- Обмежте використання плагінів: Використовуйте лише необхідні плагіни, щоб зменшити поверхню атаки.
- Моніторте оновлення плагінів: Тримайте плагіни оновленими, щоб скористатися патчами безпеки.
- Ізолюйте середовища плагінів: Запускайте плагіни в ізольованих середовищах, щоб обмежити потенційні компрометації.
Витік чутливих кінцевих точок
Публічно доступні функції або необмежені API можуть бути використані для несанкціонованих операцій.
Стратегії пом'якшення
- Обмежте доступ до функцій: Використовуйте VPC, групи безпеки та правила брандмауера для обмеження доступу до надійних джерел.
- Реалізуйте надійну аутентифікацію: Переконайтеся, що всі відкриті кінцеві точки вимагають належної аутентифікації та авторизації.
- Використовуйте API Gateway безпечно: Налаштуйте API Gateway для забезпечення політик безпеки, включаючи валідацію введення та обмеження швидкості.
- Вимкніть невикористовувані кінцеві точки: Регулярно переглядайте та вимикайте будь-які кінцеві точки, які більше не використовуються.
Надмірні дозволи для членів команди та зовнішніх співробітників
Надання надмірних дозволів членам команди та зовнішнім співробітникам може призвести до несанкціонованого доступу, витоків даних і зловживання ресурсами. Цей ризик посилюється в середовищах, де кілька осіб мають різні рівні доступу, що збільшує поверхню атаки та потенціал внутрішніх загроз.
Стратегії пом'якшення
- Принцип найменшого привілею: Переконайтеся, що члени команди та співробітники мають лише ті дозволи, які необхідні для виконання їхніх завдань.
Безпека ключів доступу та ліцензійних ключів
Ключі доступу та ліцензійні ключі є критично важливими обліковими даними, які використовуються для аутентифікації та авторизації взаємодій з CLI Serverless Framework.
- Ліцензійні ключі: Це унікальні ідентифікатори, необхідні для аутентифікації доступу до Serverless Framework версії 4, які дозволяють входити через CLI.
- Ключі доступу: Облікові дані, які дозволяють CLI Serverless Framework аутентифікуватися з панеллю управління Serverless Framework. Коли ви входите за допомогою
serverless
cli, ключ доступу буде згенеровано та збережено на ноутбуці. Ви також можете встановити його як змінну середовища з ім'ямSERVERLESS_ACCESS_KEY
.
Ризики безпеки
- Витік через репозиторії коду:
- Жорстке кодування або випадкове комітування ключів доступу та ліцензійних ключів у системи контролю версій може призвести до несанкціонованого доступу.
- Небезпечне зберігання:
- Зберігання ключів у відкритому тексті в змінних середовища або конфігураційних файлах без належного шифрування підвищує ймовірність витоку.
- Неправильне розповсюдження:
- Обмін ключами через незахищені канали (наприклад, електронна пошта, чат) може призвести до перехоплення зловмисниками.
- Відсутність ротації:
- Нерегулярна ротація ключів подовжує період експозиції, якщо ключі скомпрометовані.
- Надмірні дозволи:
- Ключі з широкими дозволами можуть бути використані для виконання несанкціонованих дій на кількох ресурсах.
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.