41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
import type { DevToolbarRule } from "./types.ts";
|
|
import { createIssue } from "./helpers.ts";
|
|
|
|
export const securityRules: DevToolbarRule[] = [
|
|
{
|
|
id: "security/page",
|
|
category: "security",
|
|
defaultSeverity: "warning",
|
|
description: "Checks development-visible security mistakes.",
|
|
run: ({ url, root }) => {
|
|
const issues = [];
|
|
for (const [key] of url.searchParams)
|
|
if (/pass(word)?|token|secret|api[-_]?key/i.test(key))
|
|
issues.push(
|
|
createIssue({
|
|
ruleId: "security/secret-query",
|
|
category: "security",
|
|
severity: "error",
|
|
title: "Potential secret appears in URL",
|
|
message: `The query parameter “${key}” may contain sensitive information.`,
|
|
recommendation:
|
|
"Send secrets in a secure request body or authorization header, not a URL.",
|
|
}),
|
|
);
|
|
for (const form of root.querySelectorAll<HTMLFormElement>('form[action^="http://"]'))
|
|
issues.push(
|
|
createIssue({
|
|
ruleId: "security/insecure-form",
|
|
category: "security",
|
|
severity: "error",
|
|
title: "Form submits over HTTP",
|
|
message: "Form values may be transmitted without transport encryption.",
|
|
element: form,
|
|
recommendation: "Submit to an HTTPS endpoint.",
|
|
}),
|
|
);
|
|
return issues;
|
|
},
|
|
},
|
|
];
|