SCW 아이콘
영웅 배경, 구분선 없음
블로그

자바 문제 - 비트별 연산자와 부울 연산자

앨런 리처드슨
게시됨 Feb 07, 2021
마지막 업데이트: 2026년 3월 9일

자바 문제 - 비트별 연산자와 부울 연산자

“Java Gotcha” - 실수로 구현하기 쉬운 일반적인 실수 패턴입니다.

자바에서 실수로 빠질 수 있는 아주 간단한 문제 중 하나는 바로 부울 비교 연산자 대신 비트별 연산자를 사용하는 것입니다.

예를 들어, 정말로 “&&”를 쓰려고 했을 때 단순한 잘못 입력으로 인해 “&”를 쓸 수 있습니다.

코드를 검토할 때 흔히 배우는 휴리스틱은 다음과 같습니다.

“&” 또는 “|”를 조건문에 사용하는 것은 의도된 것이 아닐 수 있습니다.

이 블로그 게시물에서는 휴리스틱을 살펴보고 이 코딩 문제를 식별하고 해결할 수 있는 방법을 알아보겠습니다.


무슨 문제야? 비트별 연산은 부울 값에서 잘 작동합니다.


부울 값과 함께 비트 연산자를 사용하는 것은 완벽하게 유효하므로 Java는 구문 오류를 보고하지 않습니다.

비트 연산자 OR(|)과 AND(&) 모두에 대한 진리표를 탐색하기 위해 JUnit 테스트를 구성하면 비트 연산자의 출력이 진리표와 일치하는 것을 확인할 수 있습니다. 이러한 점을 고려하면 비트 연산자를 사용하는 것이 문제가 되지 않는다고 생각할 수도 있습니다.

AND 트루스 테이블

a가 있는 세 개의 열, b가 있는 열, 마지막 열(a^b)이 있는 열


@Test
무효 비트 연산자 및 진실 테이블 () {
어설션. 같음 어설션 (참, 참, 참);
어설션. 같음 어설션 (거짓, 참, 거짓);
어설션. 같음 어설션 (거짓, 거짓, 참);
어설션. 같음 어설션 (거짓, 거짓, 거짓);
}


테스트를 통과했습니다. 이것은 완벽하게 유효한 Java입니다.


OR 진리값 표


a가 있는 세 개의 열, b가 있는 열, 마지막 열(a v b)이 있는 열


@Test
무효 비트 연산자 또는 진실 테이블 () {
어설션. 어설션 같음 (참, 참 | 참);
어설션. 어설션 같음 (참, 참 | 거짓);
어설션. 같음 어설션 (참, 거짓 | 참);
어설션. 같음 어설션 (거짓, 거짓 | 거짓);
}


이 테스트도 통과했는데 왜 “&&'와 “||'를 선호할까요?


진리표 이미지는 다음을 사용하여 생성되었습니다. 진실 테이블 도구 ...에서 web.standfor.edu.


문제: 단락 작동


진짜 문제는 비트 연산자(&, |)와 부울(&&, ||) 연산자 간의 동작 차이입니다.

부울 연산자는 단락 연산자이며 필요한 만큼만 평가합니다.

예:

만약 (격언!= null 및 인수. 길이 () > 23) {
시스템.out.printLN (args);
}


위 코드에서는 비트 연산자가 사용되었으므로 두 부울 조건이 모두 평가됩니다.

  • 인수!= 제로
  • 인수. 길이 () > 23

이렇게 하면 인수가 null인 경우 내 코드가 NullPointerException으로 열립니다. 두 부울 조건을 모두 평가해야 하기 때문에 인수가 null인 경우에도 항상 args.length 검사를 수행하기 때문입니다.


부울 연산자 단락 회로 평가


&&를 사용하는 경우 예:

만약 (격언!= null 및 인수. 길이 () > 23) {
시스템.out.printLN (args);
}


우리가 그 인수를 알게 되자마자!= null이 false로 평가되면 조건 표현식 평가가 중지됩니다.

오른쪽을 평가할 필요는 없습니다.

오른쪽 조건의 결과가 무엇이든, Boolean 표현식의 최종 값은 false가 됩니다.


하지만 프로덕션 코드에서는 이런 일이 절대 일어나지 않을 것입니다.


이는 매우 쉽게 범할 수 있는 실수이며 정적 분석 도구에서 항상 알아차릴 수 있는 것은 아닙니다.

다음 Google Dork를 사용하여 이 패턴의 공개 사례를 찾을 수 있는지 확인했습니다.

파일 형식: “! 인 경우 자바=null &”
이 검색은 Android의 일부 코드를 루트 윈도우 컨테이너에 가져왔습니다.
ISDocument = 인텐트!= null & Intent.isDocument ()


입력문에서 비트 연산자를 사용하여 값을 마스킹하는 경우가 많기 때문에 코드 검토를 통과할 수 있는 코드 유형입니다. 하지만 이 경우 결과는 위의 if 문 예제와 같습니다. 인텐트가 항상 null인 경우 NullPointerException이 발생합니다.

우리는 종종 방어적인 방식으로 코딩하고 중복 코드를 작성하기 때문에 이 구문을 사용하지 않는 경우가 많습니다. 확인해 보세요! = null은 대부분의 사용 사례에서 중복될 수 있습니다.

이것은 프로그래머가 프로덕션 코드에서 만든 오류입니다.

검색 결과가 얼마나 최신인지는 모르겠지만 검색을 실행했을 때 Google, Amazon, Apache... 그리고 제 코드가 포함된 결과가 나왔습니다.

최근 풀 리퀘스트 내 오픈 소스 프로젝트 중 하나에서 정확히 이 오류를 해결해야 했습니다.

만약 (입력!=null 및 type.trim (). 길이 () >0) {
미디어 유형 정의 목록을 승인합니다. 추가 (type.trim ());
}


이것을 찾는 방법


몇 개의 정적 분석기에서 샘플 코드를 확인했을 때 아무도 이 숨겨진 자체 파괴 코드를 발견하지 못했습니다.

Secure Code Warrior 팀으로서 우리는 이 문제를 해결할 수 있는 아주 간단한 센세이 레시피를 만들고 검토했습니다.

비트 연산자는 완벽하게 유효하며 대입에 자주 사용되기 때문에 if 문 사용 사례와 비트 연산자 &를 사용하여 문제가 되는 코드를 찾는 데 중점을 두었습니다.

검색:
표현식:
다음 중 하나:
- 입력:
조건: {}
값:
대소문자 구분: 거짓
일치: “.* &.*”


이것은 정규 표현식을 사용하여 조건 표현식으로 사용될 때 "& "와 일치시킵니다 (예: if 문에서).

이 문제를 해결하기 위해 우리는 다시 정규 표현식을 사용했습니다. 이번에는 QuickFix의 sed 함수를 사용하여 표현식의 &를 &&로 전역적으로 대체했습니다.

사용 가능한 수정 사항:
- 이름: “비트 AND 연산자를 논리 AND 연산자로 바꾸기”
조치:
- 다시 작성:
받는 사람: “{{#sed}} s/&/&/g, {{{.}}} {{/sed}}”


엔드 노트

여기서는 비트 연산자의 가장 일반적인 오용, 즉 부울 연산자가 실제로 의도된 경우에 대한 내용입니다.

예를 들어 대입 예제와 같은 다른 상황이 발생할 수 있지만 레시피를 작성할 때 위양성 식별을 피해야 합니다. 그렇지 않으면 레시피가 무시되거나 꺼집니다. 우리는 가장 자주 발생하는 상황에 맞는 레시피를 만듭니다. Sensei가 발전함에 따라 더 많은 일치 조건을 포괄하기 위해 검색 기능에 특정 기능을 추가할 예정입니다.

현재 형태로 보면 이 레시피는 많은 실제 사용 사례를 식별할 수 있습니다. 가장 중요한 것은, 내 프로젝트에서 보고된 내용입니다.

참고: 찰리 에릭센, 마티유 칼리, 로빈 클레어하우트, 브라이슨 애크스, 네이선 데스멧, 다우니 로버스쇼텐 등 코드 워리어들이 이 예제와 레시피 리뷰에 기여했습니다. 도와주셔서 감사합니다.


---


IntelliJ 내에서 “환경설정\ 플러그인” (Mac) 또는 “설정\ 플러그인” (Windows) 을 사용하여 Sensei를 설치한 다음 “센세이 보안 코드”를 검색하기만 하면 됩니다.

Secure Code Warrior 계정의 `sensei` 저장소에는 이러한 블로그 게시물(이 게시물 포함)에 대한 많은 소스 코드와 레시피가 있습니다.

https://github.com/securecodewarrior/sensei-blog-examples

선생님에 대해 더 알아보기


리소스 보기
리소스 보기

이 블로그 게시물에서는 일반적인 Java 코딩 실수(조건 연산자 대신 비트 연산자 사용), 이로 인해 코드가 취약해지는 오류, Sensei를 사용하여 문제를 해결하고 감지하는 방법을 살펴보겠습니다.

더 많은 것에 관심이 있으신가요?

Alan Richardson은 20년 이상의 전문 IT 경험을 보유하고 있으며, 개발자로 일하며 테스터부터 테스트 책임자까지 모든 수준의 테스트 계층 구조에서 일하고 있습니다. 개발자 관계 책임자 Secure Code Warrior 그는 팀과 직접 협력하여 품질 보안 코드 의 개발을 개선합니다. 앨런은 "친애하는 악테터", "테스터를위한 자바"를 포함하여 네 권의 책의 저자입니다. 앨런은 또한 온라인 교육을 만들었습니다 courses 사람들이 자바와 기술 웹 테스트 및 셀레늄 웹 드라이버를 배울 수 있도록. 앨런은 SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, CompendiumDev.co.uk 자신의 글과 트레이닝 비디오를 게시합니다.

더 알아보세요

Secure Code Warrior는 전체 소프트웨어 개발 라이프사이클에서 코드를 보호하고 사이버 보안을 최우선으로 생각하는 문화를 조성할 수 있도록 조직을 위해 여기 있습니다.AppSec 관리자, 개발자, CISO 또는 보안 관련 누구든 관계없이 조직이 안전하지 않은 코드와 관련된 위험을 줄일 수 있도록 도와드릴 수 있습니다.

데모 예약
공유 대상:
링크드인 브랜드사회적x 로고
작성자
앨런 리처드슨
게시일: Feb 07, 2021

Alan Richardson은 20년 이상의 전문 IT 경험을 보유하고 있으며, 개발자로 일하며 테스터부터 테스트 책임자까지 모든 수준의 테스트 계층 구조에서 일하고 있습니다. 개발자 관계 책임자 Secure Code Warrior 그는 팀과 직접 협력하여 품질 보안 코드 의 개발을 개선합니다. 앨런은 "친애하는 악테터", "테스터를위한 자바"를 포함하여 네 권의 책의 저자입니다. 앨런은 또한 온라인 교육을 만들었습니다 courses 사람들이 자바와 기술 웹 테스트 및 셀레늄 웹 드라이버를 배울 수 있도록. 앨런은 SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, CompendiumDev.co.uk 자신의 글과 트레이닝 비디오를 게시합니다.

공유 대상:
링크드인 브랜드사회적x 로고

자바 문제 - 비트별 연산자와 부울 연산자

“Java Gotcha” - 실수로 구현하기 쉬운 일반적인 실수 패턴입니다.

자바에서 실수로 빠질 수 있는 아주 간단한 문제 중 하나는 바로 부울 비교 연산자 대신 비트별 연산자를 사용하는 것입니다.

예를 들어, 정말로 “&&”를 쓰려고 했을 때 단순한 잘못 입력으로 인해 “&”를 쓸 수 있습니다.

코드를 검토할 때 흔히 배우는 휴리스틱은 다음과 같습니다.

“&” 또는 “|”를 조건문에 사용하는 것은 의도된 것이 아닐 수 있습니다.

이 블로그 게시물에서는 휴리스틱을 살펴보고 이 코딩 문제를 식별하고 해결할 수 있는 방법을 알아보겠습니다.


무슨 문제야? 비트별 연산은 부울 값에서 잘 작동합니다.


부울 값과 함께 비트 연산자를 사용하는 것은 완벽하게 유효하므로 Java는 구문 오류를 보고하지 않습니다.

비트 연산자 OR(|)과 AND(&) 모두에 대한 진리표를 탐색하기 위해 JUnit 테스트를 구성하면 비트 연산자의 출력이 진리표와 일치하는 것을 확인할 수 있습니다. 이러한 점을 고려하면 비트 연산자를 사용하는 것이 문제가 되지 않는다고 생각할 수도 있습니다.

AND 트루스 테이블

a가 있는 세 개의 열, b가 있는 열, 마지막 열(a^b)이 있는 열


@Test
무효 비트 연산자 및 진실 테이블 () {
어설션. 같음 어설션 (참, 참, 참);
어설션. 같음 어설션 (거짓, 참, 거짓);
어설션. 같음 어설션 (거짓, 거짓, 참);
어설션. 같음 어설션 (거짓, 거짓, 거짓);
}


테스트를 통과했습니다. 이것은 완벽하게 유효한 Java입니다.


OR 진리값 표


a가 있는 세 개의 열, b가 있는 열, 마지막 열(a v b)이 있는 열


@Test
무효 비트 연산자 또는 진실 테이블 () {
어설션. 어설션 같음 (참, 참 | 참);
어설션. 어설션 같음 (참, 참 | 거짓);
어설션. 같음 어설션 (참, 거짓 | 참);
어설션. 같음 어설션 (거짓, 거짓 | 거짓);
}


이 테스트도 통과했는데 왜 “&&'와 “||'를 선호할까요?


진리표 이미지는 다음을 사용하여 생성되었습니다. 진실 테이블 도구 ...에서 web.standfor.edu.


문제: 단락 작동


진짜 문제는 비트 연산자(&, |)와 부울(&&, ||) 연산자 간의 동작 차이입니다.

부울 연산자는 단락 연산자이며 필요한 만큼만 평가합니다.

예:

만약 (격언!= null 및 인수. 길이 () > 23) {
시스템.out.printLN (args);
}


위 코드에서는 비트 연산자가 사용되었으므로 두 부울 조건이 모두 평가됩니다.

  • 인수!= 제로
  • 인수. 길이 () > 23

이렇게 하면 인수가 null인 경우 내 코드가 NullPointerException으로 열립니다. 두 부울 조건을 모두 평가해야 하기 때문에 인수가 null인 경우에도 항상 args.length 검사를 수행하기 때문입니다.


부울 연산자 단락 회로 평가


&&를 사용하는 경우 예:

만약 (격언!= null 및 인수. 길이 () > 23) {
시스템.out.printLN (args);
}


우리가 그 인수를 알게 되자마자!= null이 false로 평가되면 조건 표현식 평가가 중지됩니다.

오른쪽을 평가할 필요는 없습니다.

오른쪽 조건의 결과가 무엇이든, Boolean 표현식의 최종 값은 false가 됩니다.


하지만 프로덕션 코드에서는 이런 일이 절대 일어나지 않을 것입니다.


이는 매우 쉽게 범할 수 있는 실수이며 정적 분석 도구에서 항상 알아차릴 수 있는 것은 아닙니다.

다음 Google Dork를 사용하여 이 패턴의 공개 사례를 찾을 수 있는지 확인했습니다.

파일 형식: “! 인 경우 자바=null &”
이 검색은 Android의 일부 코드를 루트 윈도우 컨테이너에 가져왔습니다.
ISDocument = 인텐트!= null & Intent.isDocument ()


입력문에서 비트 연산자를 사용하여 값을 마스킹하는 경우가 많기 때문에 코드 검토를 통과할 수 있는 코드 유형입니다. 하지만 이 경우 결과는 위의 if 문 예제와 같습니다. 인텐트가 항상 null인 경우 NullPointerException이 발생합니다.

우리는 종종 방어적인 방식으로 코딩하고 중복 코드를 작성하기 때문에 이 구문을 사용하지 않는 경우가 많습니다. 확인해 보세요! = null은 대부분의 사용 사례에서 중복될 수 있습니다.

이것은 프로그래머가 프로덕션 코드에서 만든 오류입니다.

검색 결과가 얼마나 최신인지는 모르겠지만 검색을 실행했을 때 Google, Amazon, Apache... 그리고 제 코드가 포함된 결과가 나왔습니다.

최근 풀 리퀘스트 내 오픈 소스 프로젝트 중 하나에서 정확히 이 오류를 해결해야 했습니다.

만약 (입력!=null 및 type.trim (). 길이 () >0) {
미디어 유형 정의 목록을 승인합니다. 추가 (type.trim ());
}


이것을 찾는 방법


몇 개의 정적 분석기에서 샘플 코드를 확인했을 때 아무도 이 숨겨진 자체 파괴 코드를 발견하지 못했습니다.

Secure Code Warrior 팀으로서 우리는 이 문제를 해결할 수 있는 아주 간단한 센세이 레시피를 만들고 검토했습니다.

비트 연산자는 완벽하게 유효하며 대입에 자주 사용되기 때문에 if 문 사용 사례와 비트 연산자 &를 사용하여 문제가 되는 코드를 찾는 데 중점을 두었습니다.

검색:
표현식:
다음 중 하나:
- 입력:
조건: {}
값:
대소문자 구분: 거짓
일치: “.* &.*”


이것은 정규 표현식을 사용하여 조건 표현식으로 사용될 때 "& "와 일치시킵니다 (예: if 문에서).

이 문제를 해결하기 위해 우리는 다시 정규 표현식을 사용했습니다. 이번에는 QuickFix의 sed 함수를 사용하여 표현식의 &를 &&로 전역적으로 대체했습니다.

사용 가능한 수정 사항:
- 이름: “비트 AND 연산자를 논리 AND 연산자로 바꾸기”
조치:
- 다시 작성:
받는 사람: “{{#sed}} s/&/&/g, {{{.}}} {{/sed}}”


엔드 노트

여기서는 비트 연산자의 가장 일반적인 오용, 즉 부울 연산자가 실제로 의도된 경우에 대한 내용입니다.

예를 들어 대입 예제와 같은 다른 상황이 발생할 수 있지만 레시피를 작성할 때 위양성 식별을 피해야 합니다. 그렇지 않으면 레시피가 무시되거나 꺼집니다. 우리는 가장 자주 발생하는 상황에 맞는 레시피를 만듭니다. Sensei가 발전함에 따라 더 많은 일치 조건을 포괄하기 위해 검색 기능에 특정 기능을 추가할 예정입니다.

현재 형태로 보면 이 레시피는 많은 실제 사용 사례를 식별할 수 있습니다. 가장 중요한 것은, 내 프로젝트에서 보고된 내용입니다.

참고: 찰리 에릭센, 마티유 칼리, 로빈 클레어하우트, 브라이슨 애크스, 네이선 데스멧, 다우니 로버스쇼텐 등 코드 워리어들이 이 예제와 레시피 리뷰에 기여했습니다. 도와주셔서 감사합니다.


---


IntelliJ 내에서 “환경설정\ 플러그인” (Mac) 또는 “설정\ 플러그인” (Windows) 을 사용하여 Sensei를 설치한 다음 “센세이 보안 코드”를 검색하기만 하면 됩니다.

Secure Code Warrior 계정의 `sensei` 저장소에는 이러한 블로그 게시물(이 게시물 포함)에 대한 많은 소스 코드와 레시피가 있습니다.

https://github.com/securecodewarrior/sensei-blog-examples

선생님에 대해 더 알아보기


리소스 보기
리소스 보기

보고서를 다운로드하려면 아래 양식을 작성하세요.

귀하의 동의를 구하여 당사 제품 및/또는 관련 보안 코딩 주제에 대한 정보를 보내드릴 수 있도록 하겠습니다. 당사는 항상 귀하의 개인정보를 최대한의 주의를 기울여 취급하며, 마케팅 목적으로 다른 회사에 절대 판매하지 않습니다.

제출
scw 성공 아이콘
scw 오류 아이콘
양식을 제출하려면 'Analytics' 쿠키를 활성화하십시오. 완료되면 언제든지 다시 비활성화할 수 있습니다.

자바 문제 - 비트별 연산자와 부울 연산자

“Java Gotcha” - 실수로 구현하기 쉬운 일반적인 실수 패턴입니다.

자바에서 실수로 빠질 수 있는 아주 간단한 문제 중 하나는 바로 부울 비교 연산자 대신 비트별 연산자를 사용하는 것입니다.

예를 들어, 정말로 “&&”를 쓰려고 했을 때 단순한 잘못 입력으로 인해 “&”를 쓸 수 있습니다.

코드를 검토할 때 흔히 배우는 휴리스틱은 다음과 같습니다.

“&” 또는 “|”를 조건문에 사용하는 것은 의도된 것이 아닐 수 있습니다.

이 블로그 게시물에서는 휴리스틱을 살펴보고 이 코딩 문제를 식별하고 해결할 수 있는 방법을 알아보겠습니다.


무슨 문제야? 비트별 연산은 부울 값에서 잘 작동합니다.


부울 값과 함께 비트 연산자를 사용하는 것은 완벽하게 유효하므로 Java는 구문 오류를 보고하지 않습니다.

비트 연산자 OR(|)과 AND(&) 모두에 대한 진리표를 탐색하기 위해 JUnit 테스트를 구성하면 비트 연산자의 출력이 진리표와 일치하는 것을 확인할 수 있습니다. 이러한 점을 고려하면 비트 연산자를 사용하는 것이 문제가 되지 않는다고 생각할 수도 있습니다.

AND 트루스 테이블

a가 있는 세 개의 열, b가 있는 열, 마지막 열(a^b)이 있는 열


@Test
무효 비트 연산자 및 진실 테이블 () {
어설션. 같음 어설션 (참, 참, 참);
어설션. 같음 어설션 (거짓, 참, 거짓);
어설션. 같음 어설션 (거짓, 거짓, 참);
어설션. 같음 어설션 (거짓, 거짓, 거짓);
}


테스트를 통과했습니다. 이것은 완벽하게 유효한 Java입니다.


OR 진리값 표


a가 있는 세 개의 열, b가 있는 열, 마지막 열(a v b)이 있는 열


@Test
무효 비트 연산자 또는 진실 테이블 () {
어설션. 어설션 같음 (참, 참 | 참);
어설션. 어설션 같음 (참, 참 | 거짓);
어설션. 같음 어설션 (참, 거짓 | 참);
어설션. 같음 어설션 (거짓, 거짓 | 거짓);
}


이 테스트도 통과했는데 왜 “&&'와 “||'를 선호할까요?


진리표 이미지는 다음을 사용하여 생성되었습니다. 진실 테이블 도구 ...에서 web.standfor.edu.


문제: 단락 작동


진짜 문제는 비트 연산자(&, |)와 부울(&&, ||) 연산자 간의 동작 차이입니다.

부울 연산자는 단락 연산자이며 필요한 만큼만 평가합니다.

예:

만약 (격언!= null 및 인수. 길이 () > 23) {
시스템.out.printLN (args);
}


위 코드에서는 비트 연산자가 사용되었으므로 두 부울 조건이 모두 평가됩니다.

  • 인수!= 제로
  • 인수. 길이 () > 23

이렇게 하면 인수가 null인 경우 내 코드가 NullPointerException으로 열립니다. 두 부울 조건을 모두 평가해야 하기 때문에 인수가 null인 경우에도 항상 args.length 검사를 수행하기 때문입니다.


부울 연산자 단락 회로 평가


&&를 사용하는 경우 예:

만약 (격언!= null 및 인수. 길이 () > 23) {
시스템.out.printLN (args);
}


우리가 그 인수를 알게 되자마자!= null이 false로 평가되면 조건 표현식 평가가 중지됩니다.

오른쪽을 평가할 필요는 없습니다.

오른쪽 조건의 결과가 무엇이든, Boolean 표현식의 최종 값은 false가 됩니다.


하지만 프로덕션 코드에서는 이런 일이 절대 일어나지 않을 것입니다.


이는 매우 쉽게 범할 수 있는 실수이며 정적 분석 도구에서 항상 알아차릴 수 있는 것은 아닙니다.

다음 Google Dork를 사용하여 이 패턴의 공개 사례를 찾을 수 있는지 확인했습니다.

파일 형식: “! 인 경우 자바=null &”
이 검색은 Android의 일부 코드를 루트 윈도우 컨테이너에 가져왔습니다.
ISDocument = 인텐트!= null & Intent.isDocument ()


입력문에서 비트 연산자를 사용하여 값을 마스킹하는 경우가 많기 때문에 코드 검토를 통과할 수 있는 코드 유형입니다. 하지만 이 경우 결과는 위의 if 문 예제와 같습니다. 인텐트가 항상 null인 경우 NullPointerException이 발생합니다.

우리는 종종 방어적인 방식으로 코딩하고 중복 코드를 작성하기 때문에 이 구문을 사용하지 않는 경우가 많습니다. 확인해 보세요! = null은 대부분의 사용 사례에서 중복될 수 있습니다.

이것은 프로그래머가 프로덕션 코드에서 만든 오류입니다.

검색 결과가 얼마나 최신인지는 모르겠지만 검색을 실행했을 때 Google, Amazon, Apache... 그리고 제 코드가 포함된 결과가 나왔습니다.

최근 풀 리퀘스트 내 오픈 소스 프로젝트 중 하나에서 정확히 이 오류를 해결해야 했습니다.

만약 (입력!=null 및 type.trim (). 길이 () >0) {
미디어 유형 정의 목록을 승인합니다. 추가 (type.trim ());
}


이것을 찾는 방법


몇 개의 정적 분석기에서 샘플 코드를 확인했을 때 아무도 이 숨겨진 자체 파괴 코드를 발견하지 못했습니다.

Secure Code Warrior 팀으로서 우리는 이 문제를 해결할 수 있는 아주 간단한 센세이 레시피를 만들고 검토했습니다.

비트 연산자는 완벽하게 유효하며 대입에 자주 사용되기 때문에 if 문 사용 사례와 비트 연산자 &를 사용하여 문제가 되는 코드를 찾는 데 중점을 두었습니다.

검색:
표현식:
다음 중 하나:
- 입력:
조건: {}
값:
대소문자 구분: 거짓
일치: “.* &.*”


이것은 정규 표현식을 사용하여 조건 표현식으로 사용될 때 "& "와 일치시킵니다 (예: if 문에서).

이 문제를 해결하기 위해 우리는 다시 정규 표현식을 사용했습니다. 이번에는 QuickFix의 sed 함수를 사용하여 표현식의 &를 &&로 전역적으로 대체했습니다.

사용 가능한 수정 사항:
- 이름: “비트 AND 연산자를 논리 AND 연산자로 바꾸기”
조치:
- 다시 작성:
받는 사람: “{{#sed}} s/&/&/g, {{{.}}} {{/sed}}”


엔드 노트

여기서는 비트 연산자의 가장 일반적인 오용, 즉 부울 연산자가 실제로 의도된 경우에 대한 내용입니다.

예를 들어 대입 예제와 같은 다른 상황이 발생할 수 있지만 레시피를 작성할 때 위양성 식별을 피해야 합니다. 그렇지 않으면 레시피가 무시되거나 꺼집니다. 우리는 가장 자주 발생하는 상황에 맞는 레시피를 만듭니다. Sensei가 발전함에 따라 더 많은 일치 조건을 포괄하기 위해 검색 기능에 특정 기능을 추가할 예정입니다.

현재 형태로 보면 이 레시피는 많은 실제 사용 사례를 식별할 수 있습니다. 가장 중요한 것은, 내 프로젝트에서 보고된 내용입니다.

참고: 찰리 에릭센, 마티유 칼리, 로빈 클레어하우트, 브라이슨 애크스, 네이선 데스멧, 다우니 로버스쇼텐 등 코드 워리어들이 이 예제와 레시피 리뷰에 기여했습니다. 도와주셔서 감사합니다.


---


IntelliJ 내에서 “환경설정\ 플러그인” (Mac) 또는 “설정\ 플러그인” (Windows) 을 사용하여 Sensei를 설치한 다음 “센세이 보안 코드”를 검색하기만 하면 됩니다.

Secure Code Warrior 계정의 `sensei` 저장소에는 이러한 블로그 게시물(이 게시물 포함)에 대한 많은 소스 코드와 레시피가 있습니다.

https://github.com/securecodewarrior/sensei-blog-examples

선생님에 대해 더 알아보기


웨비나 보기
시작하기
더 알아보세요

아래 링크를 클릭하고 이 리소스의 PDF를 다운로드하십시오.

Secure Code Warrior는 전체 소프트웨어 개발 라이프사이클에서 코드를 보호하고 사이버 보안을 최우선으로 생각하는 문화를 조성할 수 있도록 조직을 위해 여기 있습니다.AppSec 관리자, 개발자, CISO 또는 보안 관련 누구든 관계없이 조직이 안전하지 않은 코드와 관련된 위험을 줄일 수 있도록 도와드릴 수 있습니다.

보고서 보기데모 예약
리소스 보기
공유 대상:
링크드인 브랜드사회적x 로고
더 많은 것에 관심이 있으신가요?

공유 대상:
링크드인 브랜드사회적x 로고
작성자
앨런 리처드슨
게시일: Feb 07, 2021

Alan Richardson은 20년 이상의 전문 IT 경험을 보유하고 있으며, 개발자로 일하며 테스터부터 테스트 책임자까지 모든 수준의 테스트 계층 구조에서 일하고 있습니다. 개발자 관계 책임자 Secure Code Warrior 그는 팀과 직접 협력하여 품질 보안 코드 의 개발을 개선합니다. 앨런은 "친애하는 악테터", "테스터를위한 자바"를 포함하여 네 권의 책의 저자입니다. 앨런은 또한 온라인 교육을 만들었습니다 courses 사람들이 자바와 기술 웹 테스트 및 셀레늄 웹 드라이버를 배울 수 있도록. 앨런은 SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, CompendiumDev.co.uk 자신의 글과 트레이닝 비디오를 게시합니다.

공유 대상:
링크드인 브랜드사회적x 로고

자바 문제 - 비트별 연산자와 부울 연산자

“Java Gotcha” - 실수로 구현하기 쉬운 일반적인 실수 패턴입니다.

자바에서 실수로 빠질 수 있는 아주 간단한 문제 중 하나는 바로 부울 비교 연산자 대신 비트별 연산자를 사용하는 것입니다.

예를 들어, 정말로 “&&”를 쓰려고 했을 때 단순한 잘못 입력으로 인해 “&”를 쓸 수 있습니다.

코드를 검토할 때 흔히 배우는 휴리스틱은 다음과 같습니다.

“&” 또는 “|”를 조건문에 사용하는 것은 의도된 것이 아닐 수 있습니다.

이 블로그 게시물에서는 휴리스틱을 살펴보고 이 코딩 문제를 식별하고 해결할 수 있는 방법을 알아보겠습니다.


무슨 문제야? 비트별 연산은 부울 값에서 잘 작동합니다.


부울 값과 함께 비트 연산자를 사용하는 것은 완벽하게 유효하므로 Java는 구문 오류를 보고하지 않습니다.

비트 연산자 OR(|)과 AND(&) 모두에 대한 진리표를 탐색하기 위해 JUnit 테스트를 구성하면 비트 연산자의 출력이 진리표와 일치하는 것을 확인할 수 있습니다. 이러한 점을 고려하면 비트 연산자를 사용하는 것이 문제가 되지 않는다고 생각할 수도 있습니다.

AND 트루스 테이블

a가 있는 세 개의 열, b가 있는 열, 마지막 열(a^b)이 있는 열


@Test
무효 비트 연산자 및 진실 테이블 () {
어설션. 같음 어설션 (참, 참, 참);
어설션. 같음 어설션 (거짓, 참, 거짓);
어설션. 같음 어설션 (거짓, 거짓, 참);
어설션. 같음 어설션 (거짓, 거짓, 거짓);
}


테스트를 통과했습니다. 이것은 완벽하게 유효한 Java입니다.


OR 진리값 표


a가 있는 세 개의 열, b가 있는 열, 마지막 열(a v b)이 있는 열


@Test
무효 비트 연산자 또는 진실 테이블 () {
어설션. 어설션 같음 (참, 참 | 참);
어설션. 어설션 같음 (참, 참 | 거짓);
어설션. 같음 어설션 (참, 거짓 | 참);
어설션. 같음 어설션 (거짓, 거짓 | 거짓);
}


이 테스트도 통과했는데 왜 “&&'와 “||'를 선호할까요?


진리표 이미지는 다음을 사용하여 생성되었습니다. 진실 테이블 도구 ...에서 web.standfor.edu.


문제: 단락 작동


진짜 문제는 비트 연산자(&, |)와 부울(&&, ||) 연산자 간의 동작 차이입니다.

부울 연산자는 단락 연산자이며 필요한 만큼만 평가합니다.

예:

만약 (격언!= null 및 인수. 길이 () > 23) {
시스템.out.printLN (args);
}


위 코드에서는 비트 연산자가 사용되었으므로 두 부울 조건이 모두 평가됩니다.

  • 인수!= 제로
  • 인수. 길이 () > 23

이렇게 하면 인수가 null인 경우 내 코드가 NullPointerException으로 열립니다. 두 부울 조건을 모두 평가해야 하기 때문에 인수가 null인 경우에도 항상 args.length 검사를 수행하기 때문입니다.


부울 연산자 단락 회로 평가


&&를 사용하는 경우 예:

만약 (격언!= null 및 인수. 길이 () > 23) {
시스템.out.printLN (args);
}


우리가 그 인수를 알게 되자마자!= null이 false로 평가되면 조건 표현식 평가가 중지됩니다.

오른쪽을 평가할 필요는 없습니다.

오른쪽 조건의 결과가 무엇이든, Boolean 표현식의 최종 값은 false가 됩니다.


하지만 프로덕션 코드에서는 이런 일이 절대 일어나지 않을 것입니다.


이는 매우 쉽게 범할 수 있는 실수이며 정적 분석 도구에서 항상 알아차릴 수 있는 것은 아닙니다.

다음 Google Dork를 사용하여 이 패턴의 공개 사례를 찾을 수 있는지 확인했습니다.

파일 형식: “! 인 경우 자바=null &”
이 검색은 Android의 일부 코드를 루트 윈도우 컨테이너에 가져왔습니다.
ISDocument = 인텐트!= null & Intent.isDocument ()


입력문에서 비트 연산자를 사용하여 값을 마스킹하는 경우가 많기 때문에 코드 검토를 통과할 수 있는 코드 유형입니다. 하지만 이 경우 결과는 위의 if 문 예제와 같습니다. 인텐트가 항상 null인 경우 NullPointerException이 발생합니다.

우리는 종종 방어적인 방식으로 코딩하고 중복 코드를 작성하기 때문에 이 구문을 사용하지 않는 경우가 많습니다. 확인해 보세요! = null은 대부분의 사용 사례에서 중복될 수 있습니다.

이것은 프로그래머가 프로덕션 코드에서 만든 오류입니다.

검색 결과가 얼마나 최신인지는 모르겠지만 검색을 실행했을 때 Google, Amazon, Apache... 그리고 제 코드가 포함된 결과가 나왔습니다.

최근 풀 리퀘스트 내 오픈 소스 프로젝트 중 하나에서 정확히 이 오류를 해결해야 했습니다.

만약 (입력!=null 및 type.trim (). 길이 () >0) {
미디어 유형 정의 목록을 승인합니다. 추가 (type.trim ());
}


이것을 찾는 방법


몇 개의 정적 분석기에서 샘플 코드를 확인했을 때 아무도 이 숨겨진 자체 파괴 코드를 발견하지 못했습니다.

Secure Code Warrior 팀으로서 우리는 이 문제를 해결할 수 있는 아주 간단한 센세이 레시피를 만들고 검토했습니다.

비트 연산자는 완벽하게 유효하며 대입에 자주 사용되기 때문에 if 문 사용 사례와 비트 연산자 &를 사용하여 문제가 되는 코드를 찾는 데 중점을 두었습니다.

검색:
표현식:
다음 중 하나:
- 입력:
조건: {}
값:
대소문자 구분: 거짓
일치: “.* &.*”


이것은 정규 표현식을 사용하여 조건 표현식으로 사용될 때 "& "와 일치시킵니다 (예: if 문에서).

이 문제를 해결하기 위해 우리는 다시 정규 표현식을 사용했습니다. 이번에는 QuickFix의 sed 함수를 사용하여 표현식의 &를 &&로 전역적으로 대체했습니다.

사용 가능한 수정 사항:
- 이름: “비트 AND 연산자를 논리 AND 연산자로 바꾸기”
조치:
- 다시 작성:
받는 사람: “{{#sed}} s/&/&/g, {{{.}}} {{/sed}}”


엔드 노트

여기서는 비트 연산자의 가장 일반적인 오용, 즉 부울 연산자가 실제로 의도된 경우에 대한 내용입니다.

예를 들어 대입 예제와 같은 다른 상황이 발생할 수 있지만 레시피를 작성할 때 위양성 식별을 피해야 합니다. 그렇지 않으면 레시피가 무시되거나 꺼집니다. 우리는 가장 자주 발생하는 상황에 맞는 레시피를 만듭니다. Sensei가 발전함에 따라 더 많은 일치 조건을 포괄하기 위해 검색 기능에 특정 기능을 추가할 예정입니다.

현재 형태로 보면 이 레시피는 많은 실제 사용 사례를 식별할 수 있습니다. 가장 중요한 것은, 내 프로젝트에서 보고된 내용입니다.

참고: 찰리 에릭센, 마티유 칼리, 로빈 클레어하우트, 브라이슨 애크스, 네이선 데스멧, 다우니 로버스쇼텐 등 코드 워리어들이 이 예제와 레시피 리뷰에 기여했습니다. 도와주셔서 감사합니다.


---


IntelliJ 내에서 “환경설정\ 플러그인” (Mac) 또는 “설정\ 플러그인” (Windows) 을 사용하여 Sensei를 설치한 다음 “센세이 보안 코드”를 검색하기만 하면 됩니다.

Secure Code Warrior 계정의 `sensei` 저장소에는 이러한 블로그 게시물(이 게시물 포함)에 대한 많은 소스 코드와 레시피가 있습니다.

https://github.com/securecodewarrior/sensei-blog-examples

선생님에 대해 더 알아보기


목차

PDF 다운로드
리소스 보기
더 많은 것에 관심이 있으신가요?

Alan Richardson은 20년 이상의 전문 IT 경험을 보유하고 있으며, 개발자로 일하며 테스터부터 테스트 책임자까지 모든 수준의 테스트 계층 구조에서 일하고 있습니다. 개발자 관계 책임자 Secure Code Warrior 그는 팀과 직접 협력하여 품질 보안 코드 의 개발을 개선합니다. 앨런은 "친애하는 악테터", "테스터를위한 자바"를 포함하여 네 권의 책의 저자입니다. 앨런은 또한 온라인 교육을 만들었습니다 courses 사람들이 자바와 기술 웹 테스트 및 셀레늄 웹 드라이버를 배울 수 있도록. 앨런은 SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, CompendiumDev.co.uk 자신의 글과 트레이닝 비디오를 게시합니다.

더 알아보세요

Secure Code Warrior는 전체 소프트웨어 개발 라이프사이클에서 코드를 보호하고 사이버 보안을 최우선으로 생각하는 문화를 조성할 수 있도록 조직을 위해 여기 있습니다.AppSec 관리자, 개발자, CISO 또는 보안 관련 누구든 관계없이 조직이 안전하지 않은 코드와 관련된 위험을 줄일 수 있도록 도와드릴 수 있습니다.

데모 예약다운로드
공유 대상:
링크드인 브랜드사회적x 로고
리소스 허브

시작하는 데 도움이 되는 리소스

더 많은 게시물
리소스 허브

시작하는 데 도움이 되는 리소스

더 많은 게시물