accuknox / accuknox/agentZ

Defense-in-depth: API keys hashed with unsalted SHA-256 (weak crypto)

Open
#98 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
48
Forks
10
Avg merge
1d 8h
Merged PRs (30d)
17

Description

Description

hashAPIKey computes sha256.Sum256([]byte(key)) with no per-key salt, then stores the base64-encoded digest in the plaintext apikeys.key column. Because the hash is deterministic and unsalted, a database compromise (SQLi, backup leak, insider access) lets an attacker crack all stored keys offline via rainbow tables or brute force, cracking one key is as cheap as cracking any of them. Recovered keys can then be used to authenticate as the original holder against the gateway API and downstream agent pods.

Data flow

User-supplied API key (HTTP Basic Auth password or X-API-Key header) → hashAPIKey() → SHA-256 hash without salt → stored in apikeys.key column → looked up via GatewayGetAPIKeyByHash SQL query.

Reachability

Requires prior database read access, not directly network-exploitable. Once the DB is accessed, though, every stored key can be cracked offline with no per-record computation barrier, since there's no salt. The apikeys table also stores config_id, reference_id (org ID), prefix, and name, which helps an attacker triage high-value keys.

Impact

Full API key recovery on DB compromise, enabling impersonation of any user/workflow holding a key.

Suggested fix (backward-compatible, single PR)

Switch to HMAC-SHA-256 with a server-side pepper stored outside the DB (config/K8s secret):

func hashAPIKey(key string) string {
    mac := hmac.New(sha256.New, pepperKey) // pepperKey from config/K8s secret
    mac.Write([]byte(key))
    return base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
}

This keeps the existing text column and lookup query unchanged, so it's a drop-in replacement.

A stronger option is Argon2id with a per-key salt, but that requires a DB migration and a rehash-on-next-use (or dual-read) strategy.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Locate hashAPIKey and GatewayGetAPIKeyByHash, then trace the HTTP Basic Auth and X-API-Key paths through storage in the apikeys.key column. Review how a server-side secret would be configured or supplied from a Kubernetes secret, and verify that authentication and existing lookup behavior remain covered. Done means stored keys are no longer deterministically hashed without a secret and the gateway still authenticates valid keys.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
authentication, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.