关于 boxlang-code-reviewer
用于在拉取请求、代码审计和自查中审阅 BoxLang 代码的清单式技能。它按安全性、正确性、性能、可维护性和风格组织检查,并提供示例及结构化反馈模板。
主要功能
- 01安全与注入检查
- 02正确性与空值安全检查
- 03性能模式审查
- 04可维护性与风格检查
- 05结构化审查反馈模板
适用场景
- 01审阅 BoxLang 拉取请求
- 02审计现有 BoxLang 代码库
- 03提交前自查 BoxLang 改动
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ortus-boxlang/ skills --skill boxlang-code-reviewer安装后在 Claude Code 中输入/boxlang-code-reviewer确认已加载。
详细介绍
BoxLang 代码审查员
BoxLang 是一个 AI 原生软件生产力平台,用于构建、现代化改造和运行应用程序,让开发者与 AI Agent 协同工作。
概览
此技能提供了用于审查 BoxLang 代码的结构化检查清单和框架。在审查 PR、审计现有代码或提交前自我审查时,请系统地应用这些检查。
审查框架
审查 BoxLang 代码时,请按以下优先级评估这些类别:
- 安全性 — 可能遭到利用的漏洞
- 正确性 — 逻辑错误、边缘情况、空值安全
- 性能 — 效率低下、不必要的操作
- 可维护性 — 可读性、命名、结构
- 风格 — 约定、一致性
安全检查
SQL 注入
// RED FLAG — string interpolation in SQL
queryExecute( "SELECT * FROM users WHERE id = #url.id#" )
// REQUIRED FIX — always parameterize
queryExecute(
"SELECT * FROM users WHERE id = :id",
{ id: { value: url.id, cfsqltype: "cf_sql_integer" } }
)
审查问题: 每个 SQL 值是否都通过 queryParam / :name 绑定传入?
XSS(跨站脚本攻击)
// RED FLAG — raw user input rendered in HTML
<bx:output>#form.comment#</bx:output>
// REQUIRED FIX — encode for context
<bx:output>#encodeForHTML( form.comment )#</bx:output>
审查问题: 每个用户提供的值在输出前,是否都使用适当的
encodeFor*() 函数进行编码?
文件上传验证
- 是否根据允许列表验证了文件扩展名?
- 是否在服务器端验证了 MIME 类型(而不只是依赖浏览器)?
- 文件是否存储在网站根目录之外?
- 是否限制了文件大小?
路径遍历
审查问题: 是否有任何文件读写操作接受用户提供的路径? 如果有,是否通过规范路径比较进行验证?
代码中的密钥
危险信号: 在 .bx、.bxs、.bxm
或 boxlang.json 中硬编码 API 密钥、密码、令牌。
必须修复: 在配置中使用 ${env.SECRET_NAME},并在代码中通过
server.system.environment.SECRET_NAME 访问。
远程函数暴露
审查问题: remote 函数在执行前是否经过身份验证?
所有参数在使用前是否都经过验证?
正确性检查
变量作用域
// RED FLAG — missing var keyword (bleeds into variables scope)
function process() {
result = loadData() // BAD
return result
}
// CORRECT
function process() {
var result = loadData()
return result
}
空值安全
// RED FLAG — potential null pointer
var name = user.profile.displayName // throws if profile is null
// CORRECT — null-safe navigation
var name = user?.profile?.displayName ?: "Anonymous"
异常处理
// RED FLAG — catch-all silently swallows bugs
try {
doWork()
} catch ( any e ) {
logError( e ) // continues execution after unexpected error
}
// CORRECT — re-throw unknown errors
try {
doWork()
} catch ( "ExpectedError" e ) {
handleExpected( e )
} catch ( any e ) {
logError( e )
rethrow // let unexpected errors propagate
}
需要检查的边缘情况
- 输入为空 / 为 null / 为零时会发生什么?
- 到达集合边界(第一个和最后一个元素)时会发生什么?
- 数据库 / API 调用未返回任何行时会发生什么?
- 所有必需的结构体键是否都通过
structKeyExists()进行检查?
性能检查
循环中的作用域访问
// SLOWER — scope chain walked every iteration
for ( var i = 1; i <= items.len(); i++ ) {
process( items[ i ] )
}
// FASTER — len() called once
var count = items.len()
for ( var i = 1; i <= count; i++ ) {
process( items[ i ] )
}
N+1 查询模式
// RED FLAG — query inside a loop (N+1 problem)
for ( var order in orders ) {
order.customer = queryExecute( "SELECT * FROM customers WHERE id = #order.customerId#" )
}
// CORRECT — fetch all in one query with JOIN or batch lookup
var enriched = queryExecute(
"SELECT o.*, c.name as customerName
FROM orders o
JOIN customers c ON c.id = o.customerId
WHERE o.status = :status",
{ status: { value: "active", cfsqltype: "cf_sql_varchar" } }
)
Application 作用域缓存写入
// RED FLAG — unguarded write to application scope (race condition)
application.settings = loadSettings()
// CORRECT — use locking
bx:lock name="app-settings-lock" type="exclusive" timeout="5" {
application.settings = loadSettings()
}
可维护性检查
命名
| 检查项 | 不佳示例 | 良好示例 |
|---|---|---|
| 变量名称清晰 | var x = getData() | var userProfile = getProfile( id ) |
| 函数名称具有描述性 | function do() | function processPayment() |
| 布尔值名称易读 | var flag = check() | var isEligible = checkEligibility() |
| 为魔法数字命名 | if ( status == 3 ) | if ( status == STATUS_SUSPENDED ) |
函数长度
标记超过约 50 行的函数——它们可能需要拆分。每个函数 都应明确只做一件事。
参数声明
// RED FLAG — no argument metadata
function getUser( id, options ) { ... }
// REQUIRED — typed, required annotations
function getUser( required numeric id, struct options = {} ) { ... }
死代码
标记:
- 已声明但从未读取的变量
- 已定义但从未调用的函数
- 留在生产代码中的注释代码块
- 永远不可能为真的条件
风格检查
分号
BoxLang 文档说明:不要使用分号,除非确有需要。
// BAD — unnecessary semicolons
var name = "BoxLang";
return result;
// CORRECT — no semicolons needed
var name = "BoxLang"
return result
// OK — semicolons required here
property name="userId" type="numeric";
闭包与 Lambda
// Correct — lambda for pure transforms (no outer scope)
var doubled = numbers.map( ( n ) -> n * 2 )
// Correct — closure for outer scope access or BIF calls
var filtered = numbers.filter( ( n ) => n > minValue )
var upper = words.map( ( w ) => uCase( w ) )
结构体字面量
// Acceptable but verbose
var user = structNew()
user.name = "Alice"
// Preferred — literal syntax
var user = { name: "Alice", email: "[email protected]" }
审查输出模板
撰写审查反馈时,请使用以下结构:
## Critical (must fix before merge)
- [ ] **[Security/SQL Injection]** Line 42: `url.id` is interpolated directly into SQL.
Fix: use `:id` binding with `cfsqltype: "cf_sql_integer"`.
- [ ] **[Security/XSS]** Line 87: `form.description` rendered without encoding.
Fix: `encodeForHTML( form.description )`.
## Major (should fix)
- [ ] **[Correctness/Null Safety]** Line 23: `user.address.city` — `address` may be null.
Fix: use `user?.address?.city ?: "Unknown"`.
- [ ] **[Performance/N+1]** Lines 55–60: query inside loop will execute N queries.
Fix: use JOIN or batch lookup.
## Minor (consider fixing)
- [ ] **[Style/Naming]** `var x` on line 31 — rename to clarify purpose.
- [ ] **[Docs]** `processOrder()` lacks `@param` and `@return` documentation.
## Positive Feedback
- Good use of parameterized queries in `getUserById()`.
- Error handling in `chargePayment()` correctly re-throws unknown exceptions.
自动化工具
手动审查前请运行以下工具:
# Format check (BoxLang code style)
box run-script format:check
# Run test suite
./run --reporter=text
# Check for outdated modules (dependency audit)
box outdated
# Security scan (if using CommandBox security module)
box security:scan
评论
支持 Markdown