慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
量子位
M
Microsoft Research Blog - Microsoft Research
Microsoft Azure Blog
Microsoft Azure Blog
Jina AI
Jina AI
罗磊的独立博客
V
Visual Studio Blog
Last Week in AI
Last Week in AI
阮一峰的网络日志
阮一峰的网络日志
IT之家
IT之家
aimingoo的专栏
aimingoo的专栏
雷峰网
雷峰网
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
博客园 - 三生石上(FineUI控件)
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MongoDB | Blog
MongoDB | Blog
小众软件
小众软件
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog

DEV Community

Autonomous Agents Need Receipts, Not Just Reasoning What 3.9M powerlifting records tell us about competition strategy — an EDA with Python Beyond the Context Window: How to Build a Self-Improving AI Agent with Persistent Memory Full Agentic Stack - 5 Ideias da Arquitetura 'AI-First' que Vão Mudar a Forma Como Você Desenvolve Software Supply Chain Attacks + Stale Credentials: Why This Combination Is So Dangerous in 2026 Daily Briefing Platform Banning Agent PRs Won't Save Open Source Hitting Merge: Mentally Preparing for Your First Push to Production Learning Progress Pt.17 Monitoring Containers on AWS ECS with CloudWatch Tier 4 — Entity and Authority: Wikidata, KG, sameAs threading LocalFind Gemma — AI-Powered Semantic Search and Chat for Your Local Files AI-dy: On-Device Emergency First Aid with Gemma 4 Datrix: Chat With Your Data Using Gemma 4 — Charts, ML Models, No Code Understanding Reinforcement Learning with Human Feedback Part 4: Teaching Models Human Preferences The Architect’s Pivot: Mastering Parallel Agent Orchestration with Antigravity 2.0 Quidditch - Powered By PostgreSQL and ASP.NET Build a Database Connection Framework In 133 Lines Of Code How I mapped 600+ GPS audio-guides as a solo dev (and why I finally did it after 8 years) Installing Terminal & WSL (Windows Subsystem for Linux) A Floating Productivity Panel I Built for Android The Microsecond Lie: Why your Go timers are lying about the GPU Google used 6,000 open-source contributors then locked the door. Classic. Terceira semana tentando voltar ao mercado de trabalho How I turned a Python function into a web app in one decorator I Got Tired of Heavy Design Tools… So I Built My Own 😩 The Google I/O 2026 Moment That Quietly Changed How I See AI Getting Started: Run Your First Local LLM in 5 Minutes Building a 1% Fee Web3 Marketplace for Study Notes: Is a 5% Shift Sustainable? Full Agentic Stack - 5 Ideias da Arquitetura 'AI-First' que Vão Mudar a Forma Como Você Desenvolve Software Build Club Week Four: the part of Themis Lex I never explained I Tried Google Antigravity 2.0 Here's What It Actually Feels Like to Code With AI Agents By Isaac Yakubu | Google I/O 2026 Challenge Submission The growth quest picks what you avoid, not what you're already good at Firebase AI Logic's Template-Only Mode Is the Security Feature We Actually Needed Hardware Guide: What Do You Actually Need to Run Local LLMs? Constitutional Exception Committees: A Pattern for AI Agent Constraint Governance Veltrix's Treasure Hunt Engine: Optimized for Long-Term Survival, Not Just Scalability Open WebUI: Your Local ChatGPT Build a streaming UI without overcomplicating it The Cost of Kernel CVE Patching Frequency in SLA Commitments Gemma 4 Runs on a Raspberry Pi. Let That Sink In. The Git Filesystem - Recreating the Content-Addressable Database Why I Still Believe Our Event-Driven Architecture Was The Right Call For Veltrix Local RAG: Chat With Your Documents (Open Source, Private) GGUF & Modelfile: The Power User's Guide to Local LLMs What Excited Me Most at Google I/O 2026 OSS assemble! Kilo Code is launching on Product Hunt. Join the launch! https://www.producthunt.com/products/kilocode Your Organizational AI Adoption Metrics Are Lying (Plus How to Measure Real Adoption) Building a Production-Grade MLOps Home Lab on Windows — K8s, LLM, RAG & GitLab CI The Moment I Realized AI Agents are Changing Software Forever
Dev.to 文章草稿第十三
ZNY · 2026-05-24 · via DEV Community

標題

二零二六年之API安全:毀滅生產系統之攻擊

標籤

安全,API,網絡開發,編程,後端,開發者安全運營

內容

二零二六年之API安全:真實毀滅生產系統之攻擊

每岁一周,有公司告其数据泄露。攻者非用零日或诡谲之毒,实乃利用旧岁已存之API漏洞。至二六年间,API安全犹为众团队所忽,而攻者知之。

吾昔半载,究析世实API之溃。此乃实击生产系统者。

OWASP API Top 10 未变(行业应对亦然)

OWASP API Security Top 10 貌似与 2019 年无甚异:

  1. 碎物层级授权 (Broken Object Level Authorization)
  2. 认证破损
  3. 碎物产权级授权
  4. 无节制之资源消耗
  5. 破损功能层级授权
  6. 批量赋值
  7. 安全配置不当
  8. 注入攻击
  9. 库存管理失当
  10. API不安全使用

此非空谈。十八月内,皆已见诸重大事件中遭利用。

攻击之壹:BOLA — 潜行数据窃取者

残缺之物授权,为数据泄露之患最甚。其弊常如一辙:API之端点暴露物之标识,而API不验其认证者果否为该物之主。

实例(简自实患)

// VULNERABLE API
app.get('/api/orders/:orderId', authMiddleware, async (req, res) => {
  const order = await Order.findById(req.params.orderId);
  res.json(order); // No ownership check!
});

// ATTACK: Iterate through order IDs
// curl https://api.example.com/api/orders/1
// curl https://api.example.com/api/orders/2
// curl https://api.example.com/api/orders/3
// ... extracted 50,000 customer records

入全景模式 出全景模式

如何革之

// SECURE API
app.get('/api/orders/:orderId', authMiddleware, async (req, res) => {
  // Explicit ownership check
  const order = await Order.findOne({
    _id: req.params.orderId,
    userId: req.user.id  // Always filter by owner
  });

  if (!order) {
    return res.status(404).json({ 
      error: 'Order not found' 
    });
  }

  res.json(order);
});

入全景模式 出全景模式

要义所在:恒验权属,非独验认证。认证非即授权于是物也

攻击之二者:认证有缺——JWT之失

JSON Web Tokens 普遍存在,且常被错误实现。此乃吾于生产API中所发现之JWT真实漏洞之例。

弱点:算法混淆

// VULNERABLE: Server accepts any algorithm
const decoded = jwt.verify(token, publicKey, {
  algorithms: ['HS256', 'RS256'] // DON'T DO THIS
});

// ATTACK: Change RS256 to HS256 and sign with the public key
// Since the server uses the SAME key for both symmetric and asymmetric,
// the attacker can forge tokens by signing HS256 with the RSA public key

入全屏模式 出全屏模式

// SECURE: Explicit algorithm allowlist
const decoded = jwt.verify(token, publicKey, {
  algorithms: ['RS256'] // Only allow the intended algorithm
});

入全景模式 出全屏模式

无缺隙:无算法

// VULNERABLE: Some libraries accept 'none' algorithm
jwt.verify(token, '', { algorithms: ['none'] }); 
// Produces: {"alg":"none","typ":"JWT"}
// becomes: eyJhbGciOiJub25lIiwidHlwIjoiand0In0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.

入全景模式 出全景模式

// SECURE: Explicitly reject 'none'
const decoded = jwt.verify(token, publicKey, {
  algorithms: ['RS256'],
  alloweds: { algorithms: ['HS256', 'RS256'] } // Reject none
});

// Or use a library that defaults to rejecting 'none'
const decoded = jwt.verify(token, publicKey);

入全景模式 出全景模式

攻击之三者:无节制资源消耗——钱包之拒

此术常被轻视,渐成常态。攻击者无需使汝之服务崩坏,但需令其运行昂贵即可.

现实之境

# VULNERABLE: No pagination, no limits
@app.get("/api/search")
def search(q: str):
    results = db.query(f"SELECT * FROM products WHERE name LIKE '%{q}%'")
    return results  # Returns ALL matches, attacker controls result set size

# Attack: Search for "a" - returns 2.3M rows
# Your database does a full table scan
# You pay $0.02 per query × 10,000 queries/minute = $200/minute

入全屏模式 出全屏模式

# SECURE: Strict pagination and query limits
@app.get("/api/search")
def search(
    q: str, 
    limit: int = Query(default=20, ge=1, le=100),  # Max 100
    offset: int = Query(default=0, ge=0, le=10000)  # Max offset
):
    # Parameterized query prevents injection
    results = db.query(
        "SELECT * FROM products WHERE name LIKE %s LIMIT %s OFFSET %s",
        (f"%{q}%", limit, offset)
    )

    # Also add query complexity limits
    if len(q) > 100:
        raise HTTPException(400, "Query too long")

    return results

入全屏模式 出全屏模式

密码重置拒绝服务攻击

# VULNERABLE: Email sending has no rate limit
@app.post("/api/password-reset")
def request_reset(email: str):
    user = db.find_user(email)
    if user:
        send_email(user.email, generate_token())  # No throttle
    return {"message": "If email exists, reset was sent"}

# Attack: Script 1000 emails/second to your SMTP provider
# Cost: $0.10 per email × 86,400,000 emails/day = $8.6M/day

入全屏模式 出全屏模式

# SECURE: Strict rate limiting per IP and email
from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)

@app.post("/api/password-reset")
@limiter.limit("3/hour")  # 3 attempts per hour per IP
def request_reset(email: str, request: Request):
    user = db.find_user(email)
    if user:
        send_email(user.email, generate_token())
    # Always return same message to prevent enumeration
    return {"message": "If email exists, reset was sent"}

入全屏模式 出全屏模式

攻击之四:批量赋值——隐秘参数

// VULNERABLE: Trusting client input blindly
app.post('/api/profile', authMiddleware, async (req, res) => {
  await User.updateOne(
    { _id: req.user.id },
    { $set: req.body }  // Client can set ANY field
  );
});

// ATTACK: Send this request
// POST /api/profile
// {"name": "John", "role": "admin", "isVerified": true, "creditLimit": 1000000}
//
// Suddenly the regular user is an admin with unlimited credit

入全景模式 出全景模式

// SECURE: Explicit field allowlist
app.post('/api/profile', authMiddleware, async (req, res) => {
  const allowedFields = ['name', 'bio', 'avatarUrl', 'timezone'];
  const updates = {};

  for (const field of allowedFields) {
    if (field in req.body) {
      updates[field] = req.body[field];
    }
  }

  await User.updateOne(
    { _id: req.user.id },
    { $set: updates }
  );

  res.json({ success: true });
});

入全景模式 出全景模式

攻击之五:无防护之管理员端点

# VULNERABLE: Admin endpoint without role check
@app.post("/api/admin/users/delete")
def delete_user(user_id: str):
    db.delete_user(user_id)
    return {"success": True}

# Attack: Anyone who finds this endpoint can delete any user
# No authentication, no authorization check

入全景模式 出全景模式

# SECURE: Explicit role requirement
from functools import wraps

def require_admin(f):
    @wraps(f)
    async def decorated(*args, **kwargs):
        if not request.user or request.user.role != 'admin':
            return {"error": "Forbidden"}, 403
        return await f(*args, **kwargs)
    return decorated

@app.post("/api/admin/users/delete")
@require_admin
@require_auth
def delete_user(user_id: str):
    db.delete_user(user_id)
    return {"success": True}

入全景模式 出全景模式

测试之框架,汝当用之

import httpx
import pytest

class TestAPISecurity:
    """API Security Test Suite - Run these against staging before every deploy"""

    def test_bola_object_level_access(self):
        """Test that users can't access other users' resources"""
        user1_token = self.get_token("user1@example.com")
        user2_resource = self.create_resource("user2@example.com")

        # User 1 tries to access User 2's resource
        response = httpx.get(
            f"{BASE_URL}/api/resources/{user2_resource.id}",
            headers={"Authorization": f"Bearer {user1_token}"}
        )

        assert response.status_code == 403, "BOLA vulnerability: User can access others' resources!"

    def test_jwt_algorithm_confusion(self):
        """Test JWT algorithm confusion attack"""
        token = self.get_valid_token()
        # Tamper with the algorithm
        header_b64 = base64.b64encode(b'{"alg":"HS256","typ":"JWT"}').decode()
        # Re-sign with a known key
        tampered = f"{header_b64}.{token.split('.')[1]}.{fake_signature}"

        response = httpx.get(
            f"{BASE_URL}/api/protected",
            headers={"Authorization": f"Bearer {tampered}"}
        )

        assert response.status_code == 401, "JWT algorithm confusion succeeded!"

    def test_mass_assignment_protection(self):
        """Test that users can't set admin fields"""
        user_token = self.get_token("regular@example.com")

        response = httpx.post(
            f"{BASE_URL}/api/profile",
            headers={"Authorization": f"Bearer {user_token}"},
            json={"name": "Test", "role": "admin", "isVerified": True}
        )

        # Verify admin fields weren't changed
        profile = self.get_profile("regular@example.com")
        assert profile["role"] != "admin", "Mass assignment vulnerability!"

    def test_rate_limiting(self):
        """Test that rate limiting prevents abuse"""
        for _ in range(100):
            response = httpx.post(
                f"{BASE_URL}/api/password-reset",
                json={"email": "test@example.com"}
            )

        # 101st request should be rate limited
        response = httpx.post(
            f"{BASE_URL}/api/password-reset",
            json={"email": "test@example.com"}
        )

        assert response.status_code == 429, "Rate limiting not enforced!"

Enter fullscreen mode Exit fullscreen mode

部署之前之安全检点

□ Object-level authorization tested for every endpoint
□ All JWT implementations use explicit algorithm allowlists
□ Rate limiting on all public endpoints
□ Pagination limits on all list endpoints
□ Mass assignment protection via field allowlists
□ Admin endpoints protected by role checks
□ No sensitive data in URL parameters (tokens, IDs)
□ SQL injection protection (parameterized queries)
□ No stack traces or internal errors in responses
□ CORS properly configured
□ Security headers present (CSP, X-Frame-Options, etc.)

Enter fullscreen mode Exit fullscreen mode

严酷之实情

二零二六年,API安全犹滞于应用安全数载。众团队多然:

  • 无API安全测试于CI/CD
  • 无API清单(汝有多少端点?汝竟不知耶?)
  • 八成端点无速率限制
  • 认证无授权之检

攻者知此。彼等规模化扫描此等弱点,自动化,昼夜不息。

佳音:治之非难。惟需将安测试尊为开发之要务耳。


汝之最大API安全之困也?于江湖间尝得有趣之漏洞乎?吾辈共论之。

再读之:OWASP API Security Top 10— 仍为 API 安全之根本要义之最佳发端。