dependency-track icon indicating copy to clipboard operation
dependency-track copied to clipboard

Trivy analyzer fails on container restart.

Open AkselAllas opened this issue 1 year ago • 2 comments

Current Behavior

I am running my Trivy container in a sidecar with the following command:

args   = ["server", "--listen", "0.0.0.0:8081", "--token", "plaintext", "--cache-backend", "memory"]

I have the following Trivy config (plaintext written as API token here): Image

When I restart my dependency-track backend container & therefore Trivy sidecar. Requests to Trivy analyzer fail with the following error:

javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
	at java.base/com.sun.crypto.provider.CipherCore.unpad(Unknown Source)
	at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(Unknown Source)
	at java.base/com.sun.crypto.provider.CipherCore.doFinal(Unknown Source)
	at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(Unknown Source)
	at java.base/javax.crypto.Cipher.doFinal(Unknown Source)
	at alpine.security.crypto.DataEncryption.decryptAsBytes(DataEncryption.java:136)
	at alpine.security.crypto.DataEncryption.decryptAsBytes(DataEncryption.java:148)
	at alpine.security.crypto.DataEncryption.decryptAsString(DataEncryption.java:176)
	at org.dependencytrack.util.DebugDataEncryption.retryDecryptAsString(DebugDataEncryption.java:59)
	at org.dependencytrack.util.DebugDataEncryption.decryptAsString(DebugDataEncryption.java:54)
	at org.dependencytrack.tasks.scanners.TrivyAnalysisTask.inform(TrivyAnalysisTask.java:150)
	at org.dependencytrack.tasks.VulnerabilityAnalysisTask.performAnalysis(VulnerabilityAnalysisTask.java:197)
	at org.dependencytrack.tasks.VulnerabilityAnalysisTask.analyzeComponents(VulnerabilityAnalysisTask.java:157)
	at org.dependencytrack.tasks.VulnerabilityAnalysisTask.inform(VulnerabilityAnalysisTask.java:87)
	at alpine.event.framework.BaseEventService.lambda$publish$0(BaseEventService.java:110)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)

For Trivy to work, I need to:

  1. Know that my container has restarted
  2. Go to Trivy config in UI and rewrite plaintext as trivy api token (even though it should already be plaintext from my last time I wrote it there)

Retries aren't working. It can stay broken like this for multiple weeks without you noticing unless you have an alert on error logs.

Also --cache-backend memory should be mentioned in Trivy docs for scenarios where you don't have a volume at hand for your Trivy container.

Proposed Behavior

When I restart my container, Trivy keeps working without manual intervention.

Checklist

AkselAllas avatar Oct 15 '24 12:10 AkselAllas

Also this very much sucks when you redeploy DT via IaC

AkselAllas avatar Oct 15 '24 12:10 AkselAllas

I have seen this happen to other instances of these encrypted fields in DT such as the OSS Index API Token. Sometimes it looks like it gets reset to null or empty string somewhere end ends up like that in the database. It only happened once or twice for me, not every restart. Are you seeing it consistenly every restart?

valentijnscholten avatar Oct 15 '24 18:10 valentijnscholten

@valentijnscholten Yes. I am seeing this consistently on every restart.

AkselAllas avatar Nov 02 '24 05:11 AkselAllas

Would it be possible to use environment variable to be source of trivy token? ie something like TRIVY_API_TOKEN? if so - are there any steps to "unconfigure" any value that was currently set in database?

ervin-pactum avatar Nov 02 '24 07:11 ervin-pactum

Duplicate of #2366.

If this happens on every restart, please verify that you're mounting the /data directory to a persistent volume, and that files in that volume are accessible by the restarted instance (randomized user IDs can cause issues here).

The key used to encrypt and decrypt secrets is stored on disk. If that is not persisted, DT will generate a new key on startup that of course won't work with secrets already stored in the DB.

nscuro avatar Nov 05 '24 11:11 nscuro

@nscuro In the case where I am hosting a separate db for the backend, the best practice would be to allow the backend to be stateless and pass secrets via environment variables (as per 12 factor app framework) using whichever secret management approach the user prefers.

Then no data mount or storing ciphertext in db or setting secret via UI would be necessary

AkselAllas avatar Nov 05 '24 14:11 AkselAllas

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Dec 06 '24 10:12 github-actions[bot]