Mengurangkan 10 Ancaman Keselamatan API Teratas OWASP
Petakan ancaman API lazim kepada pertahanan FastAPI khusus untuk pengesahan rosak, BOLA dan tugasan besar-besaran.
Mengurangkan 10 Ancaman Keselamatan API Teratas OWASP ialah pelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Kem Intensif Pembangunan Bahagian Belakang FastAPI merangkumi sejumlah 4 pelajaran.
Mengapa OWASP API Security Top 10 Penting
OWASP API Security Top 10 ialah senarai terpilih risiko keselamatan paling kritikal yang dihadapi oleh API moden. Berbeza daripada OWASP Top 10 klasik untuk aplikasi web, senarai ini memberi tumpuan khusus kepada permukaan serangan API — termasuk penyalahgunaan pengesahan, pendedahan data berlebihan dan kelemahan penetapan massa.
FastAPI ialah rangka kerja yang berkuasa, tetapi ia tidak menjadikan API anda selamat secara lalai. Anda mesti menerapkan pertahanan dengan sengaja pada setiap lapisan: penghalaan, pengesahan, pengesahan identiti dan pensirian.
Dalam pelajaran ini, kita memberi tumpuan kepada tiga kategori berimpak tinggi:
- API1 — Broken Object Level Authorization (BOLA)
- API2 — Broken Authentication
- API6 — Mass Assignment
Setiap satunya mempunyai corak serangan yang tersendiri dan pengurangan risiko FastAPI yang nyata serta boleh anda gunakan hari ini.
Pengesahan Rosak: Permukaan Serangan
Broken Authentication (API2) berlaku apabila API gagal mengesahkan dengan betul bahawa pemanggil ialah orang yang didakwanya. Kegagalan yang biasa termasuk:
- Menerima JWT yang telah tamat tempoh atau diubah suai tanpa pengesahan tandatangan
- Menggunakan rahsia yang lemah atau boleh dijangka untuk menandatangani token
- Tidak menguatkuasakan tempoh tamat token (tuntutan
exp) - Membenarkan percubaan log masuk tanpa had (tiada had kadar)
Dalam FastAPI, corak yang paling boleh dipercayai ialah mengesahkan JWT dengan pustaka seperti python-jose atau PyJWT pada setiap laluan terlindung — menggunakan kebergantungan yang disuntik melalui Depends().
Pendekatan kebergantungan memusatkan logik pengesahan supaya anda tidak terlupa menerapkannya secara tidak sengaja pada laluan baharu.
Melaksanakan Kebergantungan Pengesahan JWT
Di bawah ialah kebergantungan JWT bergaya pengeluaran untuk FastAPI. Ia mengesahkan tandatangan token, menyemak tuntutan exp dan mencetuskan 401 bagi sebarang kegagalan. Suntikkannya ke dalam setiap laluan yang memerlukan pengesahan identiti.
Titik utama untuk memperkukuh keselamatan:
algorithms=[ALGORITHM]— benarkan secara jelas hanya HS256 (atau RS256); jangan sekali-kali hantaralgorithms=None- Rahsia mesti datang daripada pemboleh ubah persekitaran, bukan dikodkan secara keras
- Tuntutan
subyang tiada atau tidak sah dianggap sebagai token tidak sah
import os
from datetime import datetime, timezone
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
SECRET_KEY = os.environ["JWT_SECRET_KEY"] # never hardcode
ALGORITHM = "HS256"
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/token")
def get_current_user_id(token: str = Depends(oauth2_scheme)) -> int:
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id: str = payload.get("sub")
if user_id is None:
raise credentials_exception
return int(user_id)
except JWTError:
raise credentials_exceptionBOLA: Keizinan Tahap Objek Rosak
BOLA (API1) ialah kelemahan API nombor satu di seluruh dunia. Ia berlaku apabila pemanggil boleh mengakses mana-mana objek hanya dengan meneka ID-nya — kerana pelayan tidak pernah menyemak pemilikan.
Corak klasik yang terdedah:
GET /orders/9871Jika pelayan mendapatkan pesanan hanya berdasarkan order_id lalu mengembalikannya, mana-mana pengguna yang disahkan boleh membaca mana-mana pesanan dalam pangkalan data hanya dengan menambah nilai ID.
Penyelesaiannya sentiasa sama: selepas mendapatkan sumber, bandingkan pemilik sumber dengan pemanggil yang disahkan. Jika kedua-duanya tidak sepadan, pulangkan 403 Forbidden — bukannya 404, yang dalam sesetengah konteks boleh membocorkan maklumat tentang kewujudan sumber.
Membetulkan BOLA dalam Laluan FastAPI
Coraknya: dapatkan objek, kemudian sahkan pemilikan. Jangan sekali-kali melangkau semakan pemilikan kerana anda menganggap ID sukar diteka — UUID bukan kawalan keselamatan.
Perhatikan bahawa get_current_user_id daripada babak sebelumnya disuntik melalui Depends(). Pengesahan pemilikan ialah satu pernyataan if, tetapi ia merupakan baris paling penting dalam fungsi tersebut.
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.auth import get_current_user_id
from app.db import get_db
from app.models import Order
router = APIRouter()
@router.get("/orders/{order_id}")
async def get_order(
order_id: int,
current_user_id: int = Depends(get_current_user_id),
db: AsyncSession = Depends(get_db),
):
order = await db.get(Order, order_id)
if order is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Order not found")
# BOLA fix: verify the caller owns this resource
if order.user_id != current_user_id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Access denied")
return orderMenulis Pengawal BOLA yang Boleh Digunakan Semula
Apabila API anda mempunyai berpuluh-puluh titik akhir sumber, mengulangi semakan pemilikan secara sebaris mudah menyebabkan ralat. Ekstrakkannya ke dalam pembantu yang boleh digunakan semula dan mencetuskan pengecualian secara automatik. Ini mengurangkan kemungkinan pembangun terlupa melakukan semakan pada laluan baharu.
Pembantu ini cukup umum untuk berfungsi dengan mana-mana model SQLAlchemy yang mempunyai atribut user_id. Untuk peraturan pemilikan yang lebih kompleks (contohnya, akses berasaskan pasukan), luaskan fungsi ini dengan pertanyaan peranan/keizinan.
from fastapi import HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
async def get_owned_resource(model_class, resource_id: int, user_id: int, db: AsyncSession):
"""
Fetch a resource and assert ownership in one call.
Raises 404 if not found, 403 if the caller does not own it.
"""
resource = await db.get(model_class, resource_id)
if resource is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"{model_class.__name__} not found",
)
if resource.user_id != user_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="You do not have permission to access this resource",
)
return resourcePenetapan Massa: Serangan
Penetapan Pukal (API6) berlaku apabila API memetakan medan badan permintaan kepada model pangkalan data secara membuta tuli, lalu membolehkan penyerang menetapkan medan yang tidak pernah dimaksudkan untuk dikawal oleh pengguna.
Contoh klasik: pengguna mengemas kini profil mereka dan memasukkan "is_admin": true atau "balance": 99999 dalam badan JSON. Jika pelayan melaksanakan user.__dict__.update(request_data) tanpa penapisan, medan tersebut akan ditulis ke pangkalan data.
Dalam FastAPI, skema masukan Pydantic ialah pertahanan utama Anda. Skema ini bertindak sebagai senarai benarkan yang jelas: hanya medan yang diisytiharkan dalam skema boleh diterima daripada klien. Sebarang medan tambahan akan diabaikan secara senyap (atau ditolak, bergantung pada konfigurasi).
Memisahkan Skema Masukan dan Keluaran
Pola paling penting untuk mencegah penetapan pukal ialah menggunakan model Pydantic yang berasingan untuk masukan dan keluaran:
- Skema masukan — hanya medan yang dibenarkan untuk ditetapkan oleh pengguna
- Skema keluaran — semua medan yang selamat untuk dikembalikan kepada pemanggil
- Model pangkalan data — rekod penuh, termasuk medan sensitif seperti
is_admin,hashed_passworddan sebagainya.
Jangan gunakan skema yang sama untuk masukan dan keluaran jika kedua-duanya mempunyai keperluan keselamatan yang berbeza.
from pydantic import BaseModel, EmailStr
from typing import Optional
# What the client is ALLOWED to send when updating a profile
class UserUpdateInput(BaseModel):
display_name: Optional[str] = None
bio: Optional[str] = None
email: Optional[EmailStr] = None
# NOTE: is_admin, balance, role, hashed_password are NOT here
# What we return to the client (read-only fields visible but not settable)
class UserPublicOutput(BaseModel):
id: int
display_name: str
email: EmailStr
is_admin: bool
model_config = {"from_attributes": True}Menggunakan Skema Masukan dalam Laluan Kemas Kini
Dengan skema berasingan tersedia, laluan kemas kini menggunakan model_dump(exclude_unset=True) untuk mendapatkan hanya medan yang benar-benar dihantar oleh klien. Medan ini kemudiannya digunakan pada model pangkalan data satu demi satu — jangan sekali-kali melalui kemas kini pukal __dict__.
exclude_unset=True amat penting untuk semantik PATCH: ia memastikan medan yang tiada bermaksud "jangan ubah" dan bukannya "tetapkan kepada null".
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.auth import get_current_user_id
from app.db import get_db
from app.models import User
from app.schemas import UserUpdateInput, UserPublicOutput
router = APIRouter()
@router.patch("/users/me", response_model=UserPublicOutput)
async def update_profile(
payload: UserUpdateInput,
current_user_id: int = Depends(get_current_user_id),
db: AsyncSession = Depends(get_db),
):
user = await db.get(User, current_user_id)
if user is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
# Only apply fields the client actually provided
update_data = payload.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(user, field, value)
await db.commit()
await db.refresh(user)
return userMenguatkuasakan Penolakan Medan Tambahan
Secara lalai, Pydantic v2 mengabaikan medan yang tidak diketahui secara senyap. Untuk skema yang sensitif dari segi keselamatan, Anda boleh mengkonfigurasi model supaya menimbulkan ralat pengesahan jika medan yang tidak dijangka dihantar. Ini menjadikan percubaan penetapan pukal kelihatan dalam log dan mencegah kehilangan data secara senyap akibat kesilapan taip.
Tetapkan model_config = ConfigDict(extra='forbid') pada skema masukan Anda. API Anda akan mengembalikan 422 Unprocessable Entity jika klien menghantar sebarang medan yang tidak diisytiharkan dalam skema.
from pydantic import BaseModel, EmailStr, ConfigDict
from typing import Optional
class StrictUserUpdateInput(BaseModel):
model_config = ConfigDict(extra="forbid") # reject unknown fields
display_name: Optional[str] = None
bio: Optional[str] = None
email: Optional[EmailStr] = None
# Demonstration (runs standalone)
if __name__ == "__main__":
import json
from pydantic import ValidationError
# Valid input
valid = StrictUserUpdateInput(display_name="Alice")
print("Valid:", valid.model_dump(exclude_unset=True))
# Attacker tries to escalate privileges
try:
evil = StrictUserUpdateInput(display_name="Alice", is_admin=True)
except ValidationError as e:
errors = json.loads(e.json())
print("Blocked:", errors[0]["type"], "-", errors[0]["loc"])Menggabungkan Ketiga-tiga Pertahanan dalam Satu Aliran
Ketiga-tiga pertahanan ini berfungsi bersama sebagai lapisan. Begini cara ketiga-tiganya digabungkan dalam satu titik akhir kemas kini dokumen:
- Kebergantungan pengesahan — mengesahkan JWT dan mengekstrak
current_user_id(menangani Pengesahan Rosak) - Pemeriksaan BOLA — mendapatkan dokumen dan menegaskan
doc.owner_id == current_user_id(menangani BOLA) - Skema masukan dengan
extra='forbid'— hanya membenarkantitledancontentditetapkan (menangani Penetapan Pukal)
Setiap lapisan adalah bebas. Jika Anda membuang mana-mana satu daripadanya, dua lapisan yang lain masih memberikan perlindungan separa — tetapi ketiga-tiganya diperlukan untuk liputan penuh.
from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, ConfigDict
from typing import Optional
from sqlalchemy.ext.asyncio import AsyncSession
from app.auth import get_current_user_id
from app.db import get_db
from app.models import Document
router = APIRouter()
class DocumentUpdateInput(BaseModel):
model_config = ConfigDict(extra="forbid")
title: Optional[str] = None
content: Optional[str] = None
@router.patch("/documents/{doc_id}")
async def update_document(
doc_id: int,
payload: DocumentUpdateInput, # Layer 3: mass assignment guard
current_user_id: int = Depends(get_current_user_id), # Layer 1: auth
db: AsyncSession = Depends(get_db),
):
doc = await db.get(Document, doc_id)
if doc is None:
raise HTTPException(status_code=404, detail="Document not found")
if doc.owner_id != current_user_id: # Layer 2: BOLA guard
raise HTTPException(status_code=403, detail="Access denied")
for field, value in payload.model_dump(exclude_unset=True).items():
setattr(doc, field, value)
await db.commit()
await db.refresh(doc)
return docSemakan Pengetahuan: Mencegah BOLA
Titik akhir FastAPI mendapatkan invois berdasarkan ID-nya dan mengembalikannya kepada pemanggil. Titik akhir itu sudah memerlukan JWT yang sah. Langkah tambahan manakah yang penting untuk mencegah serangan BOLA (Kebenaran Tahap Objek yang Rosak)?
Ulang Kaji Pelajaran: Tiga Pertahanan, Satu API Selamat
Dalam pelajaran ini, Anda memadankan tiga ancaman OWASP API Security Top 10 dengan pertahanan FastAPI yang nyata:
- Pengesahan Rosak (API2) — pusatkan pengesahan JWT dalam kebergantungan
Depends(); senaraikan putih algoritma tandatangan; muatkan rahsia daripada pemboleh ubah persekitaran. - BOLA (API1) — selepas mendapatkan sebarang sumber, sentiasa tegaskan
resource.owner_id == current_user_id. Kembalikan403apabila tidak sepadan. Ekstrak pemeriksaan itu ke dalam pembantu yang boleh digunakan semula bagi mencegah keciciran. - Penetapan Pukal (API6) — gunakan skema Pydantic masukan dan keluaran yang berasingan; tetapkan
extra='forbid'pada skema masukan; gunakan kemas kini medan demi medan denganexclude_unset=True.
Ketiga-tiga pola ini bebas dan boleh digabungkan. Apabila digunakan bersama melalui sistem suntikan kebergantungan FastAPI, pola ini menghapuskan vektor serangan API yang paling lazim pada peringkat rangka kerja — sebelum satu baris logik perniagaan pun dijalankan.
Pelajari Kem Intensif Pembangunan Bahagian Belakang FastAPI dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 21
- Pelajaran
- 84
Soalan Lazim
Adakah pelajaran “Mengurangkan 10 Ancaman Keselamatan API Teratas OWASP” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI, termasuk “Mengurangkan 10 Ancaman Keselamatan API Teratas OWASP”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Kem Intensif Pembangunan Bahagian Belakang FastAPI merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Mengurangkan 10 Ancaman Keselamatan API Teratas OWASP”?
Petakan ancaman API lazim kepada pertahanan FastAPI khusus untuk pengesahan rosak, BOLA dan tugasan besar-besaran. Anda berlatih Kem Intensif Pembangunan Bahagian Belakang FastAPI menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Kem Intensif Pembangunan Bahagian Belakang FastAPI?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.
Berapa lamakah pelajaran “Mengurangkan 10 Ancaman Keselamatan API Teratas OWASP” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI ini?
Ya. Setiap pelajaran Kem Intensif Pembangunan Bahagian Belakang FastAPI menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Mengurangkan 10 Ancaman Keselamatan API Teratas OWASP
- Pengehadan Kadar dan Perlindungan Penyalahgunaan Bot
- Pengurusan Rahsia dan Putaran Kunci
- CORS, CSP dan Dasar Pengepala Selamat