# Security by Design ## Навигация - [🏠 Главная страница курса](../../../README.md) - [📚 Модуль 6](../README.md) --- ## Принципы Security by Design ### 1. Secure by Default - Безопасные настройки по умолчанию - Минимальные права доступа - Защита от случайных ошибок ### 2. Fail Secure - При отказе система переходит в безопасное состояние - Блокировка доступа при ошибках - Логирование всех событий безопасности ### 3. Security as Code - Безопасность как часть кода - Автоматизированные проверки безопасности - Версионирование политик безопасности ## Моделирование угроз ### STRIDE Model - **S**poofing (Подмена) - **T**ampering (Изменение) - **R**epudiation (Отказ) - **I**nformation Disclosure (Раскрытие информации) - **D**enial of Service (Отказ в обслуживании) - **E**levation of Privilege (Повышение привилегий) ### Пример Threat Model: ```yaml # threat-model.yml application: "E-commerce Platform" components: - name: "User Authentication" threats: - type: "Spoofing" description: "User impersonation" mitigations: - "Strong password policy" - "Multi-factor authentication" - name: "Payment Processing" threats: - type: "Tampering" description: "Payment data modification" mitigations: - "Data encryption" - "Digital signatures" ``` ## Архитектура безопасности ### 1. Zero Trust Architecture **Принцип:** "Никогда не доверяй, всегда проверяй" ```java @Component public class ZeroTrustFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; // проверяем каждую аутентификацию if (!isAuthenticated(httpRequest)) { throw new AuthenticationException("Authentication required"); } // проверяем каждую авторизацию if (!isAuthorized(httpRequest)) { throw new AuthorizationException("Access denied"); } // проверяем устройство if (!isDeviceTrusted(httpRequest)) { throw new SecurityException("Untrusted device"); } chain.doFilter(request, response); } } ``` ### 2. Microsegmentation **Принцип:** Разделение сети на мелкие сегменты ```yaml # network-policy.yml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: order-service-policy spec: podSelector: matchLabels: app: order-service policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: app: api-gateway ports: - protocol: TCP port: 8080 egress: - to: - podSelector: matchLabels: app: payment-service ports: - protocol: TCP port: 8080 ``` ## Аутентификация и авторизация ### Аутентификация #### 1. Password-based Authentication ```java @Service public class AuthenticationService { @Autowired private PasswordEncoder passwordEncoder; @Autowired private UserRepository userRepository; public AuthenticationResult authenticate(String username, String password) { User user = userRepository.findByUsername(username); if (user == null) { return AuthenticationResult.failure("User not found"); } if (!passwordEncoder.matches(password, user.getPasswordHash())) { return AuthenticationResult.failure("Invalid password"); } if (!user.isActive()) { return AuthenticationResult.failure("User account is disabled"); } return AuthenticationResult.success(user); } } ``` #### 2. Multi-Factor Authentication (MFA) ```java @Service public class MFAService { @Autowired private TOTPGenerator totpGenerator; @Autowired private SMSService smsService; public void enableMFA(Long userId, String phoneNumber) { String secret = totpGenerator.generateSecret(); userRepository.updateMFASecret(userId, secret); userRepository.updatePhoneNumber(userId, phoneNumber); } public boolean verifyMFA(Long userId, String code) { User user = userRepository.findById(userId); String secret = user.getMFASecret(); return totpGenerator.verifyCode(secret, code); } public void sendSMS(Long userId, String code) { User user = userRepository.findById(userId); smsService.sendSMS(user.getPhoneNumber(), "Your verification code: " + code); } } ``` #### 3. OAuth 2.0 / OpenID Connect ```java @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .userInfoEndpoint(userInfo -> userInfo .userService(customOAuth2UserService) ) ) .authorizeHttpRequests(authz -> authz .requestMatchers("/public/**").permitAll() .requestMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() ); return http.build(); } } ``` ### Авторизация #### 1. Role-Based Access Control (RBAC) ```java @Entity public class User { @Id private Long id; @ManyToMany(fetch = FetchType.EAGER) @JoinTable( name = "user_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id") ) private Set roles = new HashSet<>(); } @Entity public class Role { @Id private Long id; private String name; @ManyToMany(fetch = FetchType.EAGER) @JoinTable( name = "role_permissions", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "permission_id") ) private Set permissions = new HashSet<>(); } ``` #### 2. Attribute-Based Access Control (ABAC) ```java @Component public class ABACPolicyEngine { public boolean evaluate(Policy policy, AccessRequest request) { // проверяем субъект if (!policy.getSubject().matches(request.getSubject())) { return false; } // проверяем ресурс if (!policy.getResource().matches(request.getResource())) { return false; } // проверяем действие if (!policy.getAction().matches(request.getAction())) { return false; } // проверяем контекст if (!policy.getContext().matches(request.getContext())) { return false; } return true; } } // Пример политики Policy policy = Policy.builder() .subject("role:manager") .resource("department:finance") .action("read") .context("time:business_hours") .build(); ``` #### 3. JWT Tokens ```java @Service public class JWTService { private final String secretKey = "mySecretKey"; private final int jwtExpiration = 86400000; // 24 hours public String generateToken(UserDetails userDetails) { Map claims = new HashMap<>(); claims.put("roles", userDetails.getAuthorities()); claims.put("userId", userDetails.getUsername()); return createToken(claims, userDetails.getUsername()); } private String createToken(Map claims, String subject) { return Jwts.builder() .setClaims(claims) .setSubject(subject) .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date(System.currentTimeMillis() + jwtExpiration)) .signWith(SignatureAlgorithm.HS512, secretKey) .compact(); } public Boolean validateToken(String token, UserDetails userDetails) { final String username = extractUsername(token); return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); } } ``` ## Безопасность API ### Лучшие практики безопасности API #### 1. Input Validation ```java @RestController @Validated public class UserController { @PostMapping("/users") public ResponseEntity createUser(@Valid @RequestBody CreateUserRequest request) { // валидация выполняется автоматически через @Valid User user = userService.createUser(request); return ResponseEntity.ok(user); } } public class CreateUserRequest { @NotBlank(message = "Username is required") @Size(min = 3, max = 50, message = "Username must be between 3 and 50 characters") private String username; @NotBlank(message = "Email is required") @Email(message = "Email must be valid") private String email; @NotBlank(message = "Password is required") @Size(min = 8, message = "Password must be at least 8 characters") @Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$", message = "Password must contain at least one uppercase letter, one lowercase letter, one number and one special character") private String password; } ``` #### 2. Rate Limiting ```java @Component public class RateLimitingFilter implements Filter { private final Map rateLimiters = new ConcurrentHashMap<>(); @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String clientId = getClientId(httpRequest); RateLimiter rateLimiter = rateLimiters.computeIfAbsent(clientId, k -> RateLimiter.create(10.0)); // 10 запросов в секунду if (!rateLimiter.tryAcquire()) { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setStatus(429); // Too Many Requests httpResponse.getWriter().write("Rate limit exceeded"); return; } chain.doFilter(request, response); } } ``` #### 3. API Versioning ```java @RestController @RequestMapping("/api/v1/users") public class UserControllerV1 { @GetMapping("/{id}") public UserV1 getUser(@PathVariable Long id) { return userService.getUserV1(id); } } @RestController @RequestMapping("/api/v2/users") public class UserControllerV2 { @GetMapping("/{id}") public UserV2 getUser(@PathVariable Long id) { return userService.getUserV2(id); } } ``` ### Безопасность API Gateway ```yaml # api-gateway-security.yml apiVersion: networking.istio.io/v1alpha3 kind: AuthorizationPolicy metadata: name: api-gateway-policy spec: selector: matchLabels: app: api-gateway rules: - from: - source: principals: ["cluster.local/ns/default/sa/api-gateway"] to: - operation: methods: ["GET", "POST"] paths: ["/api/v1/*"] - from: - source: principals: ["cluster.local/ns/default/sa/admin-service"] to: - operation: methods: ["*"] paths: ["/admin/*"] ``` ## Безопасность данных ### Классификация данных #### 1. Data Sensitivity Levels - **Public** — общедоступные данные - **Internal** — внутренние данные - **Confidential** — конфиденциальные данные - **Restricted** — ограниченные данные ```java @Entity public class User { @Id private Long id; @Column(name = "username") @DataClassification(level = DataClassification.Level.INTERNAL) private String username; @Column(name = "email") @DataClassification(level = DataClassification.Level.CONFIDENTIAL) private String email; @Column(name = "ssn") @DataClassification(level = DataClassification.Level.RESTRICTED) @Encrypted private String ssn; } ``` #### 2. Data Masking ```java @Service public class DataMaskingService { public User maskUserData(User user, UserRole requesterRole) { User maskedUser = new User(); maskedUser.setId(user.getId()); switch (requesterRole) { case ADMIN: // админы видят все данные maskedUser.setEmail(user.getEmail()); maskedUser.setSsn(user.getSsn()); break; case MANAGER: // менеджеры видят частично замаскированные данные maskedUser.setEmail(maskEmail(user.getEmail())); maskedUser.setSsn(maskSSN(user.getSsn())); break; case USER: // обычные пользователи видят только базовую информацию maskedUser.setEmail(maskEmail(user.getEmail())); maskedUser.setSsn("***-**-****"); break; } return maskedUser; } private String maskEmail(String email) { String[] parts = email.split("@"); String username = parts[0]; String domain = parts[1]; if (username.length() <= 2) { return "*@" + domain; } return username.substring(0, 2) + "*".repeat(username.length() - 2) + "@" + domain; } private String maskSSN(String ssn) { return "***-**-" + ssn.substring(ssn.length() - 4); } } ``` ### Шифрование данных #### 1. Encryption at Rest ```java @Entity public class PaymentCard { @Id private Long id; @Column(name = "card_number") @Convert(converter = EncryptedStringConverter.class) private String cardNumber; @Column(name = "cvv") @Convert(converter = EncryptedStringConverter.class) private String cvv; } @Converter public class EncryptedStringConverter implements AttributeConverter { @Autowired private EncryptionService encryptionService; @Override public String convertToDatabaseColumn(String attribute) { return encryptionService.encrypt(attribute); } @Override public String convertToEntityAttribute(String dbData) { return encryptionService.decrypt(dbData); } } ``` #### 2. Encryption in Transit ```java @Configuration public class SSLConfig { @Bean public RestTemplate restTemplate() throws Exception { SSLContext sslContext = SSLContextBuilder.create() .loadTrustMaterial(null, (certificate, authType) -> true) .build(); HttpClient httpClient = HttpClients.custom() .setSSLContext(sslContext) .build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); return new RestTemplate(factory); } } ``` ## Соответствие требованиям ### GDPR (Общий регламент по защите данных) #### 1. Data Subject Rights ```java @Service public class GDPRService { public void handleDataSubjectRequest(DataSubjectRequest request) { switch (request.getType()) { case ACCESS: provideDataAccess(request.getSubjectId()); break; case RECTIFICATION: rectifyData(request.getSubjectId(), request.getData()); break; case ERASURE: eraseData(request.getSubjectId()); break; case PORTABILITY: provideDataPortability(request.getSubjectId()); break; } } private void eraseData(Long subjectId) { // удаляем персональные данные userRepository.deletePersonalData(subjectId); // логируем удаление auditService.logDataErasure(subjectId); // уведомляем заинтересованные системы notificationService.notifyDataErasure(subjectId); } } ``` #### 2. Consent Management ```java @Entity public class Consent { @Id private Long id; private Long userId; private String purpose; private ConsentStatus status; private LocalDateTime givenAt; private LocalDateTime withdrawnAt; public boolean isValid() { return status == ConsentStatus.GIVEN && withdrawnAt == null; } } @Service public class ConsentService { public void giveConsent(Long userId, String purpose) { Consent consent = new Consent(); consent.setUserId(userId); consent.setPurpose(purpose); consent.setStatus(ConsentStatus.GIVEN); consent.setGivenAt(LocalDateTime.now()); consentRepository.save(consent); } public void withdrawConsent(Long userId, String purpose) { Consent consent = consentRepository.findByUserIdAndPurpose(userId, purpose); if (consent != null) { consent.setStatus(ConsentStatus.WITHDRAWN); consent.setWithdrawnAt(LocalDateTime.now()); consentRepository.save(consent); } } } ``` ### PCI DSS (Стандарт безопасности данных индустрии платежных карт) #### 1. Card Data Protection ```java @Service public class PCIService { public String tokenizeCard(String cardNumber) { // генерируем токен вместо хранения номера карты String token = UUID.randomUUID().toString(); // сохраняем токен в безопасном хранилище secureStorage.storeToken(token, cardNumber); return token; } public String detokenizeCard(String token) { // получаем номер карты по токену return secureStorage.getCardByToken(token); } public boolean validateCard(String cardNumber) { // проверяем номер карты по алгоритму Луна return luhnAlgorithm.validate(cardNumber); } } ``` #### 2. Secure Payment Processing ```java @Service public class PaymentService { @Transactional public PaymentResult processPayment(PaymentRequest request) { // валидируем данные карты if (!validateCardData(request.getCardData())) { return PaymentResult.failure("Invalid card data"); } // токенизируем данные карты String token = tokenizeCard(request.getCardData().getNumber()); // обрабатываем платеж PaymentResult result = paymentProcessor.processPayment(request); // логируем транзакцию auditService.logPaymentTransaction(request, result); return result; } } ``` ### SOX (Закон Сарбейнса-Оксли) #### 1. Financial Data Controls ```java @Service public class FinancialControlService { public void validateFinancialTransaction(FinancialTransaction transaction) { // проверяем авторизацию if (!isAuthorized(transaction.getAmount())) { throw new AuthorizationException("Transaction amount exceeds authorization limit"); } // проверяем дублирование if (isDuplicateTransaction(transaction)) { throw new DuplicateTransactionException("Duplicate transaction detected"); } // проверяем целостность данных if (!validateDataIntegrity(transaction)) { throw new DataIntegrityException("Data integrity check failed"); } } public void auditFinancialData() { // аудит финансовых данных List transactions = getTransactionsForAudit(); for (FinancialTransaction transaction : transactions) { validateTransaction(transaction); logAuditTrail(transaction); } } } ``` ## Заключение Security by Design обеспечивает встроенную безопасность на всех уровнях приложения: 1. **Принципы безопасности** — Secure by Default, Fail Secure, Security as Code 2. **Моделирование угроз** — STRIDE модель для выявления рисков 3. **Архитектура безопасности** — Zero Trust, Microsegmentation 4. **Аутентификация и авторизация** — MFA, RBAC, ABAC, JWT 5. **Безопасность API** — Валидация, Rate Limiting, Versioning 6. **Безопасность данных** — Классификация, Маскирование, Шифрование 7. **Соответствие требованиям** — GDPR, PCI DSS, SOX Интеграция этих принципов в процесс разработки обеспечивает надежную защиту приложения от угроз безопасности.