# Secure Component Command Analyze and secure Angular components against XSS, injection, and other vulnerabilities. ## Usage ```bash /angular-security:secure-component ``` ## Security Checks ### 1. XSS Prevention ```typescript // ❌ CRITICAL: XSS vulnerability @Component({ template: `
` }) export class UnsafeComponent { @Input() userInput: string; } // ✅ SECURE: Sanitized HTML @Component({ template: `
` }) export class SafeComponent { @Input() set userInput(value: string) { this.safeContent = this.sanitizer.sanitize( SecurityContext.HTML, value ); } safeContent: SafeHtml; constructor(private sanitizer: DomSanitizer) {} } // ✅ BEST: Avoid innerHTML @Component({ template: `
{{ userInput }}
` // Auto-escaped }) export class BestComponent { @Input() userInput: string; } ``` ### 2. URL Sanitization ```typescript // ❌ DANGEROUS: Arbitrary URL Click // ✅ SECURE: Sanitize URLs export class LinkComponent { @Input() set url(value: string) { this.safeUrl = this.sanitizer.sanitize( SecurityContext.URL, value ); } safeUrl: SafeUrl; constructor(private sanitizer: DomSanitizer) {} } // Template Click ``` ### 3. Resource URL Validation ```typescript // ❌ DANGEROUS: Untrusted resource // ✅ SECURE: Whitelist trusted domains export class VideoComponent { @Input() set videoUrl(url: string) { if (this.isTrustedDomain(url)) { this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url); } else { console.error('Untrusted video URL:', url); this.safeUrl = null; } } safeUrl: SafeResourceUrl | null; private trustedDomains = ['youtube.com', 'vimeo.com']; private isTrustedDomain(url: string): boolean { try { const domain = new URL(url).hostname; return this.trustedDomains.some(trusted => domain.includes(trusted) ); } catch { return false; } } constructor(private sanitizer: DomSanitizer) {} } ``` ### 4. Style Injection ```typescript // ❌ DANGEROUS: User-controlled styles
Content
// ✅ SECURE: Sanitize styles export class StyledComponent { @Input() set userStyle(value: string) { this.safeStyle = this.sanitizer.sanitize( SecurityContext.STYLE, value ); } safeStyle: SafeStyle; constructor(private sanitizer: DomSanitizer) {} } // ✅ BETTER: Use class binding
Content
``` ### 5. Dynamic Script Loading ```typescript // ❌ NEVER DO THIS eval(userCode); new Function(userCode)(); // ✅ SECURE: No dynamic code execution // Use configuration objects instead export class ConfigurableComponent { @Input() config: { enabled: boolean; options: string[]; }; executeAction() { // Safe configuration-driven logic if (this.config.enabled) { this.config.options.forEach(opt => this.handleOption(opt)); } } } ``` ### 6. Form Input Validation ```typescript // ✅ SECURE: Comprehensive validation export class UserFormComponent { userForm = this.fb.group({ username: ['', [ Validators.required, Validators.minLength(3), Validators.maxLength(20), Validators.pattern(/^[a-zA-Z0-9_]+$/) // Alphanumeric only ]], email: ['', [ Validators.required, Validators.email ]], bio: ['', [ Validators.maxLength(500) ]] }); constructor(private fb: FormBuilder) {} onSubmit() { if (this.userForm.valid) { // Server-side validation still required! const data = this.userForm.value; this.api.createUser(data).subscribe(); } } } ``` ### 7. File Upload Security ```typescript // ✅ SECURE: File validation export class FileUploadComponent { private readonly MAX_SIZE = 5 * 1024 * 1024; // 5MB private readonly ALLOWED_TYPES = [ 'image/jpeg', 'image/png', 'image/gif', 'application/pdf' ]; onFileSelected(event: Event) { const input = event.target as HTMLInputElement; const file = input.files?.[0]; if (!file) return; // Validate file type if (!this.ALLOWED_TYPES.includes(file.type)) { alert('Invalid file type'); return; } // Validate file size if (file.size > this.MAX_SIZE) { alert('File too large (max 5MB)'); return; } // Validate file extension const ext = file.name.split('.').pop()?.toLowerCase(); const validExtensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf']; if (!ext || !validExtensions.includes(ext)) { alert('Invalid file extension'); return; } this.uploadFile(file); } } ``` ### 8. Sensitive Data in Templates ```typescript // ❌ DANGEROUS: Exposing sensitive data @Component({ template: `
API Key: {{ apiKey }}
Password: {{ password }}
` }) // ✅ SECURE: Never expose sensitive data @Component({ template: `
Status: {{ isAuthenticated ? 'Connected' : 'Disconnected' }}
` }) export class SecureComponent { isAuthenticated: boolean; // Sensitive data only in memory, never in template private apiKey: string; private password: string; } ``` ### 9. Clickjacking Prevention ```typescript // Set X-Frame-Options header (server-side) // But also check in Angular: export class FrameGuard implements OnInit { ngOnInit() { // Prevent loading in iframe if (window.self !== window.top) { console.error('Clickjacking attempt detected'); window.top.location = window.self.location; } } } ``` ### 10. Content Security Policy ```html ``` ## Security Audit Checklist ```typescript // Component security audit export class AuditedComponent { // ✅ 1. No innerHTML with user data // ✅ 2. All URLs sanitized // ✅ 3. Form inputs validated // ✅ 4. No eval or Function constructor // ✅ 5. Sensitive data not in template // ✅ 6. File uploads validated // ✅ 7. External resources whitelisted // ✅ 8. CSP headers configured // ✅ 9. HTTPS enforced // ✅ 10. Dependencies audited } ``` ## Output Example ``` 🔒 Security Audit: UserProfileComponent ⚠️ Issues Found: 1. 🔴 CRITICAL: XSS Vulnerability (Line 23) Location: template: `
` Risk: Arbitrary JavaScript execution Fix: Use sanitizer or remove innerHTML 2. 🟡 HIGH: Unvalidated File Upload (Line 45) Location: onFileUpload(event) Risk: Malicious file upload Fix: Add file type and size validation 3. 🟡 MEDIUM: Hardcoded API Key (Line 12) Location: apiKey = 'sk_live_123...' Risk: Credential exposure Fix: Use environment variables ✅ Secure Patterns Detected: - Form validation with Validators - HTTPS enforced - HttpOnly cookies for auth token 📋 Recommendations: 1. Sanitize HTML content 2. Validate file uploads 3. Move API key to environment config 4. Add CSP headers 5. Implement rate limiting for API calls 🎯 Security Score: 6/10 (Medium Risk) After fixes: 9/10 (Low Risk) ``` --- *Secure every component! 🛡️*