Secure C 및 Secure C 관용구 쓰기
"평범한 사람들은 자유로워지고 싶어하지 않습니다.그는 그저 안전하기를 원할 뿐입니다." - H.L. 멘켄
나는 매우 안전한 C를 쓰려고 시도하고 있습니다.아래에는 제가 사용하는 몇 가지 기술이 나열되어 있으며 제가 생각하는 것만큼 안전한지 물어봅니다.부디 주저하지 마시고 제 코드/선개념을 갈기갈기 찢어버리세요.가장 사소한 취약점이라도 찾아내거나 새로운 아이디어를 알려주는 답변은 높은 평가를 받을 것입니다.
스트림에서 읽기:
GNUC 프로그래밍 튜토리얼 getline에 따르면:
getline 기능은 reloc 기능을 통해 필요에 따라 메모리 블록을 자동으로 확장하므로 공간이 부족하지 않습니다. getline이 안전한 이유 중 하나입니다.[..] 입력 라인이 아무리 길어도 안전하게 처리할 수 있습니다.
getline은 모든 입력 하에서 스트림에서 읽을 때 버퍼 오버플로가 발생하지 않도록 해야 한다고 생각합니다.
- 제 추측이 맞습니까?이것이 악용으로 이어질 수 있는 입력 및/또는 할당 체계가 있습니까?예를 들어 스트림의 첫 번째 문자가 특이한 제어 문자인 경우 0x08 BACKSPACE(ctl-H)일 수 있습니다.
- getline을 수학적으로 안전하다고 증명하는 작업이 이루어졌습니까?
실패 시 Malloc이 Null을 반환합니다.
malloc에서 오류가 발생하면 malloc에서 NULL 포인터를 반환합니다.이는 NULL (0x0) 포인터에 포인터 산술을 적용할 수 있기 때문에 보안 위험을 나타냅니다. 따라서 위키피디아는 권장합니다.
/* Allocate space for an array with ten elements of type int. */
int *ptr = (int*)malloc(10 * sizeof (int));
if (ptr == NULL) {
/* Memory could not be allocated, the program should handle
the error here as appropriate. */
}
보안 검색:
sscanf를 사용할 때 저는 추출할 문자열의 크기를 입력 문자열의 크기에 할당하는 습관이 생겼습니다. 오버런의 가능성을 피하기를 바랍니다.예를 들어,
const char *inputStr = "a01234b4567c";
const char *formatStr = "a%[0-9]b%[0-9]c":
char *str1[strlen(inputStr)];
char *str2[strlen(inputStr)];
sscanf(inputStr, formatStr, str1, str2);
str1과 str2는 inputStr의 크기이고 inputStr에서 strlen(inputStr) 이상의 문자를 읽을 수 없기 때문에 inputStr에서 버퍼 오버플로가 발생할 가능성이 있는 모든 값을 고려할 때 불가능해 보입니다.
- 내가 맞나요?제가 미처 생각하지 못한 이상한 코너 케이스가 있나요?
- 이 글을 쓰는 더 좋은 방법이 있습니까?이미 해결한 라이브러리?
일반 질문:
제가 많은 질문을 올렸지만 아무도 그 질문에 모두 답하지는 않을 것으로 예상합니다.그 질문들은 제가 찾고 있는 답변의 종류에 대한 가이드라인에 가깝습니다.저는 안전한 C 사고방식을 꼭 배우고 싶습니다.
- 또 다른 안전한 C 관용구는?
- 항상 확인해야 하는 코너 케이스는 무엇입니까?
- 이 규칙을 적용하기 위해 단위 테스트를 작성하려면 어떻게 해야 합니까?
- 테스트 가능성 또는 올바른 방법으로 제약 조건을 적용하려면 어떻게 해야 합니까?
- C에 권장되는 정적/동적 분석 기술이나 도구가 있습니까?
- 귀하는 어떤 보안 C 관행을 따르고 있으며, 귀하와 다른 사람들에게 어떻게 이를 정당화합니까?
리소스:
많은 자료들이 답변들로부터 빌려왔습니다.
- David Wheeler의 Linux 및 Unix HOWTO용 보안 프로그래밍
- Secure C 프로그래밍 - SUN 마이크로시스템즈
- 예제에 의한 안전하지 않은 프로그래밍
- 추가 NOPS - 이러한 문제를 다루는 블로그
- CERT 보안 코딩 이니셔티브
- 탐상기 - 정적 분석 도구
- 야닉 모이의 안전성 증명을 위해 Thm Provers 사용
- 안전한
나는 당신의 스캔 예시가 틀렸다고 생각합니다.그렇게 사용해도 여전히 넘칠 수 있습니다.
읽어 볼 최대 바이트 수를 지정하는 시도:
void main(int argc, char **argv)
{
char buf[256];
sscanf(argv[0], "%255s", &buf);
}
버퍼 오버플로를 방지하는 방법에 대한 IBM 개발 기사를 살펴보십시오.
테스트 측면에서, 저는 무작위 길이의 문자열을 생성하여 당신의 프로그램에 공급하는 프로그램을 작성하고, 그것들이 적절하게 처리되는지 확인할 것입니다.
스트림에서 읽기
그 은.
getline()
"필요에 따라 메모리 블록을 자동으로 확대합니다."는 프로세스(또는 시스템)에 사용 가능한 메모리를 소진할 정도로 긴 입력을 생성하는 것은 사소한 일이므로 서비스 거부 공격으로 사용될 수 있음을 의미합니다.메모리 부족 상태가 발생하면 다른 취약성도 작동할 수 있습니다.메모리 부족/무메모리에서 코드의 동작은 거의 양호하지 않으며 예측하기 매우 어렵습니다.IMHO는 특히 보안에 민감한 애플리케이션에서 모든 것에 합리적인 상한을 설정하는 것이 더 안전합니다.와 같이 ()
getline()
는 버퍼만 제공하고 버퍼의 내용에 대해서는 보장하지 않습니다(안전성은 애플리케이션에 전적으로 의존하기 때문에).따라서 입력을 검사하는 것은 사용자 데이터를 처리하고 검증하는 데 여전히 필수적인 부분입니다.스스캔프
는 를 보다 정규 사용하고 표현식 라이브러리를 합니다.
sscanf
. 이렇게 하면 입력 시 많은 유효성 검사를 수행할 수 있습니다.일반댓글
- 입력 처리를 테스트하는 데 사용할 수 있는 임의 입력(유효 및 무효)을 생성하는 퍼징 도구를 사용할 수 있습니다.
- 버퍼 오버플로, 언더플로, 메모리 부족 등 버퍼 관리가 중요합니다.
- 레이스 상태를 보안 코드로 이용할 수 있음
- 이진 파일을 조작하여 잘못된 값 또는 오버사이즈 값을 헤더에 주입할 수 있으므로 파일 형식 코드는 rock-solid여야 하며 이진 데이터가 유효하다고 가정하지 않아야 함
- 임시 파일은 종종 보안 문제의 원인이 될 수 있으므로 신중하게 관리해야 합니다.
- 코드 주입은 시스템 또는 런타임 라이브러리 호출을 악성 버전으로 대체하는 데 사용될 수 있습니다.
- 플러그인은 공격을 위한 거대한 벡터를 제공합니다.
- 일반적인 원칙으로, 사용자 데이터(또는 애플리케이션 외부의 데이터)가 처리, 소독 및 검증될 때까지 유효하지 않고 적대적인 것으로 간주되고 사용자 데이터가 애플리케이션에 진입할 수 있는 유일한 방법인 명확하게 정의된 인터페이스를 제안합니다.
이것을 살펴보기에 좋은 곳은 David Wheeler의 훌륭한 보안 코딩 사이트입니다.
그의 무료 온라인 책 "리눅스 및 유닉스 HOWTO용 안전한 프로그래밍"은 정기적으로 업데이트되는 훌륭한 자료입니다.
또한 그의 뛰어난 정적 분석기인 FlakeFinder를 통해 몇 가지 힌트를 얻을 수 있습니다.하지만 경험이 풍부한 두 눈을 위한 자동화된 도구는 없다는 것을 기억하시기 바랍니다. 또는 David가 그렇게 다채롭게 표현한 것처럼 말이죠.
Flakefinder와 같은 모든 정적 분석 도구는 도구에 불과합니다.어떤 도구도 인간의 생각을 대체할 수 없습니다!간단히 말해서, "도구를 가진 바보는 여전히 바보입니다."분석 도구(예: 결함 탐지기)가 보안 교육 및 지식의 대체물이라고 생각하는 것은 잘못된 것입니다.
저는 몇 년 동안 David의 자원을 개인적으로 사용해 왔고 그것들이 훌륭하다는 것을 알게 되었습니다.
예제에 의한 안전하지 않은 프로그래밍
답이 몇 개 있는 블로그
야닉 모이(Yannick Moy)는 박사과정 중 C를 위한 Hoare/Floyd 최약체 전제조건 시스템을 개발하여 CERT 관리 스트링 라이브러리에 적용했습니다.그는 많은 버그를 발견했습니다. (그의 회고록 197쪽 참조)좋은 소식은 도서관이 그의 일에 더 안전하다는 것입니다.
여기 Les Hatton의 웹사이트와 아마존에서 얻을 수 있는 그의 책 Safer C도 볼 수 있습니다.
사용하지않습니다.gets()
용,fgets()
. 사용방법fgets()
"(, "에"), 합니다 합니다.
char buf[N];
...
if (fgets(buf, sizeof buf, fp) != NULL)
합니다의 에도 계속 합니다.buf
이 이 양식은 다음과 같습니다.
#define N whatever
char buf[N];
if (fgets(buf, N, fp) != NULL)
는 을 사용하기 입니다.buf
두 번째 인수를 결정합니다. 그리고 더 명확합니다.
언급URL : https://stackoverflow.com/questions/2008173/writing-secure-c-and-secure-c-idioms
'source' 카테고리의 다른 글
C 전처리기 연결이 #정의 바깥쪽에 있음 (0) | 2023.09.19 |
---|---|
코드 사인 오류:'iPhone Developer' ID가 기본 키 체인의 유효한 인증서/개인 키 쌍과 일치하지 않습니다. (0) | 2023.09.19 |
페이지 로드 시 표현식 표시 안 함 (0) | 2023.09.19 |
다중 컨스트럭터용 자바스크립트 패턴 (0) | 2023.09.19 |
문서의 시작 부분에만 XML 선언이 허용됨 (0) | 2023.09.19 |