문제

코드를 작성할 때 높은 프로그램 품질을 보장하고 코드가 악의적으로 악용될 가능성을 피하기 위해 의식적으로 방어적으로 프로그래밍합니까?버퍼 오버플로 공격 또는 코드 삽입을 통해?

코드에 항상 적용할 "최소" 품질 수준은 무엇입니까?

도움이 되었습니까?

해결책

내 업무 분야에서는 코드 품질이 최고여야 합니다.
그래서 우리는 두 가지 주요 사항에 중점을 둡니다.

  1. 테스트
  2. 코드 검토

그들은 집에 돈을 가져옵니다.

다른 팁

abyx와 마찬가지로 제가 속한 팀에서는 항상 단위 테스트와 코드 검토를 사용합니다.그 외에도 사람들이 사용하지 않는 코드를 포함하지 않도록 하는 것도 목표입니다. 5월 사용 - 나는 지정된 대로 작동하는 객체에 필요한 기본 메소드 세트에 대해서만 코드를 작성하는 경향이 있습니다.나는 결코 사용되지 않을 수도 있지만 기능을 제공하는 방법을 통합하면 의도치 않게 "백도어" 또는 의도하지 않은/예기치 않은 사용이 시스템에 도입될 수 있다는 것을 발견했습니다.

결코 오지 않을 것을 예상하는 것보다 나중에 돌아가서 요청한 메서드, 속성 및 속성을 소개하는 것이 훨씬 쉽습니다.

"구성 요소"나 프레임워크에 들어가는 데이터에 대해서는 방어적인 자세를 취하는 것이 좋습니다."구성 요소" 또는 프레임워크 내에서는 데이터가 "정확하다"고 생각해야 합니다.

이렇게 생각합니다.올바른 매개변수를 제공하는 것은 호출자에게 달려 있습니다. 그렇지 않으면 모든 함수와 메소드가 모든 수신 매개변수를 확인해야 합니다.그러나 호출자에 대해서만 확인이 수행되는 경우 확인은 한 번만 필요합니다.따라서 매개변수는 "정확"해야 하며, 따라서 더 낮은 수준으로 전달될 수 있습니다.

  1. 항상 외부 소스, 사용자 등의 데이터를 확인하세요.
  2. "구성 요소" 또는 프레임워크는 항상 들어오는 호출을 확인해야 합니다.

버그가 있어 호출 시 잘못된 값이 사용된 경우.정말로 옳은 일은 무엇입니까?하나는 프로그램이 작업 중인 "데이터"가 잘못되었다는 표시만 있고 일부는 ASSERTS와 비슷하지만 다른 일부는 고급 오류 보고 및 가능한 오류 복구를 사용하기를 원합니다.어떤 경우든 데이터에 결함이 있는 것으로 확인되며 일부 경우에는 계속 작업하는 것이 좋습니다.(적어도 서버가 죽지 않으면 좋습니다)

위성에서 보낸 이미지는 고급 오류 복구를 시도하는 경우가 될 수 있습니다. 인터넷에서 다운로드한 이미지는 오류 아이콘을 표시할 수 있습니다.

나는 사람들이 개발 환경에서는 파시스트적이고 프로덕션에서는 자비로운 코드를 작성하도록 권장합니다.

개발 중에 문제가 눈에 띄지 않게 되거나 나중에 근본 원인을 추적하기 어려운 문제가 발생하는 것을 방지하기 위해 잘못된 데이터/로직/코드를 가능한 한 빨리 포착하려고 합니다.

프로덕션에서는 문제를 최대한 우아하게 처리합니다.실제로 복구할 수 없는 오류인 경우 이를 처리하고 해당 정보를 사용자에게 제공합니다.

예를 들어 벡터를 정규화하는 코드는 다음과 같습니다.개발 중에 잘못된 데이터를 입력하면 비명을 지르고, 프로덕션에서는 안전 값을 반환합니다.

inline const Vector3 Normalize( Vector3arg vec )
{
    const float len = Length(vec);
    ASSERTMSG(len > 0.0f "Invalid Normalization");
    return len == 0.0f ? vec : vec / len;
}

나는 항상 주입 공격과 같은 것을 방지하기 위해 노력합니다.그러나 내부 인트라넷 사이트에서 작업할 때 대부분의 보안 기능은 노력이 낭비되는 것처럼 느껴집니다.나는 아직도 그 일을 하고 있지만 어쩌면 그렇지 않을 수도 있습니다.

보안에 대한 특정 모범 사례가 있습니다.데이터베이스 애플리케이션의 경우 최소한 SQL 주입을 주의해야 합니다.

비밀번호 해싱, 연결 문자열 암호화 등과 같은 기타 작업표준이기도 합니다.

여기서부터는 실제 적용에 따라 다릅니다.

다행히 .Net과 같은 프레임워크로 작업하는 경우 다양한 보안 보호 기능이 내장되어 있습니다.

내부 앱의 경우에도 항상 방어적으로 프로그래밍해야 합니다. 왜냐하면 사용자가 운 좋게도 앱을 손상시키는 무언가를 작성할 수 있기 때문입니다.물론 돈을 속이려고 하는 것에 대해 걱정할 필요는 없지만 그래도 마찬가지입니다.항상 방어적으로 프로그래밍하고 앱이 실패할 것이라고 가정하십시오.

테스트 주도 개발을 사용하면 확실히 도움이 됩니다.한 번에 하나의 구성 요소를 작성한 다음 코드를 작성하기 전에 (테스트를 통해) 입력에 대한 모든 잠재적인 사례를 열거합니다.이렇게 하면 모든 내용을 다뤘고 어떤 내용도 작성하지 않았음을 확인할 수 있습니다. 시원한 아무도 사용하지 않지만 깨질 수 있는 코드입니다.

나는 공식적인 일을 하지 않지만 일반적으로 각 수업을 살펴보고 다음 사항을 확인하는 데 시간을 보냅니다.

  1. 유효한 상태에 있는 경우 유효한 상태를 유지합니다.
  2. 유효하지 않은 상태로 구성할 수 있는 방법이 없습니다.
  3. 예외적인 상황에서는 가능한 한 우아하게 실패합니다(종종 정리하고 던집니다).

때에 따라 다르지.

내가 진정으로 내 자신의 사용을 위해 무언가를 해킹한다면 나는 생각할 필요가 없는 최고의 코드를 작성할 것입니다.경고 등을 위해 컴파일러를 나의 친구로 삼으십시오.그러나 나는 그 지옥에 대한 유형을 자동으로 생성하지 않을 것입니다.

코드가 사용될 가능성이 높을수록, 가끔씩이라도 검사 수준을 높입니다.

  • 최소 매직 넘버
  • 더 나은 변수 이름
  • 완전히 확인되고 정의된 배열/문자열 길이
  • 계약 주장에 의한 프로그래밍
  • null 값 검사
  • 예외(코드 컨텍스트에 따라 다름)
  • 기본 설명 코멘트
  • 접근 가능한 사용법 문서(Perl 등의 경우)

나는 방어 프로그래밍에 대해 다른 정의를 취하겠습니다. 효과적인 자바 조쉬 블로크 지음.책에서 그는 호출자가 코드에 전달하는 변경 가능한 개체(예: setter)와 호출자에게 전달하는 변경 가능한 개체(예: getter)를 처리하는 방법에 대해 설명합니다.

  • setter의 경우 변경 가능한 개체를 모두 복제하고 복제본을 저장해야 합니다.이렇게 하면 호출자는 프로그램의 불변성을 깨뜨리기 위해 전달된 객체를 변경할 수 없습니다.
  • getter의 경우 인터페이스에서 허용하는 경우 내부 데이터의 변경 불가능한 보기를 반환합니다.그렇지 않으면 내부 데이터의 복제본을 반환합니다.
  • 내부 데이터가 포함된 사용자 제공 콜백을 호출할 때 콜백이 데이터를 변경하도록 의도하지 않는 한 변경 불가능한 뷰나 복제본을 적절하게 전송하세요. 이 경우 사실 이후에 유효성을 검사해야 합니다.

중요한 메시지는 외부 코드가 내부적으로 사용하는 변경 가능한 개체에 대한 별칭을 보유할 수 없도록 하여 불변성을 유지할 수 있도록 하는 것입니다.

나는 올바른 프로그래밍이 이러한 위험으로부터 보호할 수 있다고 생각합니다.보안 취약성으로 인해 일반적으로 더 이상 사용되지 않는 함수(적어도 Microsoft C++ 라이브러리에서는)를 방지하고 외부 경계를 넘는 모든 항목의 유효성을 검사하는 것과 같은 것입니다.

코드에서만 호출되는 함수는 호출자를 제어하므로 외부 경계를 넘지 않으므로 과도한 매개변수 유효성 검사가 필요하지 않습니다.다른 사람의 코드에서 호출되는 함수는 들어오는 매개변수가 어느 시점에서는 유효하지 않거나 악의적일 것이라고 가정해야 합니다.

노출된 함수를 처리하는 나의 접근 방식은 가능하면 도움이 되는 메시지를 표시하면서 간단히 충돌을 일으키는 것입니다.호출자가 매개변수를 바로 얻을 수 없다면 문제는 호출자의 코드에 있는 것이므로 문제를 해결해야 할 사람은 당신이 아니라 호출자입니다.(분명히 함수가 노출되었으므로 함수에 대한 문서를 제공했습니다.)

코드 삽입은 애플리케이션이 현재 사용자의 권한을 높일 수 있는 경우에만 문제가 됩니다.프로세스가 애플리케이션에 코드를 삽입할 수 있다면 코드를 메모리에 쉽게 작성하고 실행할 수 있습니다.시스템에 대한 전체 액세스 권한을 얻지 못하면 코드 삽입 공격은 의미가 없습니다.(이것이 관리자가 사용하는 애플리케이션을 더 적은 규모의 사용자가 쓸 수 있어서는 안 되는 이유입니다.)

내 경험에 따르면 방어적 프로그래밍을 적극적으로 사용한다고 해서 반드시 코드 품질이 향상되는 것은 아닙니다.내 말을 오해하지 마십시오. 사용자가 직면하게 될 종류의 문제를 포착하기 위해 방어적으로 프로그래밍해야 합니다. 사용자는 프로그램이 충돌할 때 그것을 좋아하지 않습니다. 그러나 이렇게 하면 코드를 유지 관리하기가 더 쉬워질 가능성이 없습니다. 테스트 등

몇 년 전, 우리는 단위 테스트, 코드 검토 등과 함께 소프트웨어의 모든 수준에서 어설션을 사용하는 정책을 만들었습니다.기존 애플리케이션 테스트 제품군과 함께 코드 품질에 상당히 긍정적인 영향을 미쳤습니다.

Java, 서명된 JAR 및 JAAS.

버퍼 오버플로 및 포인터/스택 해킹 공격을 방지하는 Java

JNI를 사용하지 마세요.(Java Native Interface)는 DLL/공유 라이브러리에 노출됩니다.

클래스 로딩이 보안 문제가 되는 것을 막기 위해 JAR에 서명했습니다.

JAAS를 사용하면 애플리케이션이 누구도 신뢰하지 않도록 할 수 있습니다. 심지어 자신도 신뢰하지 않습니다.

J2EE에는 역할 기반 보안에 대한 기본 지원이 포함되어 있습니다(제한적임).

이 중 일부에는 약간의 오버헤드가 있지만 보안 허점은 사라집니다.

간단한 대답: 때에 따라 다르지.너무 많은 방어 코딩 ~할 수 있다 심각한 성능 문제가 발생합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top