bugsbuny243/koschei-lang
GitHub: bugsbuny243/koschei-lang
一门在编译期强制执行能力安全模型的编程语言,通过显式传递权限 token 从根本上阻断依赖包的供应链攻击。
Stars: 1 | Forks: 0
# Koschei (`.ks`)
**一种具备能力安全(capability-secure)的编程语言。除非你显式传递 token,否则导入的包无法触碰你的磁盘、网络或环境。**
大多数供应链攻击之所以能够得逞,是因为依赖项继承了进程所拥有的所有权限。安装一个包,它就可以读取 `~/.ssh`、你的 `.env`,或者打开一个 socket —— 完全不需要请求。Koschei 消除了这种隐性权限:副作用访问权限是必须显式传递的值,如果程序试图获取未被授予的权限,编译器会予以拒绝。
Türkçe: [README.tr.md](README.tr.md)
## 60 秒体验
一个刻意包含恶意代码的包试图读取机密文件并将其返回给调用者。请在你的机器上亲自验证它根本无法运行。
```
git clone https://github.com/bugsbuny243/koschei-lang
cd koschei-lang
pip install .
ks check examples/supply_chain/main.ks
```
被测试的包 —— `examples/supply_chain/analytics.ks`:
```
fn track(event: String) -> String or Error {
let secret = disk.read("/etc/app/secrets.env") or return Error("unreadable")
return secret
}
```
输出:
```
KOSCHEI ERROR: KS2401 [line 6, column 18]: Required capability is unavailable
in this scope — A disk, network, environment, or process operation was
attempted without the corresponding capability token.
Hint: run 'ks --lang en explain KS2401' for details.
```
退出代码 `1`。程序根本没有运行。文件根本没有被打开。也没有向任何地方发送任何内容。
这并非是由运行时沙箱拦截了调用。在 `track` 内部根本不存在 `disk`,因此该攻击在编译阶段就会失败。
## 安装说明
需要 Python 3.12 或更高版本。没有其他依赖项 —— 安全语言不应增加你被迫信任的包的数量。
```
pip install git+https://github.com/bugsbuny243/koschei-lang
ks version
```
你的第一个程序:
```
ks new hello-koschei
cd hello-koschei
ks run .
```
`ks new` 会创建一个零依赖项目,包含 `koschei.toml` 和 `src/main.ks`。相关命令接受源文件、项目目录或 `koschei.toml` 路径作为参数。
## 核心理念
- **无隐性权限。** 对磁盘、网络、环境和进程的访问需要显式的 capability 值。未被传递该值的函数无法执行相应操作。
- **Capability 只能缩减,永远不会扩大。** `caps.disk` 是一个仅能用于授权的根 token;`caps.disk.allow(path)` 会生成一个缩减后的 token,且无法再将其扩大(`KS2403`),而根 token 无法直接执行 I/O 操作(`KS2402`)。
- **没有 `null`。** 可能缺失的值使用 `Option` 表示(`Some` / `None`)。
- **错误即值。** `Result` 搭配单一的 `or` 关键字具有三种形式:`or return`、`or default` 和 `or { block }`。未处理的错误值会导致编译错误(`KS1401`)。
- **默认不可变。** 重新绑定需要使用 `let mut`。
- **每个诊断信息都可解释。** 拥有 33 个带有双语文档的错误代码;`ks explain KS2401` 会打印出原因和修复建议。
## 示例
```
fn fetch_data(net: NetCaps, url: String) -> String or Error {
let response = net.get(url) or return Error("request failed")
return response.text()
}
fn main(caps: SystemCaps) {
let api_net = caps.net.allow("https://api.example.com")
let response = fetch_data(api_net, "https://api.example.com/v1")
println(response)
}
```
`fetch_data` 只能访问唯一的一个源。它无法触碰磁盘、读取环境变量或启动进程——这并不是因为它经过了审计且被发现没有这么做,而是因为它根本没有被赋予允许这样做的 token。
## Capability 清单
由于权限在源码中是显式的,因此可以通过机制自动生成摘要。`ks caps` 会报告整个模块图中程序能够访问的所有内容:
```
ks caps examples/app.ks
ks caps --json src/main.ks
ks caps --deny net src/main.ks # exits 2 if the program can reach the network
```
对于纯程序而言,该清单是空的,且这是一个可被验证的事实,而不仅仅是代码审查中的一个声明:
```
KOSCHEI CAPABILITY MANIFEST: examples/app.ks
This program carries no side-effect capability.
No disk, network, environment, or process access — pure computation.
```
`--deny` 门控专为 CI 设计:如果依赖项更新暗中增加了可访问范围,构建将会失败。
## 语言特性
目前已实现:带有类型参数的函数、`let` / `let mut`、结构体、`List`、不可变的 `Map`(`get`/`set`/`keys`/`contains`)、`for`-in、条件仅限 `Bool` 类型的 `if`/`else`/`while`、带有穷举 `match` 的枚举、真正的 `Option` / `Result`、完整的表达式插值(`"{items.length()}"`)、日常使用的标准库(`String` 的 `trim`/`split`/`join`,`List` 的 `sort`/`filter`/`contains`),以及一个模块系统:通过 `import risk` 即可绑定导入文件旁边的 `risk.ks` —— 无需清单、构建脚本或配置。
## 工具链
```
ks check src/main.ks # types, modules, capability rules
ks run src/main.ks # interpreter
ks build src/main.ks -o app # native binary via generated Go
ks fmt --write src/ # canonical formatting
ks caps src/main.ks # capability manifest
ks explain KS2401 # diagnostics, --lang tr for Turkish
ks check --json src/main.ks # stable code/message/line/column for editors
ks tokens / ks ast / ks emit-go
```
处理流水线为:`.ks` → lexer → parser → AST → 类型、capability 和不可变性检查 → Go 代码生成 → 原生二进制文件。诊断信息默认为英语;使用 `--lang tr` 或 `KOSCHEI_LANG=tr` 可以选择带有相同错误代码的土耳其语文档。
## 编辑器支持
`editors/vscode` 包含官方扩展:`.ks` 语法高亮、括号和注释规则、`Koschei: Check Current File` 命令,以及保存时的诊断功能。没有 npm 依赖。
## 测试
```
python -m unittest discover -s tests -v
```
321 个测试。其中被跳过的 33 个测试需要本地 Go 工具链,它们会在 CI 中运行——CI 会在每次推送和拉取请求时执行完整的测试套件,包括验证恶意的 `examples/supply_chain/` 包依然无法通过编译。
## 状态
Koschei 目前处于 **v0.9.0** alpha 阶段。它能够运行真实的多文件程序,并且 capability 模型得到了端到端的执行,但在 v1.0 之前,语法和运行时约定可能会发生变化。暂请勿用于生产环境。
原生路径中目前执行的安全边界包括:
- 安全的原生磁盘 ABI 针对的是 Linux 的 `openat` / `O_NOFOLLOW`。在没有安全等效方案的系统平台上,使用磁盘的构建会因 `KS4001` 而停止,而不是退而求其次使用较弱的安全性。
- 进程 capability 的 `run` / `spawn` 不会启动进程;它会返回一个错误值。
- 在运行时,路径遍历、符号链接逃逸和超出范围的路径会触发 `KS3402`;通过只读 token 进行写入会触发 `KS3404`;离开允许源的 HTTP 重定向会被拒绝;调用深度被限制为 512(`KS3105`)。
下一个里程碑是 **v1.0**:冻结的语法和 capability 运行时 ABI、SemVer 兼容性承诺、至少针对 `List` 和 `Option` 的泛型约定、带有锁文件的包解析,以及迁移测试。
**已设计但尚未构建**,且未作为特性展示的内容包括:静态区域推断(static region inference)、C 后端,以及 Sentinel / tarpit 层。Koschei 在其类型系统中执行 capability 约束——它并不生成形式化的数学证明,目前也不是一种基于区域进行内存管理的语言;当前的后端生成 Go 代码并使用 Go 的垃圾回收器。
## 贡献
目前最有用的事情就是编写一个真实的程序。用 Koschei 写点小程序,当语言阻碍了你时(比如缺少标准库函数、诊断信息令人困惑,或者某种本应通过编译的模式却失败了),请提一个 issue。带有能够复现问题的 `.ks` 文件的 Bug 报告是获得修复的最快途径。
## 许可证
MIT
标签:Golang, Python, 安全编程, 无后门, 日志审计, 权限控制, 编程语言, 编译器, 逆向工具