Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
enject — enject: .env 시크릿을 prAIng의 눈에서 숨깁니다: 시크릿은 (프로젝트별) 로컬 암호화 저장소에 저장되며 런타임에 앱에 직접 주입되어 디스크에 평문으로 저장되지 않습니다. | Kitploit
도구/GitHubGitHub/greatscott/enject
Encryption/Decryption ToolsCloud SecurityDevSecOpsSecret DetectionSupply Chain SecurityAuthentication
GitHubgreatscott/enject

enject

enject: .env 시크릿을 prAIng의 눈에서 숨깁니다: 시크릿은 (프로젝트별) 로컬 암호화 저장소에 저장되며 런타임에 앱에 직접 주입되어 디스크에 평문으로 저장되지 않습니다.

저장소 보기
500145개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

enject

.env 비밀번호를 prAIng의 눈으로부터 숨깁니다.

(참고: 이 프로젝트는 이전에 enveil이라고 불렸으며, 현재 enject로 이름이 변경되었습니다.)

Claude Code, Copilot, Cursor 및 기타 AI 코딩 도구는 프로젝트 디렉토리의 파일을 읽을 수 있으며, 이는 일반 텍스트 .env 파일이 우발적인 비밀 덤프가 될 수 있음을 의미합니다. 이는 이론적인 문제가 아닙니다. 그것은 저에게 여러 번 발생한 알려진 문제입니다(Claude Code의 settings.json 파일에서 엿보지 말라고 명시적으로 지시한 후에도 말이죠). enject는 일반 텍스트 비밀번호가 절대 디스크에 존재하지 않도록 하여 이 문제를 해결합니다. .env 파일에는 기호 참조만 포함됩니다. 실제 값은 암호화된 로컬 저장소에 저장되며, 시작 시 하위 프로세스에 직접 주입됩니다.

이 프로젝트는 Filip Hric의 솔루션/블로그 게시물에서 영감을 받았으며, 1Password를 활용하는 유사한 개념을 사용합니다. 저는 타사 서비스에 의존하지 않는 자체 포함 솔루션을 원했고, 이 솔루션이 탄생했습니다. 그리고 네, 이 프로젝트는 수동 검증과 테스트를 포함하여 거의 전적으로 Claude Code로 구축되었습니다.

이점 및 주의사항

이 프로젝트는 주로 AI/LLM 도구가 프로젝트의 .env 비밀번호를 실수로 읽는 알려진 문제를 완화하기 위해 설계되었습니다. 추가 이점으로는 .env 파일이 실수로 리포지토리에 커밋되는 경우 비밀 누출을 방지하고, 일반 텍스트 비밀번호 대신 참조가 포함된 .env 파일을 공유할 수 있으며, 암호화된 저장소 자체를 공유할 수 있는 옵션도 있습니다.

이 프로젝트는 AI 에이전트가 비밀번호를 얻는 것을 막는 만병통치약이 아닙니다. 예를 들어, 에이전트는 여전히 (실수로 또는 프롬프트 인젝션을 통해) 런타임에 비밀번호를 터미널 출력이나 파일로 유출하는 코드를 작성할 수 있습니다. 이 도구나 일반적인 .env 파일에 프로덕션 비밀번호를 저장하는 데 의존하지 않는 것이 좋습니다.

작동 방식

.env 파일은 다음과 같습니다:

root@kitploit:~
DATABASE_URL=en://database_url
STRIPE_KEY=en://stripe_key
PORT=3000

기술적으로는 커밋해도 안전합니다(하지만 그렇게 하지 않는 것이 좋습니다). 더 중요한 것은: AI 도구가 실수로 (또는 어쩌면 의도적으로) 이를 엿보더라도 안전합니다.

enject run -- npm start를 실행하면 다음이 수행됩니다:

  1. 마스터 비밀번호를 요청합니다 (절대 에코되지 않으며, 셸 기록에 남지 않음)
  2. Argon2id를 사용하여 비밀번호에서 256비트 AES 키를 파생합니다 (64MB 메모리, 3회 반복)
  3. AES-256-GCM으로 로컬 저장소를 복호화합니다 — 저장소 파일은 12바이트 임의 nonce 뒤에 인증된 암호문이 옵니다
  4. 복호화된 맵에 대해 모든 en:// 참조를 확인합니다
  5. 메모리에서 키와 비밀번호 바이트를 제거합니다
  6. 확인된 값이 환경에 주입된 상태로 하위 프로세스를 생성합니다

저장소 파일은 이진 blob입니다. 마스터 비밀번호 없이는 무작위 노이즈와 구별할 수 없습니다. nonce는 쓰기할 때마다 새로 생성되므로 AES-GCM nonce 재사용이 불가능합니다. 암호문에 대한 수정(단일 비트 뒤집기라도)은 인증 실패를 초래하고 복호화가 거부됩니다.


설치

Cargo를 통해

이 릴리스는 아직 알파 단계이므로 cargo install 호출 시 최신 버전을 추가해야 합니다.

root@kitploit:~
cargo install enject --version 0.2.0-alpha 

소스에서

Rust 1.70+가 필요합니다.

root@kitploit:~
git clone https://github.com/greatscott/enject
cd enject
cargo build --release

컴파일된 바이너리는 target/release/enject에 있습니다. PATH에 있는 위치에 한 번 설치하면 모든 프로젝트에서 실행할 수 있습니다:

macOS / Linux (bash 또는 zsh)

root@kitploit:~
# Option A: ~/.local/bin (no sudo required, common on Linux)
mkdir -p ~/.local/bin
cp target/release/enject ~/.local/bin/

# Option B: /usr/local/bin (requires sudo, available system-wide)
sudo cp target/release/enject /usr/local/bin/

# Option C: ~/.cargo/bin (already on PATH if you used rustup)
cp target/release/enject ~/.cargo/bin/

옵션 A를 사용했고 ~/.local/bin이 이미 PATH에 없다면, 셸 설정 파일(~/.zshrc, ~/.bashrc 또는 ~/.bash_profile)에 다음을 추가하세요:

root@kitploit:~
export PATH="$HOME/.local/bin:$PATH"

그런 다음 다시 로드하세요:

root@kitploit:~
source ~/.zshrc   # or ~/.bashrc

작동하는지 확인하세요:

root@kitploit:~
enject --version

프로젝트별 설정 (프로젝트당 한 번 실행)

바이너리는 전역으로 설치됩니다 — 다시 설치할 필요가 없습니다. 그러나 각 프로젝트는 자체 암호화 저장소를 가집니다:

root@kitploit:~
cd your-project
enject init

이렇게 하면 현재 디렉토리에 프로젝트의 설정과 암호화된 저장소가 포함된 .enject/가 생성됩니다. .gitignore에 추가하세요 — 절대 커밋되어서는 안 됩니다.


사용법

저장소 초기화

프로젝트 루트에서 프로젝트당 한 번 실행하세요:

root@kitploit:~
enject init

이렇게 하면 임의의 32바이트 솔트가 생성되고, .enject/config.toml이 작성되며, .enject/store에 빈 암호화 저장소가 생성되고, 마스터 비밀번호를 설정하라는 메시지가 표시됩니다. .gitignore에 .enject/를 추가하세요 — 저장소는 절대 커밋되어서는 안 됩니다.

비밀 추가

root@kitploit:~
enject set some_database_url
# prompts: Value for 'database_url': (hidden)

enject set some_api_key

값은 항상 대화식으로 입력됩니다. 명령줄 인수로 값을 전달할 방법이 없습니다 — 이렇게 하면 셸 기록이나 ps 출력에 비밀번호가 나타나는 것을 방지합니다.

.env에서 비밀 참조

root@kitploit:~
DATABASE_URL=en://some_database_url
MY_API_KEY=en://stripe_key
PORT=3000

일반 KEY=VALUE 줄은 변경되지 않고 전달됩니다. en:// 참조만 확인됩니다.

앱 실행

root@kitploit:~
enject run -- npm start
enject run -- python manage.py runserver
enject run -- cargo run

-- 이후의 모든 것은 OS에 그대로 전달됩니다. 하위 프로세스는 전체 셸 환경(PATH, HOME 등이 있음)을 상속받으며, 여기에 .env 값이 추가됩니다.

기타 명령

root@kitploit:~
enject list              # print stored key names (never values)
enject delete <key>      # remove a secret
enject import <file>     # encrypt all values in a plaintext .env, rewrite it as en:// template
enject rotate            # re-encrypt the store with a new master password

의도적으로 누락된 명령

get 및 export 명령은 없습니다. 비밀 값을 stdout으로 출력하면 AI가 읽을 수 있는 누출 경로가 생성됩니다 — enject의 핵심은 값을 디스크와 읽을 수 있는 출력 스트림에서 멀리 유지하는 것입니다.

보안 검증

모든 보안 불변성에는 자동화된 테스트와 수동 검증 경로가 있습니다.

모든 자동화 테스트 실행

root@kitploit:~
cargo test

31개의 테스트가 아래의 주장을 모두 포함합니다.


1. 비밀이 일반 텍스트로 디스크에 기록되지 않음

자동화: store::password::tests::test_encrypt_decrypt_roundtrip

비밀을 저장하고, 저장소를 유지하며, 디스크에서 다시 로드하고, 복호화한 다음 값이 올바르게 왕복되는지 확인합니다. 디스크의 바이트가 유효한 암호문인 경우에만 통과합니다 — 일반 텍스트는 복호화에 실패합니다.

root@kitploit:~
cargo test store::password::tests::test_encrypt_decrypt_roundtrip

수동 검증:

root@kitploit:~
enject init          # password: test123
enject set mykey     # value: my-super-secret

xxd .enject/store | head -5
strings .enject/store

xxd는 이진 데이터를 표시합니다. strings는 아무것도 반환하지 않습니다 — 추출할 ASCII 시퀀스가 없습니다. 처음 12바이트는 임의의 nonce이고, 이후의 모든 것은 16바이트 인증 태그가 추가된 AES-GCM 암호문입니다.


2. 쓰기할 때마다 새로운 임의 nonce

자동화: store::password::tests::test_nonce_changes_on_each_save

저장소를 연속으로 두 번 저장하고, 파일의 처음 12바이트를 각각 읽어 서로 다른지 확인합니다.

root@kitploit:~
cargo test store::password::tests::test_nonce_changes_on_each_save

수동 검증:

root@kitploit:~
xxd .enject/store | head -1    # note the first 12 bytes
enject set anotherkey          # any write rotates the nonce
xxd .enject/store | head -1    # first 12 bytes are now different

3. 잘못된 비밀번호는 오류 반환

자동화: store::password::tests::test_wrong_password_returns_err

하나의 비밀번호로 저장소를 만든 다음, 다른 비밀번호로 잠금 해제를 시도하고 Err가 반환되는지 확인합니다.

root@kitploit:~
cargo test store::password::tests::test_wrong_password_returns_err

수동:

root@kitploit:~
enject list    # enter the wrong password
# output: "Wrong master password or corrupted store."
# exit code: 1

4. 변조된 암호문 거부 (AES-GCM 인증)

AES-GCM은 암호문에 대한 16바이트 인증 태그를 생성합니다. 단일 비트 뒤집기와 같은 모든 수정은 복호화가 진행되기 전에 검증을 실패하게 합니다. 일반 텍스트는 절대 노출되지 않습니다.

자동화: store::password::tests::test_tampered_ciphertext_returns_err

저장소 파일의 암호문 영역(12바이트 nonce 이후)에서 1바이트를 뒤집은 후, 복호화를 시도하고 Err를 반환하는지 확인합니다.

root@kitploit:~
cargo test store::password::tests::test_tampered_ciphertext_returns_err

수동:

root@kitploit:~
# Flip byte 20 (inside ciphertext, past the nonce)
python3 -c "
data = open('.enject/store', 'rb').read()
bad  = data[:20] + bytes([data[20] ^ 0xFF]) + data[21:]
open('.enject/store', 'wb').write(bad)
"
enject list
# output: "Wrong master password or corrupted store."

5. 확인되지 않은 en:// 참조 시 하드 오류

.env의 참조가 저장소에 일치하는 키가 없으면 enject run이 즉시 0이 아닌 코드로 종료됩니다. 하위 프로세스는 실행되지 않습니다.

자동화: env_template::tests::test_unknown_ev_ref_returns_err

resolve()를 일치하는 항목이 없는 참조로 호출하고 Err를 반환하는지 확인합니다.

root@kitploit:~
cargo test env_template::tests::test_unknown_ev_ref_returns_err

수동:

root@kitploit:~
echo "DB=en://nonexistent_key" > .env
enject run -- env
# output: Secret 'nonexistent_key' not found in store. Add it with: enject set nonexistent_key
# exit code: 1  (the `env` subprocess never ran)

향후 계획

1. 전역 저장소

여러 프로젝트에서 사용되는 비밀을 더 쉽게 관리할 수 있도록 선택적/추가 시스템 전체 저장소를 구현합니다.

2. 시스템 키체인 등과 통합

업데이트할 때마다 저장소 비밀번호를 수동으로 입력해야 하는 필요성을 줄입니다.

도구 다운로드