Dalam pengembangan perangkat lunak modern, keamanan (security) bukan lagi aspek tambahan, melainkan komponen fundamental yang harus terintegrasi di seluruh tahapan Software Development Life Cycle (SDLC). Dokumen ini menyajikan analisis mendalam mengenai implementasi Secure Programming pada modul apps/reply, yang mendemonstrasikan penerapan standar keamanan industri seperti OWASP dan kemampuan mengidentifikasi serta mengantisipasi potensi kerentanan keamanan.
Transformasi ini mendemonstrasikan:
- Identifikasi dan analisis ancaman serta risiko pada proyek.
- Penerapan standar keamanan autentikasi dan autorisasi.
- Implementasi panduan OWASP dengan pengujian komprehensif.
- Analisis keamanan dalam keseluruhan proses SDLC.
Konteks Penilaian Level 4
Dokumen ini dirancang untuk memenuhi kriteria penilaian tertinggi (Level 4):
- ✓ Menganalisa kemungkinan isu security yang terkait dengan keseluruhan proses SDLC.
- ✓ Mengantisipasi potensi kerentanan pada project dengan implementasi konkret.
- ✓ Menerapkan dan menguji standar OWASP API Security Top 10.
- ✓ Menunjukkan bukti implementasi melalui hasil pengujian dan analisis arsitektur.
1. Threat Modeling dan Risk Assessment (Level 1)
1.1 Identifikasi Ancaman pada Modul Reply
Pada tahap awal pengembangan, dilakukan threat modeling untuk mengidentifikasi potensi ancaman yang mungkin terjadi pada modul Reply:
| Threat Category | Potential Attack | Risk Level | Mitigasi |
|---|---|---|---|
| Injection | SQL Injection, XSS | High | Input sanitization, parameterized queries |
| Broken Authentication | Token spoofing, session hijacking | High | JWT validation, SSO integration |
| Broken Authorization | IDOR, privilege escalation | High | Ownership validation, role-based access |
| Data Exposure | Sensitive data leakage | Medium | Response filtering, audit logging |
| Rate Limiting | DDoS, brute force | Medium | Per-user throttling, IP limiting |
| Concurrent Modification | Race conditions, lost updates | Medium | Optimistic locking, database constraints |
1.2 Analisis Risiko Spesifik pada Modul Reply
Risiko Utama yang Teridentifikasi:
- Unauthorized Modification: User mencoba mengubah/menghapus Reply milik user lain.
-
Data Injection: Malicious content dalam field
contentuntuk XSS atau SQL injection. - Privilege Escalation: Regular user mencoba akses fungsi moderator/admin.
- Information Disclosure: Sensitive data (private notes) terekspos ke unauthorized users.
- Race Condition Exploitation: Concurrent requests untuk bypass business rules.
Struktur Direktori Security-Aware:
apps/reply/
├── permissions.py ← [Role-based access control]
├── validators/
│ ├── base.py ← [Model validation]
│ └── sanitizers.py ← [Input sanitization & injection detection]
├── throttles/
│ ├── reply.py ← [Rate limiting per operation]
│ └── enhanced_rate_limiting.py ← [Advanced throttling]
├── models/
│ ├── audit_log.py ← [Immutable audit trail]
│ └── reply.py ← [Database constraints, version field]
├── services/
│ └── reply.py ← [Ownership validation, optimistic locking]
└── tests/
├── test_security.py ← [Security unit tests]
├── test_permissions.py ← [Authorization tests]
└── test_penetration.py ← [OWASP penetration tests]
2. Autentikasi dan Autorisasi (Level 2)
2.1 Implementasi Autentikasi
Modul Reply menggunakan JWT-based authentication yang terintegrasi dengan SSO UI:
# fimo_be/settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'auth.sso_ui.SSOUIJWTAuthentication', # JWT SSO integration
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # Default require auth
],
}
Fitur Autentikasi yang Diimplementasikan:
| Feature | Implementation | Security Benefit |
|---|---|---|
| JWT Validation | SSOUIJWTAuthentication |
Token-based, stateless auth |
| Token Expiry | Configured via SSO | Limit window of compromise |
| Invalid Token Rejection | DRF authentication flow | Prevent forged tokens |
| No Token = 401 |
IsAuthenticated permission |
Enforce authentication |
2.2 Implementasi Autorisasi
Permission Classes (apps/reply/permissions.py):
def is_admin_or_moderator(user: Any) -> bool:
"""
Helper function untuk mengecek apakah user adalah admin atau moderator.
"""
if not user or not user.is_authenticated:
return False
return bool(user.is_staff or user.groups.filter(name="moderator").exists())
def can_view_private_note(
user: Any, reply_author_username: Optional[str] = None
) -> bool:
"""
Memeriksa apakah user dapat melihat Note dengan is_public=False.
User dapat melihat private note jika:
- User adalah admin atau moderator, ATAU
- User adalah author dari Reply terkait
"""
if not user or not user.is_authenticated:
return False
if is_admin_or_moderator(user):
return True
if reply_author_username and user.username == reply_author_username:
return True
return False
class IsAdminOrModerator(BasePermission):
"""
Izin yang hanya mengizinkan akses jika user adalah admin atau moderator.
"""
def has_permission(self, request: "Request", view: "APIView") -> bool:
return is_admin_or_moderator(request.user)
Ownership Validation di View Layer (apps/reply/views/reply.py):
def update(self, request: Request, *args: Any, **kwargs: Any) -> Response:
"""Menangani pembaruan Reply."""
instance = self.get_object()
# Validasi ownership: hanya author yang bisa update
can_modify, error = ReplyService.can_be_modified_by_user(
instance, request.user
)
if not can_modify:
return Response(
{"detail": error},
status=status.HTTP_403_FORBIDDEN,
)
# ... rest of update logic
def destroy(self, request: Request, *args: Any, **kwargs: Any) -> Response:
"""Menangani penghapusan Reply."""
reply = self.get_object()
# Validasi ownership: hanya author yang bisa delete
can_delete, error = ReplyService.can_be_deleted_by_user(
reply, request.user
)
if not can_delete:
return Response(
{"detail": error},
status=status.HTTP_403_FORBIDDEN,
)
# ... rest of delete logic
2.3 Bukti Pengujian Autorisasi
Pengujian authorization dilakukan secara komprehensif dengan 27 test cases:
$ python manage.py test apps.reply.tests.test_permissions --verbosity=2 --keepdb
Found 27 test(s).
test_admin_can_view_private_note ... ok
test_moderator_can_view_private_note ... ok
test_regular_user_cannot_view_others_private_note ... ok
test_reply_author_can_view_own_private_note ... ok
test_permission_denied_for_regular_user ... ok
test_permission_denied_for_unauthenticated_user ... ok
test_permission_denied_for_none_user ... ok
test_permission_granted_for_admin_user ... ok
test_permission_granted_for_moderator_user ... ok
test_user_removed_from_moderator_loses_access ... ok
test_user_gains_access_after_becoming_admin ... ok
... (17 more tests)
Ran 27 tests in 85.998s
OK
Coverage yang Diuji:
| Scenario | Test Case | Expected | Result |
|---|---|---|---|
| Admin access | test_admin_can_view_private_note |
Allowed | ✓ |
| Moderator access | test_moderator_can_view_private_note |
Allowed | ✓ |
| Regular user access | test_regular_user_cannot_view_others_private_note |
Denied | ✓ |
| Owner access | test_reply_author_can_view_own_private_note |
Allowed | ✓ |
| Unauthenticated | test_unauthenticated_user_cannot_view_private_note |
Denied | ✓ |
| Role revocation | test_user_removed_from_moderator_loses_access |
Denied | ✓ |
| Role promotion | test_user_gains_access_after_becoming_admin |
Allowed | ✓ |
3. Implementasi OWASP API Security Top 10 (Level 3)
Modul Reply mengimplementasikan mitigasi untuk OWASP API Security Top 10 dengan pengujian penetration testing yang komprehensif.
3.1 OWASP API1: Broken Object Level Authorization (BOLA)
Ancaman: Attacker mencoba mengakses/mengubah objek dengan memanipulasi ID.
Implementasi Mitigasi:
# apps/reply/services/reply.py
@classmethod
def can_be_modified_by_user(cls, instance: "Reply", user: Any) -> Tuple[bool, str]:
"""Validasi apakah user bisa memodifikasi reply."""
if not user or not user.is_authenticated:
return False, "User tidak terautentikasi"
if instance.author_username != user.username:
return False, "Anda tidak memiliki izin untuk mengubah reply ini"
return True, ""
Pengujian (test_penetration.py):
def test_api1_broken_object_level_authorization_direct_object_reference(self):
"""
OWASP API1: Broken Object Level Authorization (BOLA).
Attack: Attacker tries to access/modify object by manipulating ID.
Scenario: Attacker tries to PATCH victim's reply using their own token.
Expected: 403 Forbidden (ownership check should fail)
"""
self.client.force_authenticate(user=self.attacker_user)
url = reverse(
"reply-detail",
kwargs={"forum_id": self.forum.id, "id": self.victim_reply.id},
)
# Try to modify victim's reply
response = self.client.patch(
url,
{"content": "Hacked by attacker"},
format="json",
)
# Should be denied
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
# Verify content not changed
self.victim_reply.refresh_from_db()
self.assertEqual(self.victim_reply.content, "Victim's reply content")
3.2 OWASP API2: Broken Authentication
Ancaman: Akses endpoint tanpa token atau dengan token invalid.
Pengujian:
def test_api2_broken_authentication_no_token(self) -> None:
"""
Attack: Access protected endpoint without authentication token.
Expected: 401 Unauthorized
"""
response = self.client.post(
url,
{"content": "Unauthorized reply"},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
def test_api2_broken_authentication_invalid_token(self) -> None:
"""
Attack: Use invalid/expired token.
"""
self.client.credentials(HTTP_AUTHORIZATION="Bearer invalid_token_xyz")
response = self.client.post(url, {"content": "With invalid token"}, format="json")
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
3.3 OWASP API3: Excessive Data Exposure
Ancaman: API mengembalikan data lebih dari yang diperlukan.
Mitigasi: Serializer hanya expose fields yang diperlukan, sensitive fields tidak terekspos.
def test_api3_excessive_data_exposure_sensitive_fields(self) -> None:
"""
Attack: API returns more data than needed.
Expected: Only necessary fields returned, no internal IDs, password hashes.
"""
response = self.client.get(url, format="json")
if response.data and len(response.data) > 0:
reply_data = response.data[0]
# Sensitive fields should NOT be exposed
self.assertNotIn("password_hash", reply_data)
self.assertNotIn("secret_key", reply_data)
self.assertNotIn("internal_token", reply_data)
3.4 OWASP API6: Mass Assignment
Ancaman: Attacker mengirim extra fields untuk memanipulasi internal state.
Implementasi Mitigasi:
# Serializer hanya menerima fields yang diizinkan
class ReplyUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = Reply
fields = ['content', 'version'] # Only allowed fields
read_only_fields = ['author_username', 'created_at', 'id']
Pengujian:
def test_api6_mass_assignment_extra_fields(self) -> None:
"""
Attack: Send extra fields to manipulate internal state.
Expected: Extra fields should be ignored.
"""
response = self.client.patch(
url,
{
"content": "Modified content",
"author_username": "admin", # Try to change author
"created_at": "2024-01-01T00:00:00Z", # Try to change timestamp
"version": 999, # Try to bypass optimistic lock
},
format="json",
)
if response.status_code == status.HTTP_200_OK:
self.victim_reply.refresh_from_db()
self.assertEqual(self.victim_reply.author_username, "victim") # Unchanged
self.assertNotEqual(self.victim_reply.version, 999) # Unchanged
3.5 OWASP API7: Injection (SQL & XSS)
Input Sanitization (apps/reply/validators/sanitizers.py):
def detect_sql_injection_patterns(text: str) -> bool:
"""Detect common SQL injection patterns dalam text."""
sql_patterns = [
r"(\bOR\b.*=.*)", # OR 1=1
r"(\bDROP\b)", # DROP TABLE
r"(\bUNION\b)", # UNION SELECT
r"(\bSELECT\b.*\bFROM\b)", # SELECT FROM
r"(--;)", # SQL comment
]
for pattern in sql_patterns:
if re.search(pattern, text, re.IGNORECASE):
return True
return False
def detect_script_injection_patterns(text: str) -> bool:
"""Detect common script injection patterns (XSS attempts)."""
xss_patterns = [
r"(<script[^>]*>.*?</script>)", # <script> tags
r"(on\w+\s*=)", # Event handlers
r"(javascript:)", # javascript: protocol
r"(<iframe[^>]*>)", # iframe tags
]
for pattern in xss_patterns:
if re.search(pattern, text, re.IGNORECASE):
return True
return False
def validate_message_content(text: str, ...) -> tuple[bool, Optional[str]]:
"""Comprehensive message validation."""
# Check for injection patterns
if detect_sql_injection_patterns(text):
return False, "Message mengandung karakter yang tidak diizinkan"
if detect_script_injection_patterns(text):
return False, "Message mengandung script yang tidak diizinkan"
return True, None
Pengujian Injection:
def test_api7_injection_sql_injection_via_search(self) -> None:
"""
Attack: Inject SQL commands via search/filter parameters.
Expected: Query should handle safely (parameterized queries).
"""
payload = "'; DROP TABLE reply_reply; --"
response = self.client.get(f"{url}?search={payload}", format="json")
# Should not execute injection
self.assertTrue(Reply.objects.exists()) # Table still exists
3.6 Hasil Pengujian OWASP Penetration Tests
$ python manage.py test apps.reply.tests.test_penetration.OWASPAPITop10PenetrationTest --verbosity=2 --keepdb
Found 10 test(s).
test_api1_broken_object_level_authorization_direct_object_reference ... ok
test_api2_broken_authentication_invalid_token ... ok
test_api2_broken_authentication_no_token ... ok
test_api3_excessive_data_exposure_sensitive_fields ... ok
test_api5_broken_access_control_missing_permission_check ... ok
test_api6_mass_assignment_extra_fields ... ok
test_api7_injection_sql_injection_via_search ... ok
test_api7_injection_xss_via_content_field ... ok
test_api8_improper_asset_management_deprecated_api ... ok
test_api9_logging_monitoring_error_reveals_stack_trace ... ok
Ran 10 tests in 25.275s
OK
4. Security Headers dan Defense in Depth
4.1 Security Headers Middleware
Implementasi (fimo_be/middleware.py):
class SecurityHeadersMiddleware:
"""
Middleware untuk add security headers ke semua HTTP responses.
Prevent common attacks seperti XSS, clickjacking, MIME sniffing.
"""
def _add_security_headers(self, response: Any) -> None:
# Prevent MIME type sniffing
response["X-Content-Type-Options"] = "nosniff"
# Prevent clickjacking attacks
response["X-Frame-Options"] = "DENY"
# XSS Protection untuk browser lama
response["X-XSS-Protection"] = "1; mode=block"
# Referrer Policy
response["Referrer-Policy"] = "strict-origin-when-cross-origin"
# Permissions Policy
response["Permissions-Policy"] = "geolocation=(), microphone=(), camera=()"
4.2 Bukti Pengujian Security Headers
$ python manage.py test apps.reply.tests.test_security.SecurityHeadersTest --verbosity=2 --keepdb
Found 3 test(s).
test_nosniff_header ... ok
test_xframe_options_header ... ok
test_xss_protection_header ... ok
Ran 3 tests in 2.648s
OK
Coverage Security Headers:
| Header | Value | Protection |
|---|---|---|
| X-Content-Type-Options | nosniff | MIME sniffing prevention |
| X-Frame-Options | DENY | Clickjacking prevention |
| X-XSS-Protection | 1; mode=block | XSS protection (legacy browsers) |
| Referrer-Policy | strict-origin-when-cross-origin | Referrer leakage prevention |
| Permissions-Policy | geolocation=(), etc. | Browser feature restriction |
5. Concurrent Modification Protection
5.1 Optimistic Locking Implementation
Model dengan Version Field (apps/reply/models/reply.py):
class Reply(models.Model):
# ... other fields
version = models.IntegerField(default=1, editable=False)
Service dengan Optimistic Lock (apps/reply/services/reply.py):
@classmethod
def update_with_optimistic_lock(
cls,
instance: "models.Model",
updated_fields: dict[str, Any],
current_version: int,
) -> Tuple[bool, str]:
"""
Update reply dengan Optimistic Locking.
Mencegah lost update pada concurrent edit.
"""
try:
with transaction.atomic():
latest = Reply.objects.select_for_update().get(
pk=instance.pk, version=current_version
)
for field, value in updated_fields.items():
setattr(latest, field, value)
latest.version += 1
latest.updated_at = timezone.now()
latest.clean()
latest.save()
return True, ""
except Reply.DoesNotExist:
return (
False,
"Record telah dimodifikasi oleh pengguna lain. "
"Refresh halaman dan coba lagi.",
)
5.2 Pengujian Race Condition
$ python manage.py test apps.reply.tests.test_penetration.ConcurrentModificationPenetrationTest --verbosity=2 --keepdb
Found 3 test(s).
test_race_condition_concurrent_updates ... ok
test_race_condition_create_delete ... ok
test_race_condition_double_delete ... ok
Ran 3 tests in 5.209s
OK
Test Case Concurrent Updates:
def test_race_condition_concurrent_updates(self) -> None:
"""
Attack: Simultaneously update same object to trigger race condition.
Expected: Optimistic lock should prevent lost update.
"""
with ThreadPoolExecutor(max_workers=2) as executor:
future1 = executor.submit(update_reply, client1, "Update 1")
future2 = executor.submit(update_reply, client2, "Update 2")
results = [future1.result(), future2.result()]
# Optimistic lock should prevent both from succeeding
self.assertFalse(
all(code == status.HTTP_200_OK for code in status_codes),
"Both concurrent updates succeeded - lost update vulnerability!",
)
6. Audit Logging dan Forensics
6.1 Implementasi Audit Trail
Model Audit Log (apps/reply/models/audit_log.py):
class AuditLog(models.Model):
"""
Model untuk mencatat semua operasi modify/delete pada Reply dan Note.
Berfungsi sebagai immutable audit trail untuk forensics dan compliance.
"""
ACTION_CHOICES = [
("create", "Create"),
("update", "Update"),
("delete", "Delete"),
]
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user_username = models.CharField(max_length=500)
action = models.CharField(max_length=20, choices=ACTION_CHOICES)
model_name = models.CharField(max_length=100)
object_id = models.UUIDField()
old_values = models.JSONField(null=True, blank=True)
new_values = models.JSONField(null=True, blank=True)
ip_address = models.GenericIPAddressField(null=True, blank=True)
user_agent = models.TextField(blank=True)
timestamp = models.DateTimeField(auto_now_add=True, editable=False)
@classmethod
def log_operation(cls, ...) -> "AuditLog":
"""Helper method untuk membuat audit log entry."""
# Exclude sensitive fields sebelum logging
sensitive_fields = {"password", "token", "secret", "api_key"}
filtered_old = {k: v for k, v in old_values.items()
if k not in sensitive_fields}
filtered_new = {k: v for k, v in new_values.items()
if k not in sensitive_fields}
return cls.objects.create(...)
Fitur Audit Logging:
| Feature | Implementation | Benefit |
|---|---|---|
| Immutable Logs | UUID primary key, auto timestamp | Tamper-proof audit trail |
| Sensitive Field Filtering | Exclude password, token, etc. | Data protection |
| User Tracking | Username, IP, User-Agent | Forensics capability |
| Object History | get_object_history() |
Change reconstruction |
| User Activity | get_user_activity() |
Behavior monitoring |
7. Rate Limiting dan DoS Protection
7.1 Implementasi Throttling
Per-Operation Rate Limiting (apps/reply/throttles/reply.py):
class ReplyCreateThrottle(UserRateThrottle):
"""Throttle untuk pembuatan reply."""
scope: str = "reply_create"
def get_rate(self) -> str:
return f"{RATE_LIMITS['reply_create']}/minute"
class ReplyUpdateThrottle(UserRateThrottle):
"""Throttle untuk pembaruan reply."""
scope: str = "reply_update"
class ReplyDeleteThrottle(UserRateThrottle):
"""Throttle untuk penghapusan reply."""
scope: str = "reply_delete"
View dengan Throttle Classes:
class ReplyViewSet(viewsets.ModelViewSet[Reply]):
throttle_classes_by_action = {
"create": [ReplyCreateThrottle],
"update": [ReplyUpdateThrottle],
"destroy": [ReplyDeleteThrottle],
}
7.2 Pengujian Rate Limit Bypass
def test_rate_limit_bypass_via_x_forwarded_for_spoofing(self) -> None:
"""
Attack: Spoof X-Forwarded-For header to bypass per-IP rate limits.
Expected: Per-user limit should still enforce.
"""
for i in range(15):
self.client.defaults["HTTP_X_FORWARDED_FOR"] = f"192.168.1.{i}"
response = self.client.post(url, {"content": f"Test {i}"}, format="json")
if response.status_code == status.HTTP_429_TOO_MANY_REQUESTS:
break
# Per-user throttle enforces regardless of IP spoofing
8. Keamanan dalam SDLC (Level 4)
8.1 Analisis Keamanan End-to-End dalam SDLC
Level 4 mensyaratkan kemampuan menganalisa isu security dalam keseluruhan proses SDLC. Berikut analisis implementasi keamanan di setiap fase:
| SDLC Phase | Security Implementation | Evidence |
|---|---|---|
| Requirements | Threat modeling, risk assessment | Dokumentasi ancaman dan mitigasi |
| Design | Secure architecture patterns | Layered security (middleware, permissions, validators) |
| Implementation | Secure coding practices | Input sanitization, parameterized queries, ownership validation |
| Testing | Security testing automation | Penetration tests, OWASP tests (40+ test cases) |
| Deployment | Security headers, environment isolation | Middleware headers, ENV-based secrets |
| Maintenance | Audit logging, monitoring | Immutable audit trail, activity tracking |
8.2 Database Constraints sebagai Defense Layer
Model dengan Check Constraints (apps/reply/models/reply.py):
class Reply(models.Model):
class Meta:
constraints = [
# Prevent timestamp manipulation
models.CheckConstraint(
condition=Q(updated_at__gte=F("created_at")),
name="reply_updated_not_before_created",
),
# Enforce 30-minute edit window at DB level
models.CheckConstraint(
condition=Q(
updated_at__lte=models.ExpressionWrapper(
F("created_at") + datetime.timedelta(minutes=30),
output_field=models.DateTimeField(),
)
),
name="reply_updated_within_30_minutes",
),
# Prevent self-referencing parent
models.CheckConstraint(
condition=~Q(parent=F("id")) | Q(parent__isnull=True),
name="reply_parent_not_self",
),
]
Signifikansi: Constraints di level database memberikan defense in depth - bahkan jika application layer di-bypass, database tetap enforce rules.
8.3 Environment-Based Security Configuration
# fimo_be/settings.py
# Secrets dari environment, bukan hardcoded
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", "dev-unsafe-key")
DEBUG = os.environ.get("DEBUG", "False") == "True"
# CORS hanya allow specific origins di production
CORS_ALLOW_ALL_ORIGINS = os.environ.get("DEBUG", "False") == "True"
# SSO integration dengan secure key management
LOGIN_UI_PUBLIC_KEY = os.getenv("LOGIN_UI_PUBLIC_KEY")
SSO_UI_SECRET = os.getenv("SSO_UI_SECRET")
8.4 Dependency Security dan Version Control
Optimistic Locking untuk Data Integrity:
# Version field prevents lost updates
version = models.IntegerField(default=1, editable=False)
# Update dengan version check
def update_with_optimistic_lock(cls, instance, updated_fields, current_version):
latest = Reply.objects.select_for_update().get(
pk=instance.pk, version=current_version
)
latest.version += 1 # Increment on every update
latest.save()
8.5 Antisipasi Kerentanan dan Continuous Security
Proactive Security Measures:
| Measure | Implementation | Purpose |
|---|---|---|
| Input Validation | validators/sanitizers.py |
Prevent injection at entry point |
| Output Encoding | Django auto-escaping | Prevent XSS on output |
| Parameterized Queries | Django ORM | Prevent SQL injection |
| Audit Logging | models/audit_log.py |
Forensics dan compliance |
| Rate Limiting | throttles/*.py |
DoS prevention |
| Security Headers | middleware.py |
Browser-level protection |
| Database Constraints | Model constraints | Defense in depth |
9. Ringkasan Security Implementation
9.1 Coverage Matrix
| OWASP Category | Implemented | Tested | Evidence |
|---|---|---|---|
| API1: BOLA | ✓ | ✓ | Ownership validation, 403 on unauthorized access |
| API2: Broken Auth | ✓ | ✓ | JWT validation, 401 on missing/invalid token |
| API3: Data Exposure | ✓ | ✓ | Serializer field filtering |
| API5: BFLA | ✓ | ✓ | Role-based permissions |
| API6: Mass Assignment | ✓ | ✓ | Read-only fields in serializer |
| API7: Injection | ✓ | ✓ | Input sanitization, parameterized queries |
| API8: Asset Management | ✓ | ✓ | Versioned API, deprecation handling |
| API9: Logging | ✓ | ✓ | Audit log, no stack trace in response |
9.2 Test Coverage Summary
| Test Category | Test Count | Pass Rate |
|---|---|---|
| Permission Tests | 27 | 100% |
| OWASP Penetration Tests | 10 | 100% |
| Security Header Tests | 3 | 100% |
| Concurrent Modification Tests | 3 | 100% |
| Input Sanitization Tests | 11 | 100% |
| Total Security Tests | 54+ | 100% |
9.3 Pencapaian Level 4 (Criteria Fulfillment)
✓ Level 1 - Threat Analysis:
- Threat modeling dengan identifikasi 6 kategori ancaman
- Risk assessment dengan prioritas High/Medium
- Dokumentasi mitigasi untuk setiap ancaman
✓ Level 2 - Authentication & Authorization:
- JWT-based authentication via SSO integration
- Role-based access control (Admin, Moderator, Regular User)
- Ownership validation untuk modify/delete operations
- 27 test cases untuk authorization
✓ Level 3 - OWASP Implementation:
- Implementasi mitigasi OWASP API Top 10
- Penetration testing dengan 10+ attack scenarios
- Security headers middleware
- Input sanitization dan injection detection
✓ Level 4 - SDLC Security Analysis:
- Security integration di seluruh SDLC phases
- Database constraints sebagai defense in depth
- Environment-based security configuration
- Optimistic locking untuk data integrity
- Audit logging untuk forensics dan compliance
- Proactive vulnerability anticipation
10. Simpulan
Implementasi Secure Programming pada modul Reply mendemonstrasikan pendekatan defense in depth yang komprehensif:
- Multiple Security Layers: Dari middleware (security headers) hingga database (constraints).
- OWASP Compliance: Mitigasi terhadap API Security Top 10 dengan pengujian.
- SDLC Integration: Keamanan terintegrasi dari requirements hingga maintenance.
- Measurable Results: 54+ security test cases dengan 100% pass rate.
- Continuous Monitoring: Audit logging untuk forensics dan compliance.
Modul ini tidak hanya mengimplementasikan standar keamanan, tetapi juga menunjukkan kemampuan menganalisis dan mengantisipasi potensi kerentanan dalam keseluruhan proses SDLC, sesuai dengan kriteria Level 4.
Top comments (0)