개발 이야기

🤫 Secrets, 소스 코드를 통한 유출 방지

inspiring-ini 2024. 8. 17. 10:33

(2021년 7월에 작성했던 발표자료)

 

📰 소스 코드를 통한 Credential 유출 피해 사례

가격, 거래량 그래프

 

🤭 여전히 GitHub에 등장하는 Credential들

  • https://github.com/search
  • keyword 기반 검색
  • pattern 기반 검색
  • 자동화 가능: GitHub의 검색 API를 통한 1차 filtering + 로컬에서 정규식 적용 검색으로 2차 filtering
  • 같은 실수를 반복하는 인간 - 유출된 credential 근처 코드를 확인해 보면 또 다른 종류의 credential을 발견하는 경우가 많음

 

 

🔍 Credential Scanner

소스 코드를 Scan하여 Credential일 가능성이 높은 것을 찾아내는 도구

Regular expression 규칙을 정의하고, 그 규칙에 맞는 string을 찾는 방식을 주로 취한다

rules = {
    "Slack Token": "(xox[p|b|o|a]-[0-9]{12}-[0-9]{12}-[0-9]{12}-[a-z0-9]{32})",
    "RSA private key": "-----BEGIN RSA PRIVATE KEY-----",
    "SSH (OPENSSH) private key": "-----BEGIN OPENSSH PRIVATE KEY-----",
    "SSH (DSA) private key": "-----BEGIN DSA PRIVATE KEY-----",
    "SSH (EC) private key": "-----BEGIN EC PRIVATE KEY-----",
    "PGP private key block": "-----BEGIN PGP PRIVATE KEY BLOCK-----",
    "Facebook Oauth": "[f|F][a|A][c|C][e|E][b|B][o|O][o|O][k|K].{0,30}['\"\\s][0-9a-f]{32}['\"\\s]",
    "Twitter Oauth": "[t|T][w|W][i|I][t|T][t|T][e|E][r|R].{0,30}['\"\\s][0-9a-zA-Z]{35,44}['\"\\s]",
    "GitHub": "[g|G][i|I][t|T][h|H][u|U][b|B].{0,30}['\"\\s][0-9a-zA-Z]{35,40}['\"\\s]",
    "Google Oauth": "(\"client_secret\":\"[a-zA-Z0-9-_]{24}\")",
    "AWS API Key": "AKIA[0-9A-Z]{16}",
    "Heroku API Key": "[h|H][e|E][r|R][o|O][k|K][u|U].{0,30}[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}",
    "Generic Secret": "[s|S][e|E][c|C][r|R][e|E][t|T].{0,30}['\"\\s][0-9a-zA-Z]{32,45}['\"\\s]",
    "Generic API Key": "[a|A][p|P][i|I][_]?[k|K][e|E][y|Y].{0,30}['\"\\s][0-9a-zA-Z]{32,45}['\"\\s]",
    "Slack Webhook": "https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}",
    "Google (GCP) Service-account": "\"type\": \"service_account\"",
    "Twilio API Key": "SK[a-z0-9]{32}",
    "Password in URL": "[a-zA-Z]{3,10}://[^/\\s:@]{3,20}:[^/\\s:@]{3,20}@.{1,100}[\"'\\s]",
    "SlackInternal": "slack-corp",
}

출처: https://github.com/trufflesecurity/truffleHog/blob/dev/scripts/searchOrg.py

 

 

주요 Credential Scanner

  • Open source
    • trufflehog 링크
      — 논문에서 자주 인용됨. 성능의 기준으로 삼아짐
    • Credential Digger 링크
      — AI support
    • shhgit 링크
    • Gitrob 링크
      — 현재는 gitlab에서 관리 중이며, gitlab 특화 기능 포함
    • gitleaks 링크
  • Non-open source

구분 특징

  1. 소스 코드 위치
    • Local에 있는 코드를 스캔
      $ gitleaks --path=path/to/local/repo
    • GitHub, GitLab 같이 Online에 있는 코드를 스캔
      $ python -m credentialdigger scan https://github.com/user/repo
  2. Scan 위치
    • 로컬 자원을 사용하여 스캔
      — Repository 크기가 커질수록 자원 부담이 커진다
    • 스캐닝 서버를 제공
      — Non-open source 서비스들의 방식. 유료인 경우가 많음
      — 소스 코드 유출이 걱정되는 사용자에게는 부적절
  3. Historical scan
    • 현재 상태 (Branch의 HEAD) 만 스캔
    • Branch의 commit history까지 전부 스캔
  4. 배포 방식
    • source code
    • executable
    • python library
    • docker
    • web service
  5. Customizing - 스캔할 규칙, 예외 규칙을 사용자가 설정할 수 있는지
    • Open source scanner들이 자유도가 높은 편
  6. Output format
    • JSON 과 같은 텍스트 파일
      — 자체적으로 parsing하여 분석하기 용이함
    • sqlite db 파일
      — table에 바로 query를 호출하여 분석하기 용이함
    • 웹 뷰
      예쁨
      — 위험도에 따라 highlight color를 다르게 주는 등, 개발자가 빠른 판단을 하기에 좋은 방식

오탐은 개발자를 귀찮게 해

  • token, secret 이라는 변수에 대입만 하면 무조건 탐지

  • Test code에 있는 가짜 credential 탐지

  • Placeholder 탐지

 

오탐을 줄이기 위한 연구

  1. Path 분석
    Code 내용 뿐 아니라 file path도 분석하여, test, node_modules, venv, example이 포함되어 있으면 탐지하지 않거나 경고 단계를 낮춘다
  2. Allowlist
    널리 알려진 example credential은 allowlist로 관리하여 탐지하지 않는다
  3. Validation
    여전히 활성화된 credential 인지를 credential 제공자 (AWS, Google 등)에게 확인하는 과정
    https://gitlab.com/gitlab-com/gl-security/security-operations/gl-redteam/secrets-hunting-misc
    범죄가 되지 않도록 잘 해야 한다..
  4. Code flow 분석
    a = "dkan/rmfwk_melon"
    ...
    
    PASSWORD = a
    ...
    
    some_api.call(pw=PASSWORD)

    이 때 a가 credential임을 탐지할 수 있게 한다
    연구에 따라서는 AST까지 그리기도 하는데, 언어마다 compiler가 필요하고 분석 시간이 오래 걸린다는 단점이 있다
  5. AI support
    • (논문) Secrets in Source Code: Reducing False Positives using Machine Learning
      https://ieeexplore.ieee.org/abstract/document/9027350
      코드에 특정 문자가 있는지, 20여가지 feature를 도출하고 직접 labeling하여 traditional machine learning 기법(combination of Logistic Regression, Naïve Bayes and SVM)으로 학습시킴
    • (특허) Cleartext password detection using machine learning
      https://patents.google.com/patent/US10762192B2/en
      Word embedding (e.g. Word2Vec)을 사용하여, 등장할 확률이 낮은 문자가 등장하는 경우에 password일 가능성을 높게 보겠다는 기조

🔑 (개발자가 실제로 가장 많이 접할) GitHub의 Secret Scanning

GitHub은 public repository에 대해서 수 년 전부터 이메일 경고 서비스를 제공해 왔음

출처: https://www.youtube.com/watch?v=aoL7pDrXt74

 

2020년도 GitHub 행사에서 두 차례 소개된 Secret Scanning 기능

https://www.youtube.com/watch?v=aoL7pDrXt74

 

https://www.youtube.com/watch?v=oaHBW9Il4Wg

 

2021년 4월 1일, private repository에 대해서도 정식 지원 시작 (링크) (유료)

설정 방법 (링크)

 

 

🐕🦶개발자는 무얼 하면 좋을까

    1. Pre-commit hook 사용

      Pre-commit hook으로 설정하여 local에서 commit 시 credential이 포함되지 못하게 한다.
      Remote repository upload를 원천차단 하는데 효과적임
    2. CI 에 적용
      • CI에서 원하는 credential scanner를 세팅하여 검사
      • GitHub의 secret scanning 옵션을 사용
      • 유료 서비스에 repository 등록
    3. 하지만 이미 repository에 올라간 지 오래라면.. 😢