쓰 보안 C 고 안전한 C 어
-
18-09-2019 - |
문제
"사람을 원하지 않을 무료입니다.그는 단순히 원하는 안전해야 합니다." - H.L경험이
내가 하려고 쓰는 매우 안전한 C.아래에 나열의 일부 기술 사용 및 물은 그들의 보안 나는 그들은 생각한다.십시오지 않는 것을 주저하지 않는 눈물 나의 코드/선입견을 갈기갈기 찢었습니다.어떤 대답을 찾는 심지어 가장 사소한 취약점이나 가르치는 나에게 새로운 아이디어는 것입 높게 평가.
스트림에서 읽기:
에 따라 GNU C 프로그래밍 튜토리얼 getline:
Getline 기능 자동으로 확대하의 블록 는 데 필요한 메모리를 통해 realloc 기능,그래서 거기에 부족 의 공간 중 하나는 이유 getline 가 그래서 안전합니다.[..]는 것을 알 수 있습 getline 을 안전하게 처리하는 라인의 입력 없 얼마나 오래입니다.
나는 가정 getline 야 아래에 모든 입력,지 buffer overflow 에서 발생하는 경우에서 읽습니다.
- 내 가정이 올바른지?가 입력 및/또는 할당을 계획에서는 이것으로 이어질 수 악?예를 들어 어떤 경우 첫번째 문자 스트림에서 일 기괴한 캐릭터 컨트롤, 어쩌면 0x08 백스페이스(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:
사용하는 경우 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);
기 때문에 str1and str2 의 크기는 inputStr 고 더 이상 문자보다 strlen(inputStr)에서 읽을 수 있습 inputStr,그것은 불가능처럼 보이지만 주어 가능한 모든 값 에 대한 inputStr 을 일으킬 buffer overflow?
- 나는 정확합니까?은 거기에 이상한 소리가 나는 생각하지 않았는가?
- 이 있는 더 나은 방법을 쓰는 이?라이브러리는 이미 해결된다?
일반적인 질문:
안 게시의 큰 숫자를 질문이 난 기대하지 않는 사람이 그들 모두 대답.이 질문은 이상의 지침을 종류의 답변 내가 찾고 있습니다.나는 정말 배우고 싶 보안 C mindset.
- 무엇이 다른 안전한 C 숙어는 있는가?
- 무리요 항상 확인?
- 나는 어떻게 쓰는 단위 테스트는 이러한 규칙을 적용합니다?
- 는 방법을 적용할 수 있습니 제약 조건에서 테스트 용이성이나도 올바른 방법이 있을까?
- 모든 권장 정적/동적 분석 기술을 위한 도구 또는 C?
- 보안 C 관행을 당신은 당신을 따라 어떻게 당신이 그들을 정당화하는 자신과 다른 사람?
리소스:
의 많은 리소스를 빌려서 답변이 있습니다.
- 보안 프로그래밍을 위한 리눅스와 유닉스 HOWTO 데이비드 윌
- 안전하는 C 프로그래밍-SUN Microsystems
- 불안한 프로그래밍에 의해 예
- 추가 더 NOPS 블로 이러한 문제를 덮고
- 인증서 안전 이니셔티브 코딩
- flawfinder -정적 분석 도구
- 사용 Thm 들여오기/내보내기 플러그인을 증명하는 안전 여 Yannick 모
- libsafe
해결책
- 스트림에서 읽기
사 getline()
"이 자동으로 확대하는 블록의 메모리를 필요에 따라"이 사용될 수 있습으로 서비스 거부 공격으로 사소한 것입을 생성하는 입력했던 그렇게 긴 것을 배출할 수 있는 메모리 프로세스에 대한(또는,악 시스템!).한 번의 메모리 조건이 발생하면,다른 취약성도 있을 수 있습니다.의 동작 코드에서 낮은/고 메모리가 거의 좋은,그리고 예측하기 매우 어렵습니다.이럴는 것이 안전을 설정하는 합리적인 범위에서 모든 것을 특히,보안에 민감한 애플리케이션.
또한(으로 예상 언급하여 특별한 문자), getline()
만 당신에게 buffer;그것은 만들지 않는 어떠한 보증의 내용에 대한 버퍼(로 안전은 완전히 어플리케이션별로 다릅).그래서 소독 입력은 여전히 필수적인 부분을 처리하고 검증하는 사용자 데이터입니다.
- sscanf
나는 것을 선호하는 경향이 정규 표현식을 사용하는 도서관,매우 좁게 정의 regexps 사용자를 위한 데이터를 사용하기보다 sscanf
.이 방법으로 수행할 수 있는 좋은 거래의 유효성 검사에는 시간의 입력이 있습니다.
일반 코멘트
- 퍼지 사용할 수 있는 도구를 생성하는 임의의 입력(모두 유효하고 부)사용할 수 있는 테스트하는 입력 처리
- 버퍼 관리가 중요하다:buffer overflow,언더플로우의 메모리
- 경쟁 조건을 악용될 수 있습에 그렇지 않으면 보안 코드
- 바이너리 파일을 조작할 수 있었습을 주입하는 잘못된 값 또는 대형 값을 헤더,그래서 파일 형식으로 코드가 견고하다고 가정하지 않는 이진 데이터가 유효한
- 임시 파일이터의 보안 문제,그리고 신중하게 관리되어야
- 코드 주입 교체를 사용할 수 있는 시스템이나 런타임 라이브러리 호출로 악의적인 버전
- 플러그인을 제공하는 거대한 벡터 공격
- 일반적으로는 것이 좋을 명확하게 정의된 인터페이스는 사용자 데이터(또는 모든 데이터를 외부로부터 응용 프로그램)가정 무효과 적대까지 처리,살균 및 검증되고 유일한 방법은 사용자를 위한 데이터를 입력 응용 프로그램
다른 팁
나는 당신의 sscanf 예는 잘못된 것입니다.그것은 여전히 오버플로 할 때 사용하는 방법입니다.
하려고 이 지정하는 최대 바이트 수를 읽:
void main(int argc, char **argv)
{
char buf[256];
sscanf(argv[0], "%255s", &buf);
}
을 살펴 이 IBM dev 에 대한 문서에 대한 보호 buffer overflow.
의 측면에서 테스트,내가 쓸 것 프로그램을 생성하는 임의의 문자열을 임의의 길이 그들을 먹이 귀하의 프로그램을 만들고,그들이 적절하게 처리될 수 있습니다.
시작하기 좋은 장소를 찾고에서 이 데이비드 윌의 우수한 보안 코딩이트.
자신의 무료 온라인 예약"보안 프로그래밍을 위한 리눅스와 유닉스 HOWTO"훌륭한 리소스가 정기적으로 업데이트됩니다.
수도 있습 보기 좋아하는 그의 우수한 정적 해석기 FlawFinder 을 얻을 추가합니다.그러나,기억하지 않는 자동화된 도구입니다 보충을 위한 좋은 쌍의 경험있는,눈이나 다윗이 그렇게 화려한 색감을 둔다.
모든 정적 분석 도구와 같은 Flawfinder,은 단지 도구입니다.없는 도구를 대체할 수 있는 인간의 생각했습니다.에서 짧은 "바보는 도구입니다 아직도 바보".실수를 생각하는 분석 도구(예 flawfinder)는 대신 보안에 대한 훈련과 지식
나 개인적으로 사용되 다윗의 자원에 대한 여러 가지고 그들을 발견하실 수 있습니다.
Yannick 모 개발 Hoare/드는 가장 약한 전제 조건에 대한 시스템 C 박사 학위를 취득했고 에 적용되는 인증서 관리되는 문자열 라이브러리.그는 버그(페이지를 참조하십시오 197 의 자신의 회고록).좋은 소식은 라이브러리가 안전하 지금 그의 작동합니다.
당신은 수도에서 보 Les Hatton 의 웹 사이트 기 및에서 그의 예약 안전 C 에서 얻을 수 있는 아마존.
를 사용하지 않는 gets()
입력을 위해,사용 fgets()
.사 fgets()
, 는 경우,귀하의 버퍼가 자동으로 할당(i.e,"스택에서"),다음 사용하에서는 이러한 방법:
char buf[N];
...
if (fgets(buf, sizeof buf, fp) != NULL)
이 작동되는 것을 계속할 것입니다 당신이 결정하는 경우의 크기를 변경하려면 buf
.본 양식을 작성합니다:
#define N whatever
char buf[N];
if (fgets(buf, N, fp) != NULL)
기 때문에 먼저 양식을 사용하는 buf
을 결정하는 두 번째 인수하고 명확하다.