con un clic
security-by-design
// Defense-in-depth security principles — OWASP Top 10 prevention, input validation, secure error handling, encryption, least privilege
// Defense-in-depth security principles — OWASP Top 10 prevention, input validation, secure error handling, encryption, least privilege
AI-assisted development governance — Copilot custom agents, MCP servers, change control, audit trail — per Hack23 ISMS AI Policy
Clear technical documentation — JSDoc, Mermaid, READMEs, ADRs, C4 diagrams, ISMS policy citations
Hack23 ISMS alignment — ISO 27001:2022, NIST CSF 2.0, CIS Controls v8.1, GDPR, NIS2, EU CRA — with policy citations
React re-render optimization, Three.js rendering performance, useMemo/useCallback, bundle size, 60 fps profiling, Lighthouse budgets
Three.js game development with React using @react-three/fiber and @react-three/drei — strict TypeScript, 60 fps, accessible
Vitest + Cypress + RTL — deterministic tests, ≥80% line / ≥70% branch coverage, ≥95% on security code, Three.js component testing
| name | security-by-design |
| description | Defense-in-depth security principles — OWASP Top 10 prevention, input validation, secure error handling, encryption, least privilege |
| license | MIT |
Applies to all code handling user input, state persistence, external assets, audio, networking, authentication, authorization, or sensitive configuration. Also applies to infrastructure config, CI/CD pipelines, and security-critical changes.
Aligned with Hack23 AB's ISMS — see Information Security Policy and Secure Development Policy.
secrets.* only; rotate on exposure| OWASP 2021 | Enforcement in this project |
|---|---|
| A01 Broken Access Control | No client-side authorization; render-based capabilities only |
| A02 Cryptographic Failures | TLS only, no custom crypto, no plaintext storage of sensitive data |
| A03 Injection | Validate + encode; never dangerouslySetInnerHTML without DOMPurify |
| A04 Insecure Design | Threat-model per Threat Modeling Policy; STRIDE for new features |
| A05 Security Misconfiguration | Security headers (SECURITY_HEADERS.md), secure defaults |
| A06 Vulnerable Components | npm audit, Dependabot, license gate, SBOMQS ≥ 7.0 |
| A07 Identification/Auth Failures | Not applicable (no user auth in this template) — document when added |
| A08 Software/Data Integrity | SLSA L3 attestations, SHA-pinned Actions, signed releases |
| A09 Logging/Monitoring Failures | GitHub audit + Scorecard + CodeQL alerts reviewed |
| A10 SSRF | Avoid arbitrary URL fetches from untrusted input |
/**
* Validate plain-text user input.
* ISMS: Secure Development Policy §Phase 2 — Secure Coding
*/
function validatePlainText(input: unknown, max = 100): string {
if (typeof input !== 'string') throw new TypeError('Input must be a string');
const trimmed = input.trim();
if (trimmed.length === 0) throw new RangeError('Input is required');
if (trimmed.length > max) throw new RangeError('Input too long');
return trimmed;
}
/** Encode untrusted text before inserting it into HTML. */
function escapeHtml(s: string): string {
return s
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
// For rich HTML use DOMPurify — never ad-hoc stripping.
function handleRequest(): { success?: true; error?: string } {
try {
// do work
return { success: true };
} catch {
// In the browser, avoid console.error with raw details — users can see it.
// Send structured telemetry to restricted server logs instead.
return { error: 'An error occurred. Please try again.' };
}
}
/** ISMS: SDP §Phase 2 — Input Validation */
export function saveHighScore(score: number): void {
if (!Number.isFinite(score) || score < 0 || score > 1_000_000) {
throw new RangeError('Invalid score value');
}
localStorage.setItem('highScore', String(Math.floor(score)));
}
// BAD: hardcoded secret
const API_KEY = "<API_KEY>";
// BAD: leaking stack trace to user
function handleError(e: Error) { return { error: e.stack }; }
// BAD: no input validation — XSS
document.body.innerHTML = userContent;
// BAD: trusting typeof-less JSON.parse output
const data = JSON.parse(input) as User; // no validation/narrowing!
npm audit + license check