mirror of
https://github.com/prompt-security/clawsec.git
synced 2026-06-13 05:28:02 +03:00
7cdb4ab7e2
* docs: add agent collaboration and git safety rules to AGENTS.md
* fix(portability): harden cross-platform path handling and install workflows
- add shared path resolution utility for advisory guardian components
- expand and normalize home-path tokens: ~, $HOME, ${HOME}, %USERPROFILE%, $env:USERPROFILE
- reject unresolved/escaped home tokens to prevent literal "$HOME" directory creation
- fix install/runtime path handling in:
- openclaw-audit-watchdog setup_cron and suppression config loader
- clawsec-suite advisory hook handler, suppression loader, and guarded installer
- remove hardcoded Homebrew binary assumptions in watchdog scripts/tests
- add LF enforcement via .gitattributes to reduce CRLF script breakage
- expand CI Node checks to linux/macos/windows matrix
- add cross-platform test coverage for path expansion and token rejection
- update README and SKILL docs with bash/zsh/PowerShell-safe path guidance
- add compatibility deliverables:
- docs/COMPATIBILITY_REPORT.md
- docs/REMEDIATION_PLAN.md
- docs/PLATFORM_VERIFICATION.md
Validation:
- node skills/clawsec-suite/test/path_resolution.test.mjs
- node skills/clawsec-suite/test/guarded_install.test.mjs
- node skills/clawsec-suite/test/advisory_suppression.test.mjs
- node skills/openclaw-audit-watchdog/test/suppression_config.test.mjs
- node skills/openclaw-audit-watchdog/test/render_report_suppression.test.mjs
* fix(advisory): avoid fail-open on invalid path vars and cover watchdog tests
* docs: move signing runbooks into docs folder
* docs: remove root-level signing runbooks after move
* chore(clawsec-suite): bump version to 0.1.3
* chore(openclaw-audit-watchdog): bump version to 0.1.1
* docs(changelog): add entries for clawsec-suite 0.1.3 and watchdog 0.1.1
* docs(changelog): credit @aldodelgado for PR #62 contributions
* feat(clawsec-suite): scope advisories to openclaw application
* fix(ci): run advisory scope tests without TypeScript loader
---------
Co-authored-by: David Abutbul <David.a@prompt.security>
99 lines
2.9 KiB
JavaScript
99 lines
2.9 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Advisory application scope tests:
|
|
* - openclaw advisories are considered
|
|
* - nanoclaw advisories are ignored
|
|
* - legacy advisories without application remain eligible
|
|
*
|
|
* Run: node skills/clawsec-suite/test/advisory_application_scope.test.mjs
|
|
*/
|
|
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const LIB_PATH = path.resolve(__dirname, "..", "hooks", "clawsec-advisory-guardian", "lib");
|
|
const { advisoryAppliesToOpenclaw } = await import(`${LIB_PATH}/advisory_scope.mjs`);
|
|
|
|
let passCount = 0;
|
|
let failCount = 0;
|
|
|
|
function pass(name) {
|
|
passCount += 1;
|
|
console.log(`\u2713 ${name}`);
|
|
}
|
|
|
|
function fail(name, error) {
|
|
failCount += 1;
|
|
console.error(`\u2717 ${name}`);
|
|
console.error(` ${String(error)}`);
|
|
}
|
|
|
|
function testFindMatchesFiltersByApplicationScope() {
|
|
const testName = "advisoryAppliesToOpenclaw: openclaw + legacy advisories are considered";
|
|
|
|
const inputs = [
|
|
{ id: "ADV-OPENCLAW-001", application: "openclaw", expect: true },
|
|
{ id: "ADV-NANOCLAW-001", application: "nanoclaw", expect: false },
|
|
{ id: "ADV-LEGACY-001", expect: true },
|
|
];
|
|
|
|
for (const input of inputs) {
|
|
const result = advisoryAppliesToOpenclaw({ application: input.application });
|
|
if (result !== input.expect) {
|
|
fail(testName, `Unexpected result for ${input.id}: expected ${input.expect}, got ${result}`);
|
|
return;
|
|
}
|
|
}
|
|
|
|
pass(testName);
|
|
}
|
|
|
|
function testApplicationAllAccepted() {
|
|
const testName = "advisoryAppliesToOpenclaw: application=all is considered";
|
|
const result = advisoryAppliesToOpenclaw({ application: "all" });
|
|
if (!result) {
|
|
fail(testName, "Expected true for application=all");
|
|
return;
|
|
}
|
|
pass(testName);
|
|
}
|
|
|
|
function testFindMatchesAcceptsApplicationArray() {
|
|
const testName = "advisoryAppliesToOpenclaw: application array containing openclaw is considered";
|
|
const result = advisoryAppliesToOpenclaw({ application: ["nanoclaw", "openclaw"] });
|
|
if (!result) {
|
|
fail(testName, "Expected true for application array containing openclaw");
|
|
return;
|
|
}
|
|
|
|
pass(testName);
|
|
}
|
|
|
|
function testInvalidApplicationValueFallsBackCompat() {
|
|
const testName = "advisoryAppliesToOpenclaw: invalid application values keep legacy compatibility";
|
|
const result = advisoryAppliesToOpenclaw({ application: { invalid: true } });
|
|
if (!result) {
|
|
fail(testName, "Expected true for non-string application to preserve backward compatibility");
|
|
return;
|
|
}
|
|
pass(testName);
|
|
}
|
|
|
|
function runTests() {
|
|
console.log("=== ClawSec Advisory Application Scope Tests ===\n");
|
|
|
|
testFindMatchesFiltersByApplicationScope();
|
|
testApplicationAllAccepted();
|
|
testFindMatchesAcceptsApplicationArray();
|
|
testInvalidApplicationValueFallsBackCompat();
|
|
|
|
console.log(`\n=== Results: ${passCount} passed, ${failCount} failed ===`);
|
|
if (failCount > 0) {
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
runTests();
|