mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
test: guard raw HTTP2 with OpenGrep
This commit is contained in:
@@ -63,6 +63,7 @@ Local trust:
|
||||
|
||||
## Security
|
||||
|
||||
- Direct APNs delivery uses HTTP/2. OpenClaw code should use `connectApnsHttp2Session()` from `src/infra/push-apns-http2.ts` instead of raw `http2.connect()` so managed proxy mode can route APNs through the configured CONNECT proxy.
|
||||
- [Security overview](/gateway/security)
|
||||
- [Gateway config reference](/gateway/configuration)
|
||||
- [Troubleshooting](/gateway/troubleshooting)
|
||||
|
||||
@@ -1426,7 +1426,6 @@
|
||||
"lint:tmp:dynamic-import-warts": "node scripts/check-dynamic-import-warts.mjs",
|
||||
"lint:tmp:no-random-messaging": "node scripts/check-no-random-messaging-tmp.mjs",
|
||||
"lint:tmp:no-raw-channel-fetch": "node scripts/check-no-raw-channel-fetch.mjs",
|
||||
"lint:tmp:no-raw-http2-connect": "node scripts/check-no-raw-http2-connect.mjs",
|
||||
"lint:tmp:tsgo-core-boundary": "node scripts/check-tsgo-core-boundary.mjs",
|
||||
"lint:ui:no-raw-window-open": "node scripts/check-no-raw-window-open.mjs",
|
||||
"lint:web-fetch-provider-boundaries": "node scripts/check-web-fetch-provider-boundaries.mjs",
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import path from "node:path";
|
||||
import ts from "typescript";
|
||||
import { runCallsiteGuard } from "./lib/callsite-guard.mjs";
|
||||
import {
|
||||
collectCallExpressionLines,
|
||||
runAsScript,
|
||||
unwrapExpression,
|
||||
} from "./lib/ts-guard-utils.mjs";
|
||||
|
||||
const sourceRoots = ["src", "extensions"];
|
||||
const allowedRawHttp2ConnectCallsites = new Set([
|
||||
"src/infra/push-apns-http2.ts:39",
|
||||
"src/infra/push-apns-http2.ts:55",
|
||||
]);
|
||||
|
||||
function isHttp2ConnectCall(expression) {
|
||||
const callee = unwrapExpression(expression);
|
||||
if (!ts.isPropertyAccessExpression(callee) || callee.name.text !== "connect") {
|
||||
return false;
|
||||
}
|
||||
const receiver = unwrapExpression(callee.expression);
|
||||
return ts.isIdentifier(receiver) && receiver.text === "http2";
|
||||
}
|
||||
|
||||
export function findRawHttp2ConnectCallLines(content, fileName = "source.ts") {
|
||||
const sourceFile = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true);
|
||||
return collectCallExpressionLines(ts, sourceFile, (node) =>
|
||||
isHttp2ConnectCall(node.expression) ? node.expression : null,
|
||||
);
|
||||
}
|
||||
|
||||
export async function main() {
|
||||
await runCallsiteGuard({
|
||||
importMetaUrl: import.meta.url,
|
||||
sourceRoots,
|
||||
extraTestSuffixes: [".browser.test.ts", ".node.test.ts"],
|
||||
findCallLines: findRawHttp2ConnectCallLines,
|
||||
allowCallsite: (callsite) => allowedRawHttp2ConnectCallsites.has(callsite),
|
||||
skipRelativePath: (relPath) =>
|
||||
relPath === path.posix.join("src", "infra", "push-apns-http2.test.ts"),
|
||||
header: "Found raw http2.connect usage outside APNs proxy wrapper:",
|
||||
footer:
|
||||
"Use connectApnsHttp2Session() from src/infra/push-apns-http2.ts so APNs HTTP/2 honors managed proxy policy.",
|
||||
});
|
||||
}
|
||||
|
||||
runAsScript(import.meta.url, main);
|
||||
@@ -3,9 +3,9 @@
|
||||
# Auto-generated by security/opengrep/compile-rules.mjs.
|
||||
# DO NOT EDIT BY HAND. Re-run the compile script after editing source rules.
|
||||
#
|
||||
# Source rules dir: <unknown>
|
||||
# Generated at : 2026-04-29T07:10:35.427Z
|
||||
# Rule count : 147
|
||||
# Source rules dir: security/opengrep/rules/openclaw-policy
|
||||
# Generated at : 2026-04-30T09:09:41.198Z
|
||||
# Rule count : 148
|
||||
rules:
|
||||
- id: ghsa-25gx-x37c-7pph.openclaw-novnc-x11vnc-missing-auth
|
||||
message: x11vnc starts without VNC authentication; avoid -nopw and require password auth when exposing noVNC observer access.
|
||||
@@ -4976,3 +4976,37 @@ rules:
|
||||
- pattern-not-inside: |
|
||||
import { resolvePathWithinRoot, ... } from "$X";
|
||||
...
|
||||
- id: openclaw-policy-raw-http2-connect.no-raw-http2-connect
|
||||
languages:
|
||||
- typescript
|
||||
- javascript
|
||||
severity: ERROR
|
||||
message: Use connectApnsHttp2Session() from src/infra/push-apns-http2.ts instead of raw http2.connect() so APNs HTTP/2 honors managed proxy policy.
|
||||
metadata:
|
||||
advisory-id: OPENCLAW-POLICY-RAW-HTTP2-CONNECT
|
||||
advisory-url: https://github.com/openclaw/openclaw/pull/74905
|
||||
cwe:
|
||||
- CWE-441
|
||||
category: security
|
||||
confidence: HIGH
|
||||
detector-bucket: precise
|
||||
source-rule-id: no-raw-http2-connect
|
||||
source-file: security/opengrep/rules/openclaw-policy/no-raw-http2-connect.yml
|
||||
paths:
|
||||
include:
|
||||
- src/**/*.ts
|
||||
- src/**/*.mts
|
||||
- src/**/*.js
|
||||
- src/**/*.mjs
|
||||
- extensions/**/*.ts
|
||||
- extensions/**/*.mts
|
||||
- extensions/**/*.js
|
||||
- extensions/**/*.mjs
|
||||
exclude:
|
||||
- src/infra/push-apns-http2.ts
|
||||
- "**/*.test.ts"
|
||||
- "**/*.test.mts"
|
||||
- "**/*.test.js"
|
||||
- "**/*.test.mjs"
|
||||
patterns:
|
||||
- pattern: http2.connect(...)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
rules:
|
||||
- id: no-raw-http2-connect
|
||||
languages:
|
||||
- typescript
|
||||
- javascript
|
||||
severity: ERROR
|
||||
message: Use connectApnsHttp2Session() from src/infra/push-apns-http2.ts instead of raw http2.connect() so APNs HTTP/2 honors managed proxy policy.
|
||||
metadata:
|
||||
advisory-id: OPENCLAW-POLICY-RAW-HTTP2-CONNECT
|
||||
advisory-url: https://github.com/openclaw/openclaw/pull/74905
|
||||
cwe:
|
||||
- "CWE-441"
|
||||
category: security
|
||||
confidence: HIGH
|
||||
paths:
|
||||
include:
|
||||
- "src/**/*.ts"
|
||||
- "src/**/*.mts"
|
||||
- "src/**/*.js"
|
||||
- "src/**/*.mjs"
|
||||
- "extensions/**/*.ts"
|
||||
- "extensions/**/*.mts"
|
||||
- "extensions/**/*.js"
|
||||
- "extensions/**/*.mjs"
|
||||
exclude:
|
||||
- "src/infra/push-apns-http2.ts"
|
||||
- "**/*.test.ts"
|
||||
- "**/*.test.mts"
|
||||
- "**/*.test.js"
|
||||
- "**/*.test.mjs"
|
||||
patterns:
|
||||
- pattern: http2.connect(...)
|
||||
@@ -1,35 +0,0 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { findRawHttp2ConnectCallLines } from "../../scripts/check-no-raw-http2-connect.mjs";
|
||||
|
||||
describe("check-no-raw-http2-connect", () => {
|
||||
it("finds direct http2.connect calls", () => {
|
||||
const source = `
|
||||
import http2 from "node:http2";
|
||||
export function connect() {
|
||||
return http2.connect("https://api.push.apple.com");
|
||||
}
|
||||
`;
|
||||
|
||||
expect(findRawHttp2ConnectCallLines(source)).toEqual([4]);
|
||||
});
|
||||
|
||||
it("finds parenthesized or asserted http2 references", () => {
|
||||
const source = `
|
||||
import http2 from "node:http2";
|
||||
export function connect() {
|
||||
return (http2 as typeof import("node:http2")).connect("https://api.push.apple.com");
|
||||
}
|
||||
`;
|
||||
|
||||
expect(findRawHttp2ConnectCallLines(source)).toEqual([4]);
|
||||
});
|
||||
|
||||
it("ignores mentions in strings and comments", () => {
|
||||
const source = `
|
||||
// http2.connect("https://api.push.apple.com")
|
||||
const text = "http2.connect('https://api.push.apple.com')";
|
||||
`;
|
||||
|
||||
expect(findRawHttp2ConnectCallLines(source)).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user