逐日AI

面试题库

共 328 题,当前筛选 4 题。

7 天 MCP:把工具接进任何 Agent

D1 为什么需要一个协议:host / client / server 三角、JSON-RPC 消息与三种原语

  • MCP 规范为什么规定一个客户端只连一个服务端?多路复用不是更省资源吗?Why does the MCP spec require one client per server instead of multiplexing many servers over one connection?
    国内高频海外高频进阶#architecture#security

    分析过程 · 先想清楚再作答

    1. 这题看着在问性能,其实在问安全边界。只从连接数和资源占用切入的回答会被判为没读过设计原则那一节。
    2. 拆法:先问「共享一条通道之后,谁能看见谁」。规范写死了两条原则——服务端不应该读到整段对话,也不应该看得见别的服务端;一对一是实现这两条最直接的手段。
    3. 举一个具体后果:接一个第三方天气服务端时,一对一隔离让它只能看到你传的城市名;共享通道则可能让它读到你和内部数据库服务端之间的往来,那就是一次数据泄露。
    4. 结论:完整对话历史留在宿主,服务端只拿到这次真正需要的参数;宿主是唯一的安全边界执行者,也是唯一做跨服务端编排的地方。
    5. 代价要主动说:接 N 个服务端就有 N 条连接、N 套生命周期要管,客户端实现的复杂度大头正是在这里,而不是在发报文上。
    6. 可预期的追问:那多个服务端的工具重名怎么办?答案是聚合与消歧是宿主侧的职责,规范建议加服务端标识前缀,并且明确说不要依赖服务端自报的名字,因为它不保证唯一也未经验证。

    How to reason about it · think before answering

    1. It reads like a performance question but is really about security boundaries. Answering only in terms of connection count signals you never read the design principles.
    2. Ask who can see whom once a channel is shared. The spec fixes two principles: servers should not read the whole conversation, and should not see into other servers. One-to-one is the most direct way to enforce both.
    3. Concrete consequence: with isolation, a third-party weather server sees only the city you passed. On a shared channel it could observe traffic between you and an internal database server — a data leak.
    4. Conclusion: full history stays with the host, each server receives only the arguments this call needs, and the host is the single place where boundaries are enforced and cross-server orchestration happens.
    5. State the cost yourself: N servers means N connections and N lifecycles, and that is where most client complexity lives, not in sending messages.
    6. Likely follow-up: how do you handle tool name collisions across servers? Aggregation and disambiguation belong to the host; the spec suggests prefixing with a server identifier and explicitly warns against relying on the server's self-reported name, which is neither unique nor verified.

    答题要点

    • 一对一是安全设计而非性能设计:服务端读不到整段对话,也看不见别的服务端
    • 完整历史留在宿主,服务端只收到本次调用真正需要的参数
    • 跨服务端的聚合、消歧、授权都由宿主统一做,边界只有一处需要加固
    • 代价是连接与生命周期管理,这是客户端实现复杂度的主要来源

    Key points

    • One-to-one is a security decision, not a performance one: servers cannot read the conversation or see peers
    • Full history stays in the host; a server receives only the arguments for the current call
    • Aggregation, disambiguation, and authorization all happen in the host, so there is a single boundary to harden
    • The cost is connection and lifecycle management, which dominates client implementation complexity

D4 远程 MCP:Streamable HTTP 绑定、无状态模型与请求元数据、OAuth 2.1 授权、容器部署

  • Streamable HTTP 要求 Mcp-Method 头必须和请求体里的 method 一致。为什么要抄一遍?不校验会有什么风险?Streamable HTTP requires the Mcp-Method header to match the method in the request body. Why mirror it at all, and what breaks if the server does not validate the match?
    国内高频海外高频进阶#transport#security

    分析过程 · 先想清楚再作答

    1. 这题的题眼在后半句。只答「方便网关路由」是答了一半,面试官等的是「不一致会怎样」——能不能自己举出攻击场景,是区分「读过规范」和「理解规范」的地方。
    2. 先说为什么镜像:中间层不该为了做决策去解析请求体。负载均衡想按方法分流、限流器想给 tools/call 单独设阈值、可观测探针想打标签,只看头就够了,不用把几十 KB 的 body 反序列化一遍。同理还有 Mcp-Name(取自 params.name 或 params.uri)和 MCP-Protocol-Version。
    3. 再推风险:既然中间层按头决策、服务端按体执行,两个事实来源就分叉了。举个具体的:网关配了「tools/list 免鉴权、tools/call 要鉴权」,攻击者把头写成 tools/list、体写成 tools/call,鉴权就被绕过去了。同样的套路可以绕限流、绕审计、绕按参数值做的地域隔离。
    4. 结论:所以规范规定处理请求体的服务端必须校验头体一致,不一致必须回 400 加 -32020(HeaderMismatch)。这不是格式洁癖,是把「两个事实来源」重新合并成一个。
    5. 实现上有个坑值得主动说:头值只能是可见 ASCII,非 ASCII 的工具名或资源 URI 要用 =?base64?...?= 哨兵格式编码,服务端必须先解码再比对,否则自己的校验会把正常请求判成不一致。整数值应当按数值比较而不是按字符串比较。
    6. 可预期的追问:中间层自己要不要校验?规范建议按头做策略的中间层先确认 MCP-Protocol-Version 指向的是一个要求头体校验的版本,版本更老或头缺失时应当直接拒绝,而不是信任未经校验的头值。

    How to reason about it · think before answering

    1. The real question is the second half. 'It helps gateways route' is half an answer; the interviewer is waiting for a concrete attack, which separates having read the spec from having understood it.
    2. Why mirror: intermediaries should not parse the body to make decisions. A load balancer routing by method, a rate limiter capping tools/call, an observability probe tagging spans — all can read a header instead of deserializing tens of kilobytes. The same applies to Mcp-Name (from params.name or params.uri) and MCP-Protocol-Version.
    3. Then derive the risk: if intermediaries decide on the header and the server executes on the body, there are two sources of truth. Concretely, a gateway configured as 'tools/list is unauthenticated, tools/call is authenticated' is bypassed by sending the header as tools/list and the body as tools/call. The same trick evades rate limits, audit tagging, and per-parameter regional isolation.
    4. Conclusion: the spec therefore requires any server that processes the body to validate the match and reject with 400 plus -32020 (HeaderMismatch). It is not pedantry — it collapses two sources of truth back into one.
    5. Volunteer the implementation trap: header values are visible ASCII only, so non-ASCII tool names or resource URIs use the =?base64?...?= sentinel, and the server must decode before comparing or its own check will reject valid requests. Integer values should be compared numerically, not as strings.
    6. Likely follow-up: should intermediaries validate too? The spec advises that any intermediary enforcing policy from mirrored headers first confirm MCP-Protocol-Version names a revision that mandates header-body validation, and otherwise reject rather than trust unvalidated headers.

    答题要点

    • 镜像是为了让网关、限流器、探针不用解析请求体就能路由和打标签
    • 不校验就有两个事实来源:头写 tools/list、体写 tools/call 可以绕过按方法配置的鉴权与限流
    • 规范要求处理请求体的服务端必须校验一致性,不一致回 400 与 -32020
    • 非 ASCII 值用 base64 哨兵格式,服务端必须先解码再比对;整数按数值比较

    Key points

    • Mirroring lets gateways, rate limiters, and probes route and tag without parsing the body
    • Skipping validation creates two sources of truth: header tools/list with body tools/call bypasses per-method auth and limits
    • The spec requires any body-processing server to validate the match and return 400 with -32020 on mismatch
    • Non-ASCII values use the base64 sentinel, so decode before comparing; compare integers numerically
  • 为什么 MCP 服务端绝对不能把客户端给的访问令牌直接转发给下游 API?Why must an MCP server never forward the client's access token straight to a downstream API?
    国内高频海外高频深入#oauth#security

    分析过程 · 先想清楚再作答

    1. 这题在考安全边界的直觉。答「不安全」「会泄露」是空话;规范给这个反模式起了名字叫令牌转发(token passthrough),并明令禁止,能说出它坏在哪三处才算过关。
    2. 先把前提说清:MCP 服务端在授权体系里是 OAuth 2.1 的资源服务器,它必须校验收到的令牌受众就是自己(客户端靠 RFC 8707 的 resource 参数让授权服务器把受众写进令牌),并且必须只接受对自己资源有效的令牌,不得接受或转接其它令牌。
    3. 拆危害的角度是「谁的假设被打破了」。第一,绕过安全控制:限流、请求校验、流量监控往往挂在「这个令牌是发给我的」这个前提上,客户端拿着别处的令牌直连或经服务端转发,这些控制全空转。第二,审计链断裂:服务端分不清是哪个客户端在调(上游令牌对它可能是不透明的),下游日志里的身份又不是真正在转发的那个服务端,出事之后没人能还原现场;持有失窃令牌的人还能把服务端当成数据外泄的代理。第三,信任边界被打穿:下游是按「只有上游那个服务能拿到这个令牌」授信的,一旦某个服务被攻破,同一个令牌就能横着走。
    4. 结论:服务端要访问下游,就得自己作为 OAuth 客户端去拿一份属于自己的凭证,和客户端给自己的令牌完全隔离。
    5. 正确做法要一起说:需要代表用户访问第三方时走 URL 模式的补充输入,让用户在浏览器里直接和第三方完成授权,服务端把第三方令牌存在自己这边并绑定到已认证的用户身份。规范要求第三方凭证不得经由 MCP 客户端传输。
    6. 可预期的追问:那和混淆代理是什么关系?令牌转发是受众校验失败的下游后果,混淆代理是代理型服务端用静态 client id 加上跳过按客户端的同意确认造成的授权码劫持——两者都源于「服务端替别人做决定却没确认这个别人是谁」。这一条第 6 天会展开。

    How to reason about it · think before answering

    1. This probes your instinct for trust boundaries. 'It is insecure' is empty; the spec names this anti-pattern token passthrough and forbids it, so you need the three concrete failure modes.
    2. Set up the premise: in the authorization model an MCP server is an OAuth 2.1 resource server. It must validate that tokens were issued with itself as the audience — clients make that possible via the RFC 8707 resource parameter — and must accept only tokens valid for its own resources, accepting or transiting nothing else.
    3. Derive the harm by asking whose assumption breaks. First, security controls are circumvented: rate limiting, request validation, and traffic monitoring hang off 'this token was issued to me', and a token minted elsewhere makes them no-ops. Second, the audit trail breaks: the server cannot distinguish clients when the upstream token is opaque to it, downstream logs show an identity that is not the forwarding server, and a thief of a stolen token can use the server as an exfiltration proxy. Third, the trust boundary is punctured: downstream grants trust on the assumption that only the upstream service holds the token, so one compromise travels sideways.
    4. Conclusion: to call downstream, the server must obtain its own credential as an OAuth client, fully isolated from the token the client presented to it.
    5. Give the correct pattern too: for third-party access on the user's behalf, use URL-mode elicitation so the user authorizes the third party directly in a browser, and the server stores those tokens bound to the authenticated user identity. The spec requires third-party credentials never to transit the MCP client.
    6. Likely follow-up: how does this relate to the confused deputy? Token passthrough is the downstream consequence of failed audience validation, while the confused deputy is authorization-code hijacking caused by a proxy server combining a static client id with skipped per-client consent. Both come from a server acting for someone without confirming who that someone is.

    答题要点

    • MCP 服务端是 OAuth 2.1 资源服务器,必须校验令牌受众是自己,不得接受或转接其它令牌
    • 转发会绕过挂在受众上的限流、请求校验与流量监控
    • 审计链断裂:服务端分不清调用方,下游看到的身份也不是真正的转发者,还可能被当成外泄代理
    • 正确做法是服务端自己作为 OAuth 客户端取下游凭证,第三方凭证绝不经由 MCP 客户端

    Key points

    • An MCP server is an OAuth 2.1 resource server: it must validate that it is the token audience and must not accept or transit other tokens
    • Forwarding bypasses rate limiting, request validation, and monitoring that assume audience-bound tokens
    • The audit trail breaks: the server cannot identify callers, downstream sees the wrong identity, and the server can become an exfiltration proxy
    • The correct pattern is for the server to obtain its own downstream credential as an OAuth client, with third-party credentials never transiting the MCP client

D6 安全与治理:工具描述里的提示注入、混淆代理、最小权限、审计日志与工具白名单

  • 2026-07-28 之后协议是无状态的,服务端要保存状态就得铸一个句柄让客户端带回来。这会带来什么新的攻击面?怎么防?Since the protocol is stateless, a server that needs state mints a handle for the client to carry back. What attack surface does that create, and how do you close it?
    国内高频海外高频进阶#statelessness#security

    分析过程 · 先想清楚再作答

    1. 这题在考「换了机制之后有没有重新想过威胁模型」。上一版的会话劫持大家都熟,这一版会话没了,很多人就默认问题跟着消失了——其实只是换了个名字叫状态句柄劫持。
    2. 先描述攻击,四步很短:服务端为已认证用户铸一个句柄并放在工具结果里返回;攻击者拿到或猜到这个句柄;攻击者把它当成普通工具参数发过来;服务端没检查这个句柄属不属于调用者,于是操作了原用户的状态。
    3. 拆「拿到或猜到」这一层很关键,因为它决定了防线该架在哪。猜到,说明句柄可预测(自增 id、时间戳、短随机数);拿到,路径就多了——它出现在工具结果里,而工具结果会进模型上下文、会进日志、可能被另一个服务端看到,也可能被一次提示注入骗着吐出来。所以「句柄不会泄漏」这个假设不能要。
    4. 防线按规范分三层答。硬性的:实现了授权的服务端**必须**校验所有入站请求,并且**绝不能**把持有句柄当成身份认证——这是整题的题眼,句柄是名字不是凭证。应当层:用安全随机数生成,避免可预测或连续的标识,并设过期。最管用的一层也是应当:**在服务端把句柄绑定到已认证的主体**,比如存储的键做成「用户 id 加句柄」,用户 id 从校验过的令牌里取而不是客户端传,别的主体拿着同一个句柄来就查不到。这样即使猜中也冒充不了别人。
    5. 然后主动把 requestState 归到同一类:它是多轮请求里由服务端签发、经客户端转手带回的不透明状态,规范要求把它当成攻击者可控输入,用 HMAC 或 AEAD 做完整性保护、验签用定长比较,并把认证主体、原请求标识、短过期一起签进去,分别挡跨用户、跨请求和超时三种重放。
    6. 结论一句话:无状态没有消灭状态,只是把状态挪到了客户端手里,于是「谁能出示它」和「谁有权用它」必须被分开对待。
    7. 可预期的追问一:签名能不能保证一次性?不能,签名只缩小重放窗口,真要单次消费得在服务端加一层消费记录。追问二:多副本部署怎么办?句柄背后的数据本来就在共享存储里,requestState 只需要各副本共享签名密钥——这仍然是无状态的,因为服务端内存里没有为某个客户端留东西。

    How to reason about it · think before answering

    1. This checks whether you re-derived the threat model after the mechanism changed. Everyone knows session hijacking from the previous revision; sessions are gone now, so many assume the problem left with them. It only got renamed to state handle hijacking.
    2. Describe the attack in four steps: the server mints a handle for an authenticated user and returns it in a tool result; the attacker obtains or guesses it; the attacker sends it back as an ordinary tool argument; the server never checks whether the handle belongs to the caller and operates on the original user's state.
    3. Unpack 'obtains or guesses', because it decides where the defense goes. Guessing means the handle is predictable, such as a sequential id, a timestamp, or too little entropy. Obtaining has many paths: the handle appears in a tool result, so it enters the model context, the logs, possibly another server's view, and it can be coaxed out by a prompt injection. The assumption that handles stay secret is not available to you.
    4. Answer the defenses in the spec's tiers. Mandatory: servers implementing authorization MUST verify all inbound requests and MUST NOT treat possession of a handle as authentication. That is the crux, a handle is a name, not a credential. Recommended: generate handles from a secure random source, avoid predictable or sequential identifiers, and expire them. The most effective recommendation is binding: key server-side storage as user id plus handle, with the user id derived from the verified token rather than supplied by the client, and reject a handle presented by any other principal, so guessing it still buys nothing.
    5. Volunteer that requestState belongs to the same family: a server-signed opaque blob carried back through the client in multi round-trip requests, which the spec requires you to treat as attacker-controlled input, protect with HMAC or AEAD, verify with a constant-time comparison, and bind to the authenticated principal, an originating-request identifier, and a short expiry, covering cross-user, cross-request, and timeout replay.
    6. One-line conclusion: statelessness did not remove state, it moved it into the client's hands, so 'who can present it' and 'who is allowed to use it' must be judged separately.
    7. Likely follow-ups: does signing guarantee single use? No, it only bounds the replay window; true one-time consumption needs a server-side redemption record. And what about replicas? The data behind a handle already lives in shared storage, and requestState only needs a shared signing key, which is still stateless because nothing per client sits in a replica's memory.

    答题要点

    • 新攻击面叫状态句柄劫持:拿到或猜到句柄的人可以操作别人的状态
    • 句柄会出现在工具结果、上下文与日志里,不能假设它不泄漏
    • 硬性要求:必须校验所有入站请求,绝不能把持有句柄当成身份认证
    • 做法:安全随机、设过期、按「主体加句柄」在服务端绑定;requestState 同理,验签并签进主体与短过期

    Key points

    • The new surface is state handle hijacking: anyone who obtains or guesses a handle can act on another user's state
    • Handles surface in tool results, model context and logs, so secrecy is not a safe assumption
    • Mandatory: verify every inbound request and never treat possession of a handle as authentication
    • Use secure randomness, expiry, and server-side binding keyed by principal plus handle; requestState needs signing bound to principal and a short expiry