경쟁 업체에 비밀을 노출시키지 않고 어떻게 PHP 웹 애플리케이션을 안전하게 디버깅해야합니까?


11

최근에 프로그램을 만들었습니다. 두 줄의 코드를 삭제하는 것을 잊었습니다. 그 실수는 매일 매일 800 달러가 들었습니다.

PHP로 프로그래밍하고있었습니다. 방문자가 프록시를 사용하는 경우 다른 곳으로 리디렉션합니다. 일부 코드에 이온 큐브가 포함되어있어 디버거를 사용할 수 없습니다. 프로그램은 무엇이든 상관없이 단순히 다른 곳으로 리디렉션하기 때문에 코드의 어느 부분이 실행되는지 알기가 어렵습니다.

그래서 나는 모든 곳에 디버깅 정보를 넣었다. 어쨌든 나중에 삭제할 것이라고 생각했습니다.

디버깅하는 가장 자연스러운 방법은 물론 디버깅 정보를 파일에 넣는 것입니다. 문제는 종종 프록시를 사용한다는 것입니다. 따라서 프로그램을 변경 한 후 종종 filezilla로 텍스트 파일을 다운로드해야합니다. 종종 텍스트 파일은 내가 보여야 할 것으로 생각되는 것을 보여주지 않습니다. 마지막으로 웹에 오류를 표시하기로 결정했습니다.

디버깅 모드를 고려했습니다. 그러나 디버깅 정보를 삭제하는 것을 잊어 버릴까 걱정됩니다.

예를 들어 사용자가? debuggingmode = 1을 수행하는 경우 디버깅 모드를 사용하는 것을 고려했습니다. 그러나 나는 어떻게 든 경쟁자가 비밀 키워드를 추측 할 수 있다는 편집증을 일으켰다.

대부분의 디버깅 정보를 삭제했습니다. 하나를 삭제하는 것을 잊어 버렸고 사용자가 올바른 국가의 프록시를 사용하는 경우에만 나타납니다. 나는 올바른 나라에서 프록시를 가지고 있지 않다는 것을 알았습니다. 프로그램이 24 시간 동안 작동 한 후 주 도메인에 업로드했습니다.

프록시를 사용하는 경쟁 업체는 디버깅 코드를 참조하십시오. 그는 그 아이디어를 모방했고 그것이 매일 800 달러를 잃어버린 방법입니다.

돌이켜 보면, 내가 어디로 잘못 갔는지 보는 데 어려움을 겪고 있습니다. 나는 매우 조심했다. 그러나 그것은 일어났다.

경쟁 업체에 비밀을 노출시키지 않고 어떻게 PHP 웹 애플리케이션을 안전하게 디버깅해야합니까?


5
버그가없는 소프트웨어는 물론 어떤 것도 절대로 확신 할 수 없습니다.
Tar

1
아주 작은 변화라도 프로그램 / 애플리케이션을 변경할 때마다 계속해서 철저히 테스트하십시오.
Rolen Koh

16
"경쟁자에게 비밀을 노출시키지 않고 어떻게 웹 애플리케이션을 안전하게 디버깅해야합니까?" -프로덕션 환경을 모방 한 테스트 환경을 만듭니다. 라이브 디버깅은 거의 필요하지 않습니다.
CodeCaster

8
두 줄의 디버깅 코드에서 하루에 800 달러의 가치가있는 것이 무엇인지 궁금합니다. 개인 암호 키를 덤프합니까?
Philipp

2
하루 전에 800 달러 이상을 벌었다면 ... 심지어 문제가 되나요? 그러나 디버그 코드를 라이브에 넣지 마십시오! 파일에 구성 디버그 모드를 부울 수 있습니다. debug == true 인 경우에만 디버그 코드를 인쇄하십시오. 이것은 답답할 가치가없는 최소한의 빠르고 더러운 방법입니다!
Anon343224user

답변:


37

나는 내가 어디로 잘못 갔는지 보는 데 어려움을 겪고있다.

가장 큰 실수는 바퀴를 재발 명했다는 것입니다. 로깅에 기본 메카니즘을 사용하는 대신 자신 만의을 발명하여 페이지 내의 정보를 표시했습니다. 로깅 프레임 워크는 로그를 로그 파일에 저장하므로 나중에 서버에 SSH로 연결하여 로그를 참조 할 수 있습니다.

버그는 버그가없는 코드를 생성한다는 것은 형식 증명 과 같은 특정 기술을 사용한다는 의미 입니다. 비용이 비싸기 때문에 이러한 기술은 항공기 교통 또는 우주 왕복선을 제어하는 ​​응용 프로그램과 같이 생명에 중요한 응용 프로그램에는 적합하지만 거의 모든 비즈니스 응용 프로그램 에는 무리가 있습니다.

그들이 Fast Company 잡지에 올바른 내용 을 쓴다는 것을 보십시오 .
이 기사는 NASA에서 사용되는 방법론과 소프트웨어 제작 비용에 대해 설명합니다.

기계화 증명 (Mackenzie 2004)을 참조하십시오 .
이 책은 소프트웨어의 자동 증명 이력을 요약하고 이러한 증명의 장단점을 설명하며 기업이 신뢰할 수있는 소프트웨어를 작성하는 데 일반적으로 사용하지 않는 이유를 설명합니다.

소프트웨어 응용 프로그램 품질을 보장하기 위해 비즈니스 응용 프로그램에 사용되는 많은 기술이 있습니다. 여기에는 다음이 포함되지만 이에 국한되지 않습니다.

  • 비공식 코드 검토
  • 공식 코드 검사,
  • 테크놀로지,
  • 개인 책상 코드 확인,
  • 기타

코드 완성 (McConnell 2004), 프로그래밍 생산성 (Jones 1986a), 소프트웨어 결함 제거 효율성 (Jones 1996) 및 파이팅 결함에 대해 배운 내용 (Shull et al. 2002)을 참조하십시오.

또한 지속적인 통합과 지속적인 제공을 잊지 마십시오. 수정 된 버전에 코드 검토 및 단위 테스트 중에 누락 된 문제가있는 것처럼 보이지만 앱이 배포되면 발견 된 경우 프로덕션 버전의 앱을 자동으로 작업 버전으로 롤백하는 데 도움이됩니다.

안전한 연속 배포의 비결을 참조하십시오 (동영상)
배포 전에 발견 할 수 없었던 버그가 프로덕션에서 너무 오래 머무르는 것을 방지하기 위해 Google에서 어떤 기술을 설정했는지 설명합니다. 또한 pdiff프리젠 테이션 레이어와 관련이없는 버그를 포함하여 버그를 잡는 데 사용 된 방법과 방법에 대해서도 설명 합니다.


13

프로덕션에서는 절대 디버그하지 않아야합니다.

항상 프로덕션 환경과 동일한 테스트 환경이 있어야하고 디버깅해야합니다.

테스트 환경에서 코드를 변경해야하는 경우 (예 : 디버깅 문 추가) 프로덕션 환경에 들어 가지 않도록해야합니다.

전문적인 설정은 일반적으로 다음과 같습니다.

Production
   ^
Staging
   ^
Development

응용 프로그램의 "Production", "Staging"및 "Development"인스턴스는 가능한 한 동일해야합니다. "Production"에서 발생하는 버그가 "Staging"및 "Development"에서 재현 될 수 있지만 여전히 완전히 분리되어야합니다. 인스턴스 중 하나에서 발생하는 일이 다른 인스턴스에 영향을 미치지 않도록 서로

문제를 분석해야 할 때는 "개발"에서 수행하십시오. 디버그 문으로 혼란스럽고 원하는 모든 것을 실험하십시오. 솔루션을 찾은 경우 "스테이징"의 변경되지 않은 코드베이스에 해당 수정 사항을 적용하고 수정 사항이 작동하는지 확인하십시오. 그런 다음 수정 사항을 "생산"으로 승격하십시오.

적절한 버전 관리 및 빌드 관리 시스템이 도움이 될 수 있습니다.


1
그것이 내가 한 일입니다. 다른 도메인에서 먼저 디버깅합니다. 그 후, 나는 새로운 것으로 이동합니다. 그러나 다른 도메인의 버그는 여전히 존재합니다.
user114310

1
@ user114310, 개발 / 테스트 환경은 외부 세계 (로컬 호스트에 있거나 VPN이 필요하거나 이와 유사한 것)만으로는 접근 할 수 없습니다. 디버그 코드를 삽입했는데 프로덕션 환경으로 넘어 가기 전에 제거하지 않은 경우 이는 인적 오류이며이를 방지 할 수있는 기술적 인 것은 없습니다. 더 조심하십시오.
Brian S

3
@ user114310 죄송합니다. 이해가되지 않습니다. 스테이징에서 버그를 수정했지만 프로덕션에 해당 수정을 적용했을 때 버그가 여전히 있습니까? 즉, 버그를 올바르게 재현하지 않았고 실수로 다른 것을 수정 한 것입니다. 개발시 버그를 재현 할 수 없으면 개발 환경이 프로덕션 환경과 동일하지 않음을 의미합니다. 버그를 조사하기 전에 먼저 수정해야한다는 것을 발견했을 때.
Philipp

4

노력이 가치가 없기 때문에 이것은 거의 이루어지지 않습니다. 하루에 800 달러를 잃어도 프로그램 수정을 입증하는 노력이 그보다 빨리 커지므로 비즈니스를 수행 할 비즈니스 사례가 없음을 의미합니다.

특정되는 것은 경우 입니다 (우주 왕복선 소프트웨어 또는 미사일 제어 등) 많은, 당신은 형식 등을 검증, 모든 가능한 입력의 철저한 테스트, 부여를 수행하는 것이 가치, 그것은 또한 매우이다 어려울 뿐만 아니라 느리고 비싸다. 그러나 수십억 달러의 예산을 가진 프로젝트도 매우 밝은 사람들이있는 경향이 있습니다. (또는 아마도 그들은 예전의 헤드 라인이 그 규칙과 모순되는 것처럼 보였습니다.)


1
NASA 조차도 잘못 알고 있습니다. 당신이 원하는만큼 많은 노력을 기울일 수 있지만, 어떤 것들은 단순히 인간의 이해를 넘어서므로 매우 확신하기 어렵습니다.
Phoshi

1
+1 : 공식 검증은 문제입니다. 더 자세한 정보를 얻을 수 있다면 좋을 것입니다. 나는 그것이 일이라는 것을 알고 있지만 더 자세한 내용을 찾을 단어가 없습니다. 예를 들어 모든 입력을 테스트하여 유한 상태 기계로 축소, 1 차 논리로 축소하여 검증합니다. 이것에 대한 단어는 무엇입니까? 이 검증은 증거입니까? 나는 생각합니다.
Lyndon White

공식적인 검증이 있지만 확실하지는 않지만 특정 신뢰 수준에 검증을 제공 할 수있는 휴리스틱 검증도 있습니다. 나는 대학의 주제에 대해 많이 기억하지 못하지만 우리가 과정에서 사용한 도구 중 하나는 Spin입니다. 그것에 대한 설명 중 일부는 올바른 단어가 무엇인지 대답 할 수 있습니다.
Rig

2

때로는 라이브 시스템을 디버깅해야합니다. 예, 개발 또는 준비 사본이 있어야합니다. 그러나 항상 차이점이 있습니다. 고객 하드웨어에서 코드가 과도하게 실행되는 경우 특히 그렇습니다. 또는 잠재적으로 많은 다른 고객 설치.

과거 에는 & debugging = 1 기법을 사용했습니다. 나는 대부분의 PHP 개발자가 가지고 있다고 생각합니다. 이것은 코드에서 스위치를 뒤집어 응용 프로그램에서 더 자세한 디버깅을 가능하게했습니다. 이 정보는 일반적으로 로그 파일 (일반적으로 아파치 로그 (error_log () 사용))에 덤프됩니다. 그러나 출력 할 수도 있습니다. 예를 들어 프로파일 러는 정보를 수집 한 다음 페이지 하단에 다양한 벤치 마크를 출력합니다. 디버깅 정보를 HTML 주석 또는 페이지 소스를 볼 때만 볼 수있는 숨겨진 요소로 출력 할 수도 있습니다.

사이트에 '사용자'가있는 경우 특정 사용자로만 디버깅을 제한 할 수 있습니다. 이런 식으로 누군가 디버깅을 활성화하려고 시도하더라도 해당 사용자로 로그인하지 않으면 작동하지 않습니다.

이제 FileZilla를 사용하여 서버에 연결한다고 언급했습니다. 개발자는 서버에 대한 SSH 액세스 권한이 있어야합니다. 그러면 디버깅이 훨씬 쉬워집니다. 예를 들어, 디버깅 명령문을 Apache 오류 로그에 출력하려는 ​​경우 해당 파일을 IP 주소로 쉽게 grep하고 마지막 페이지 요청에서 생성 된 디버깅 정보를 볼 수 있습니다.


1

다른 사람들은 이미 일반적인 경우를 다뤘습니다.

공식 검증 (/ Proven Code) : 실제 프로그램에는 적합하지 않지만 공식적으로 입증 된 4000 라인 OS 커널이 있지만 많은 러시아 CS 박사 과정 학생들이 수개월이 걸렸습니다 (이 프로젝트의 이름을 기억하면 의견을 말하십시오)

CI 테스트 << 자동 테스트 << 테스트 : 커버리지 도구를 사용하여 테스트 케이스에 100 % 커버리지가 있는지 확인하십시오.

디버그 코드를 프로덕션 환경에 남겨 두는 두 가지 옵션이 있습니다. 두 가지 옵션이 있습니다. 두 가지 옵션 모두 새로운 (준비 / 최종 테스트) 환경에 배포하는 과정에서 소스 코드를 다시 준수해야합니다.

  1. 컴파일 타임에 제거하십시오. C # 및 C와 같은 구조로 디버그 코드를 래핑 #ifdef DEBUG하여 빌드 대상 (디버그 또는 릴리스)을 확인하고 컴파일시 자동으로 제거합니다.

  2. 배포시 플래그를 지정하십시오. 실제 환경에서 실행해서는 안되는 코드 근처에 주석을 추가하십시오. 예를 들어 //TODO: Remove This Before Deployment, 스테이징으로 마이그레이션 (배포) 될 때 코드를 컴파일하기 전에 //TODO:소스 코드에 플래그 주석 (예 :)이 없는지 확인하는 간단한 스크립트를 통해 코드를 실행하십시오 .

전자가 장기적인 경우 다시 제안하고 (예 : 자세한 로깅 모드) 나중에 디버깅하는 동안 빠른 해킹 인 경우 (예 : 코드를 통해 다양한 printfs가 흩어짐)


0

다른 사람들이 나에게 말했듯이, 가능하면 자동화되고 코드 범위가 좋은 많은 테스트 (단위 및 기능)가 버그가없는 소프트웨어를 갖추는 열쇠입니다.

문제에 대한 설명을 충분히 이해하면 서버에서 제공하는 페이지에 디버깅 정보가 표시됩니다. 이 경우 해당 정보를 서버의 적절한 로그에 저장하는 것을 고려해야합니다. 이렇게하면 'verbose'버전을 프로덕션에 배포하더라도 최종 사용자에게 표시되지 않습니다. 이것은 다른 이유가없는 한 현재 진행중인 프로젝트를 수행하는 데 도움이되는 것입니다.


0

프로덕션에서 디버깅에 대해 다른 사람들이 말하는 것은 맞습니다. 그러나 나는 때때로 어쨌든 그것을했다. 그리고 나는 당신의 것보다 더 안전한 방법이 있다고 생각합니다.

나는 그런 높은 보안을 스스로 필요로하지 않으며, 사용자가 화면에서 많은 횡설수설을 보길 원하지 않습니다.

$debug = true;
$allowed_ips = array('192.168.0.220','173.46.89.255'); // limit to your own ip's. If your competitor knows them, though, he can spoof it! But if your stuff is not top secret, it's ok. 

if(!in_array($_SERVER['REMOTE_ADDR'],$allowed_ips) ) {
  $debug = false;
}

if($debug) {
  echo '<pre>' . print_r($some_variable) . '</pre>';
}

이제 사용자는 정말로 원하지 않으면 디버깅을 볼 수 없습니다. $ 800 / day가이 디버그 정보를 비밀로 유지하는 데 의존 하는 경우 위의 코드를 사용하지 마십시오 . 그러나 정보가 그렇게 중요하지 않은 경우 위의 내용은 GET 변수에 의존하거나 국가 전체에 비밀을 밝히는 것보다 훨씬 낫습니다.

또는 debug기준에 따라 인쇄가 허용되는지 여부를 확인 하는 클래스 또는 함수를 만들 수 있습니다 . 그게 내가하는 일입니다.

이 같은:

class debug {
  public $on = false;
  public static function print($variable) {
    if($on) {
      echo '<pre>' . print_r($some_variable) . '</pre>';
    }
  }
}

debug::print($some_variable); // class checks if printing is allowed. If not, no printing occurs.

하루에 800 달러 (개발 중)가 될 프로그램의 경우, 아파치 모드 인증을 사용하여 사이트의 모든 부분에 액세스하기 위해 암호를 요구하고 디버그 정보를 특정 IP로 제한합니다. 귀하의 질문에 따라 보안을 강화해야한다고 생각합니다.


0

실제로 여기에 두 가지 추가 유효성 검사가 있습니다. 하나는 &debug=1요청 의 매개 변수입니다. "비밀" 페이지에 대한 호출 (바람직하게는 인증 사용) 을 통해서만 활성화 할 수있는 일부 특수 세션 변수 또는 쿠키 설정을 사용할 수도 있습니다 .

두 번째 유효성 검사는 구성 파일에 있어야하며, IP 범위를 가진 배열이고 해당 배열의 IP 호출 만 디버깅 기능을 트리거 할 수 있습니다. 같은

구성에서 :

$debugAllowedIPs = array('127.0.0.1', '192.168.0.1', /* add more IPs here */);

전 세계에 액세스 할 수있는 다음 방법을 사용하십시오.

function getClientIp() {
    if (!empty($_SERVER['HTTP_CLIENT_IP']))  return $_SERVER['HTTP_CLIENT_IP'];
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR'];
    return $_SERVER['REMOTE_ADDR'];
}

그리고 코드에서 다음과 같은 것을 호출하십시오.

if (in_array(getClientIp(), $debugAllowedIPs)) { /* show debug info here */ }

getClientIp()메서드 의 코드 는 값 $_SERVER['HTTP_X_FORWARDED_FOR']이 쉽게 스푸핑 되므로 안전하지 않지만 질문의 요점을 파악하는 데 도움이됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.