Deepen PracticeOrdered learning track

Threat Modeling Files, Config, and Secrets

Learn Java Microservices File Handling, State, Configuration and Secret Management - Part 055

Threat modeling untuk file, state, configuration, dan secret di Java microservices: assets, trust boundaries, attack surfaces, abuse cases, mitigations, and verification.

13 min read2583 words
PrevNext
Lesson 5570 lesson track39–58 Deepen Practice
#java#microservices#threat-modeling#security+4 more

Part 055 — Threat Modeling Files, Config, and Secrets

Threat modeling is not a security ceremony.

It is how engineering teams stop lying to themselves about trust boundaries.

Kita sudah membahas file handling, object storage, state management, configuration management, dan secret management. Sekarang kita masuk blok cross-cutting security dan production defensibility.

Part ini menjawab pertanyaan:

Apa yang bisa diserang, dari mana, oleh siapa, dengan konsekuensi apa,
dan invariant mana yang harus tetap dijaga?

Threat modeling di seri ini bukan dokumen panjang yang dibuat sekali lalu dilupakan. Threat modeling adalah cara berpikir yang harus masuk ke design review, code review, test, observability, dan runbook.

Fokus kita bukan semua security topic. Fokusnya sangat spesifik:

  • file upload/download;
  • object storage;
  • metadata;
  • local filesystem;
  • ephemeral state;
  • durable state;
  • cache;
  • configuration;
  • feature flags;
  • Kubernetes ConfigMap/Secret;
  • Vault/cloud secret manager;
  • GitOps secret delivery;
  • runtime telemetry.

1. Threat Model Scope

Untuk Java microservices, threat model harus dimulai dari asset.

Asset di sini bukan hanya database atau bucket. Asset adalah sesuatu yang jika rusak, bocor, dimanipulasi, atau hilang akan berdampak pada correctness, security, compliance, availability, atau cost.

1.1 Asset Inventory

AssetExamplePrimary Risk
Uploaded payloadPDF, image, evidence video, CSVmalware, spoofing, data leak
File metadatacontent type, owner, status, checksumtampering, broken lifecycle
Object storage keybucket/key/versiondirect access, overwrite, enumeration
Presigned URLtemporary upload/download grantreplay, leak, excessive TTL
Temp filelocal staging filepath traversal, disk exhaustion
Durable stateDB rows, events, workflow statusunauthorized mutation
Cachepermission cache, config cachestale security decision
Configtimeout, endpoint, feature toggle, size limitunsafe behavior change
SecretDB password, token, TLS keycredential compromise
Audit eventwho did whatevidence gap, tampering
Telemetrylogs, traces, metricssensitive data leakage

A weak threat model usually says:

Asset: database.

A useful threat model says:

Asset: evidence file payload in accepted state,
metadata row linking it to case,
checksum proving integrity,
retention state preventing deletion,
audit trail proving access and lifecycle transition.

Specificity matters.


2. Trust Boundaries

Trust boundary adalah titik di mana kita tidak boleh mempercayai data, identity, atau side effect begitu saja.

Boundary penting:

BoundaryJangan Dipercaya
Client → APIfilename, content-type, size claim, identity claim
Gateway → serviceforwarded headers tanpa trusted proxy config
Service → storagepartial failure, stale read, permission error
Service → scannerscanner timeout, false negative, incomplete scan
Service → configmissing config, stale config, wrong precedence
Service → secret managersecret expiry, denied access, stale cache
Service → logs/tracesaccidental sensitive data
Service → DBconcurrency conflict, stale transaction, direct mutation by other actor
Kubernetes → appenv var immutability, volume update delay

Rule:

Any crossing of trust boundary needs validation, authorization, integrity check,
timeout, audit, and failure handling appropriate to the asset.

3. Threat Modeling Framework

Kita gunakan versi praktis dari STRIDE, tetapi disesuaikan untuk file/config/secret/state.

STRIDEPertanyaan untuk Seri Ini
SpoofingSiapa bisa menyamar sebagai uploader, service, worker, atau secret consumer?
TamperingSiapa bisa mengubah file, metadata, config, secret, atau lifecycle state?
RepudiationApakah actor bisa menyangkal upload/download/delete/change?
Information DisclosureApakah payload, secret, config sensitif, atau telemetry bocor?
Denial of ServiceApakah file besar, retry storm, config error, atau secret outage bisa menjatuhkan service?
Elevation of PrivilegeApakah akses file/secret/config bisa melewati boundary least privilege?

Tambahkan dua kategori production-grade:

CategoryPertanyaan
Integrity DriftApakah metadata, object, cache, index, dan audit bisa diverge?
Operational AbuseApakah fitur legal/ops seperti presigned URL, debug endpoint, atau config reload bisa disalahgunakan?

4. File Upload Threats

File upload adalah salah satu boundary paling berbahaya karena client mengirim binary yang belum dipercaya.

4.1 Spoofed Content Type

Client bisa mengirim:

Content-Type: application/pdf

tetapi payload sebenarnya executable, zip bomb, HTML, polyglot file, atau malware.

Invariant:

Client-provided Content-Type is a hint, never a security decision.

Mitigation:

  • extension allowlist;
  • magic bytes/content detection;
  • structural parser validation;
  • malware scan;
  • size limits;
  • quarantine-first design;
  • no execution;
  • no direct serving from upload location.

4.2 Dangerous Filename

Spring MultipartFile#getOriginalFilename() documentation warns that the original filename is supplied by client and may contain path information or malicious characters. Treat filename as display metadata, not filesystem path.

Bad:

Path target = uploadDir.resolve(file.getOriginalFilename());

Better:

String safeDisplayName = sanitizeDisplayName(file.getOriginalFilename());
String storageKey = generateServerSideStorageKey(fileId);

Invariant:

Client filename must never determine physical storage path.

4.3 Path Traversal

Attack:

../../../../etc/passwd
..%2f..%2f..%2fapp.yaml

Mitigation:

Path base = Path.of("/srv/app/uploads").toRealPath();
Path target = base.resolve(userInputName).normalize();

if (!target.startsWith(base)) {
    throw new SecurityException("Invalid path");
}

But for production file upload, better:

Do not use user filename as path at all.

4.4 Zip Bomb / Archive Bomb

Uploaded archive can expand massively.

Mitigation:

  • max compressed size;
  • max uncompressed size;
  • max entry count;
  • max nesting depth;
  • timeout;
  • streaming extraction;
  • temporary quota;
  • no symlink extraction unless explicitly allowed;
  • no absolute path extraction.

4.5 Malware and Active Content

A “valid PDF” can still contain malicious content.

Mitigation:

  • quarantine all uploads;
  • scan asynchronously;
  • block download until accepted;
  • optional content disarm and reconstruction for document types;
  • scanner timeout handling;
  • re-scan when definitions change if risk requires;
  • manual review path.

4.6 File Upload DoS

Attack:

  • many large uploads;
  • slow upload;
  • many multipart sessions never completed;
  • disk exhaustion in /tmp;
  • object storage multipart part spam;
  • scanner queue flood.

Mitigation:

  • authentication before upload;
  • per-user/tenant quota;
  • max request body size at ingress, service, and app layer;
  • rate limit;
  • upload session TTL;
  • abort incomplete multipart upload;
  • scratch volume size limit;
  • backpressure;
  • worker concurrency control.

5. File Download Threats

Download looks safer than upload, but it exposes authorization and leakage risks.

5.1 Metadata Access vs Payload Access

User may be allowed to see that a file exists but not allowed to download payload.

Invariant:

Payload access requires an explicit authorization decision,
not just metadata visibility.

Bad:

GET /files/{fileId}/download
// if file exists, return presigned URL

Better:

1. Authenticate actor.
2. Load file metadata.
3. Check domain access policy.
4. Check file lifecycle state.
5. Check retention/legal restrictions if needed.
6. Generate short-lived download capability.
7. Audit download decision.

5.2 Presigned URL Leakage

Presigned URL is a bearer capability.

If leaked, anyone with URL can use it until expiry, unless additional controls exist.

Mitigation:

  • short TTL;
  • bind to method/object/action;
  • avoid logging URL query string;
  • do not send via insecure channel;
  • audit issuance;
  • prefer one-time token pattern for sensitive files if needed;
  • never make presigned URL long-lived replacement for authorization.

5.3 Cache-Control Mistakes

Sensitive file downloads should not be cached by shared proxy or browser incorrectly.

Headers:

Cache-Control: no-store
Content-Disposition: attachment; filename="safe-name.pdf"
X-Content-Type-Options: nosniff

For public assets this differs. But evidence, personal data, or confidential document should default conservative.

5.4 Content Sniffing

Browser may interpret content differently from intended type.

Mitigation:

  • set correct Content-Type;
  • set X-Content-Type-Options: nosniff;
  • serve untrusted content from separate domain if inline rendering is allowed;
  • prefer attachment disposition for untrusted uploads.

6. Object Storage Threats

6.1 Bucket Policy Too Broad

Bad:

service role can read/write/delete all buckets

Better:

evidence-service role can PutObject to evidence/quarantine/*
evidence-worker role can GetObject from quarantine/* and PutObject to accepted/*
download service can GetObject only after domain authorization
no ListBucket unless required

Least privilege should be per capability, not per team.

6.2 Object Key Enumeration

Object keys can leak information:

cases/CASE-123/john-smith-medical-record.pdf

Better:

evidence/2026/07/05/FILE-01JZ.../payload

Metadata can hold display name, but key should avoid sensitive semantic leak.

6.3 Overwrite and Tampering

If accepted object can be overwritten, evidence integrity collapses.

Invariant:

Accepted artifact must be immutable or tamper-evident.

Mitigation:

  • object versioning;
  • object lock if required;
  • no overwrite in accepted prefix;
  • checksum verification;
  • write-once semantic in service;
  • strict IAM;
  • audit storage events.

6.4 Orphan Objects

Orphan object can become:

  • cost leak;
  • privacy risk;
  • retention ambiguity;
  • access ambiguity.

Mitigation:

  • metadata-payload reconciliation;
  • object tags;
  • lifecycle policy for temporary prefix;
  • incomplete multipart abort;
  • periodic inventory review.

6.5 Confused Deputy

Service has broad storage permission and attacker tricks it into accessing object it should not.

Example:

POST /copy?sourceKey=other-tenant/private-file

Mitigation:

  • never accept arbitrary object key from user as authority;
  • derive storage key from domain metadata;
  • authorize source and target through domain model;
  • restrict IAM prefix.

7. Configuration Threats

Configuration changes runtime behavior. That makes config part of the control plane.

7.1 Unsafe Override

Spring Boot supports multiple property sources with precedence. A higher-precedence source can override intended safe value.

Threat:

MALWARE_SCAN_REQUIRED=false
MAX_UPLOAD_SIZE_MB=999999
DIRECT_UPLOAD_ENABLED=true

Mitigation:

  • typed config validation;
  • environment-specific policy;
  • config owner approval;
  • startup invariant check;
  • deny unsafe values in prod;
  • effective config audit with redaction;
  • GitOps change review.

7.2 Config Drift

Manual cluster edit:

kubectl edit configmap evidence-service-config

Impact:

  • behavior no longer matches Git;
  • rollback unclear;
  • audit weak.

Mitigation:

  • GitOps reconciliation;
  • drift detection;
  • restrict direct mutation RBAC;
  • annotate config version;
  • startup log config source/version;
  • alert on live-state drift.

7.3 Config as Secret

Common mistake:

external-api:
  token: "abc123"

inside ConfigMap.

Invariant:

Secret material must never be stored in ConfigMap or non-sensitive config store.

Mitigation:

  • secret scan;
  • config schema classification;
  • policy enforcement;
  • naming rules;
  • review gates.

7.4 Feature Flag Abuse

Feature flags can bypass release controls if too powerful.

Example:

disableAuthorizationChecks=true
skipMalwareScan=true

Mitigation:

  • do not implement unsafe bypass flags in prod;
  • classify flags by risk;
  • audit flag changes;
  • require approval for high-risk flags;
  • time-bound flags;
  • remove stale flags.

8. Secret Threats

8.1 Secret Exfiltration Through Logs

Most secret leaks are not exotic. They are often:

  • exception message;
  • debug log;
  • serialized config object;
  • HTTP header log;
  • stack trace;
  • actuator endpoint;
  • CI output.

Invariant:

Secret value must not appear in logs, metrics, traces, errors, or audit payload.

8.2 Over-privileged Secret

If service DB credential has admin privileges, compromise becomes catastrophic.

Mitigation:

  • least privilege;
  • short-lived dynamic secret;
  • per-service credential;
  • per-environment secret;
  • deny shared credentials;
  • audit auth usage.

8.3 Secret Staleness

Secret rotation fails because app keeps old secret.

Mitigation:

  • versioned secret metric;
  • rotation overlap;
  • connection pool max lifetime;
  • readiness check;
  • old credential usage audit.

8.4 Kubernetes Secret RBAC

Kubernetes docs note that reading Secrets in a namespace enables access to secret data in that namespace. Avoid broad get/list/watch secrets.

Mitigation:

  • narrow RBAC;
  • namespace isolation;
  • avoid mounting unnecessary secrets;
  • encryption at rest;
  • audit secret access;
  • use external secret managers where appropriate.

9. State Threats

9.1 Lost Update

Two actors update same state from stale read.

Mitigation:

  • optimistic locking/version column;
  • compare-and-set transition;
  • transaction boundary;
  • idempotency key.

9.2 Duplicate Event

Event delivered twice promotes file twice or sends duplicate notification.

Mitigation:

  • event idempotency;
  • processed event table;
  • state transition guard;
  • monotonic lifecycle.

9.3 Stale Cache Authorization

Permission revoked but cache still allows access.

Mitigation:

  • short TTL for security-sensitive cache;
  • force source-of-truth check on critical operations;
  • event invalidation;
  • versioned authorization decision;
  • cache metrics.

9.4 Replay Drift

Rebuild from events produces different state from original due to changed code/config.

Mitigation:

  • versioned event schema;
  • deterministic replay logic;
  • policy version captured;
  • replay test;
  • conflict detection.

9.5 Split Brain Worker

Two workers both think they own a job.

Mitigation:

  • database lock with fencing token;
  • lease-based leadership;
  • idempotent worker output;
  • state transition check.

10. Threat Model by Lifecycle Stage

10.1 Upload Lifecycle

Threats by state:

StateThreat
INITIATEDunauthorized session creation, quota bypass
UPLOADINGlarge file DoS, incomplete multipart spam
UPLOADEDmetadata-payload mismatch
QUARANTINEDearly download before scan
SCANNEDfalse scan result, duplicate result
ACCEPTEDoverwrite, unauthorized download
REJECTEDretained malware not cleaned up

10.2 Config Change Lifecycle

PR -> validation -> approval -> merge -> GitOps reconcile -> pod rollout/reload -> runtime proof

Threats:

  • unauthorized change;
  • unsafe value;
  • config drift;
  • partial rollout;
  • stale pod;
  • rollback to incompatible config.

10.3 Secret Rotation Lifecycle

create new -> distribute -> consumer switch -> proof -> revoke old

Threats:

  • new secret invalid;
  • old revoked too early;
  • consumer not refreshed;
  • secret logged during rollout;
  • mixed versions too long.

11. Abuse Cases

Abuse case is attacker-centered story. It is more useful than generic risk list.

Abuse Case 1 — Upload Polyglot File

As an attacker, I upload a file named invoice.pdf that is also valid HTML/JS
so that downstream preview renders active content in an employee browser.

Controls:

  • content detection;
  • no inline rendering for untrusted content;
  • nosniff;
  • attachment disposition;
  • sandboxed preview domain;
  • CDR if needed.

Abuse Case 2 — Exhaust Scratch Disk

As an attacker, I start many large uploads and never complete them,
filling /tmp or emptyDir until the pod is evicted.

Controls:

  • request size limit;
  • rate limit;
  • upload session TTL;
  • scratch quota;
  • cleanup job;
  • incomplete multipart abort;
  • per-tenant quota.

Abuse Case 3 — Abuse Presigned URL

As a user with temporary access, I generate a presigned URL and share it
after my domain permission is revoked.

Controls:

  • short TTL;
  • audit issuance;
  • permission check before issuance;
  • one-time token for sensitive data;
  • revoke via object version/key change if needed;
  • no long-lived URL.

Abuse Case 4 — Disable Scan via Config

As a compromised operator, I set malware.scan.required=false in production.

Controls:

  • policy forbids unsafe prod config;
  • config owner approval;
  • admission policy;
  • startup invariant;
  • alert on effective scan disabled;
  • audit config change.

Abuse Case 5 — Read All Kubernetes Secrets

As a compromised service account, I list secrets in namespace and steal DB credentials.

Controls:

  • no broad list/watch secrets;
  • per-service RBAC;
  • namespace isolation;
  • workload identity;
  • encryption at rest;
  • audit secret access;
  • avoid injecting all secrets into all pods.

Abuse Case 6 — Tamper Metadata Directly

As an insider with DB access, I mark unscanned file as ACCEPTED.

Controls:

  • DB access control;
  • status transition constraints;
  • audit trigger;
  • checksum/scan result required constraints;
  • service-only mutation;
  • periodic reconciliation.

12. Mitigation Architecture

Key design decisions:

  • untrusted file never lands directly in accepted storage;
  • file identity generated server-side;
  • payload not downloadable before lifecycle allows;
  • config cannot silently disable security-critical steps;
  • secret access is least-privilege;
  • every critical transition audited;
  • reconciliation catches divergence.

13. Threat Model Document Template

Gunakan template ini untuk setiap service yang mengelola file/config/secret/state.

# Threat Model: <Service Name>

## Scope
- Service:
- Runtime:
- Data classification:
- Environments:

## Assets
| Asset | Classification | Owner | Impact if compromised |
|---|---|---|---|

## Trust Boundaries
| Boundary | Input | Assumption | Validation/Control |
|---|---|---|---|

## Entry Points
| Entry Point | Actor | AuthN | AuthZ | Rate Limit |
|---|---|---|---|---|

## Threats
| Threat | STRIDE | Asset | Impact | Likelihood | Controls |
|---|---|---|---|---|---|

## Abuse Cases
| Abuse Case | Expected Control | Test |
|---|---|---|

## Security Invariants
- ...

## Observability
- Audit events:
- Metrics:
- Alerts:

## Residual Risk
- ...

## Review
- Owner:
- Security reviewer:
- Date:

14. Testing Threat Controls

14.1 Security Unit Tests

  • path traversal rejected;
  • lifecycle transition invalid rejected;
  • secret wrapper redacts;
  • unsafe config fails startup;
  • authorization policy denies payload access.

14.2 Integration Tests

  • upload file with misleading content type;
  • upload huge file beyond limit;
  • download without permission;
  • presigned URL TTL enforced;
  • config scan disable forbidden in prod;
  • secret missing fails readiness.

14.3 Failure Injection

  • scanner timeout;
  • object storage returns 403/503;
  • DB commit fails after object write;
  • secret manager unavailable;
  • config source stale;
  • duplicate scan event.

14.4 Abuse Case Tests

Convert every abuse case into at least one test or manual security scenario.

Example:

Given a user has access to file F
And user generates presigned URL with TTL 5 minutes
When user permission is revoked
Then new URL issuance is denied
And old URL expires within 5 minutes
And issuance/revocation is audited

15. Review Checklist

Files

[ ] Client filename not used as path
[ ] Content type not trusted from client
[ ] Upload size limited at all layers
[ ] Raw upload quarantined
[ ] Accepted file immutable/tamper-evident
[ ] Download requires payload authorization
[ ] Presigned URL short-lived and not logged
[ ] Temp files cleaned and quota-bound

State

[ ] Source of truth explicit
[ ] Critical state not only in memory/local disk
[ ] Duplicate event safe
[ ] Lost update handled
[ ] Replay drift considered
[ ] Cache correctness risk classified

Configuration

[ ] Unsafe prod values blocked
[ ] Required config validated at startup
[ ] Config provenance known
[ ] Runtime reload only for reload-safe values
[ ] ConfigMap does not contain secret
[ ] Drift detection exists

Secrets

[ ] Secret least privilege
[ ] No broad secret RBAC
[ ] Secret not logged
[ ] Rotation strategy documented
[ ] Consumer refresh method defined
[ ] Secret manager/KMS access audited

Observability

[ ] Security events audited
[ ] Sensitive data redacted
[ ] Invariant violation metrics exist
[ ] Alert on high-risk failure
[ ] Runbook exists

16. Key Takeaways

  1. Threat modeling starts with specific assets, not generic infrastructure labels.
  2. File upload is untrusted binary crossing a dangerous boundary.
  3. Client filename, content type, size claim, and metadata are not authority.
  4. Object storage keys must not become domain authorization.
  5. Configuration is a control plane and can disable security if not governed.
  6. Secret risk includes logs, RBAC, stale cache, rotation, and runtime consumers.
  7. State threats include lost update, duplicate event, stale cache, split brain, and replay drift.
  8. Presigned URLs are bearer capabilities; treat them as temporary access grants.
  9. Every abuse case should map to a control and a test.
  10. Threat modeling is useful only when it changes code, config, tests, alerts, or runbooks.

Next, we focus on one of the most common real-world failure classes: Sensitive Data Leakage Prevention across logs, metrics, traces, exceptions, config dumps, file exports, and operational tooling.


References

Lesson Recap

You just completed lesson 55 in deepen practice. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.