자바 보안 인 코딩 안내: 입력 검사
자바 프로그램의 안전 을 위해 서 는 모든 외부 사용자 의 입력 이 악의 적 인 공격 의도 가 있 을 수 있다 고 생각 합 니 다. 모든 사용자 의 입력 을 어느 정도 검증 해 야 합 니 다.
본 고 는 모 두 를 데 리 고 사용자 가 입력 하고 검증 하 는 일부 장면 을 연구 할 것 이다.같이 보 자.
문자열 표준화 후 검사 하기
보통 문자열 검 사 를 할 때 특수 문 자 를 걸 러 내 고 걸 러 낸 후에 문자열 검 사 를 해 야 합 니 다.
자바 에서 문 자 는 유 니 코드 를 기반 으로 인 코딩 된 것 을 알 고 있 습 니 다.그러나 유 니 코드 에 서 는 같은 문자 에 다른 표현 형식 이 있 을 수 있 습 니 다.그래서 우 리 는 문 자 를 표준화 해 야 한다.
자바 에는 문자 표준화 문 제 를 처리 하 는 전문 적 인 클래스 Normalizer 가 있 습 니 다.
우 리 는 다음 예 를 보 자.
public void testNormalizer(){
System.out.println(Normalizer.normalize("\u00C1", Normalizer.Form.NFKC));
System.out.println(Normalizer.normalize("\u0041\u0301", Normalizer.Form.NFKC));
}
출력 결과:
Á
Á
둘 의 유 니 코드 는 다 르 지만 최종 적 으로 나타 내 는 문 자 는 같다 는 것 을 알 수 있다.그래서 우 리 는 문자 검증 을 할 때 반드시 normalize 처 리 를 해 야 한다.
아래 의 예 를 고려 하 다.
public void falseNormalize(){
String s = "\uFE64" + "script" + "\uFE65";
Pattern pattern = Pattern.compile("[<>]"); //
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
throw new IllegalStateException();
}
s = Normalizer.normalize(s, Normalizer.Form.NFKC);
}
그 중에서 \ uFE 64 는 입력 한 문자열 에 괄호 가 포함 되 어 있 는 지 여 부 를 판단 하 는 것 을 의미 하지만 유 니 코드 문자 가 직접 들 어 오기 때문에 직접 copile 은 감지 되 지 않 습 니 다.
우 리 는 코드 에 대해 아래 의 변경 을 진행 해 야 한다.
public void trueNormalize(){
String s = "\uFE64" + "script" + "\uFE65";
s = Normalizer.normalize(s, Normalizer.Form.NFKC);
Pattern pattern = Pattern.compile("[<>]"); //
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
throw new IllegalStateException();
}
}
먼저 normalize 작업 을 한 다음 에 문자 검증 을 합 니 다.
신뢰 할 수 없 는 문자열 의 포맷 에 주의 하 십시오.
우 리 는 문자열 을 포맷 하기 위해 포맷 을 자주 사용 합 니 다. 포맷 할 때 문자열 에 사용자 가 입력 한 정보 가 들 어 있 으 면 주의해 야 합 니 다.
아래 의 예 를 보십시오.
public void wrongFormat(){
Calendar c = new GregorianCalendar(2020, GregorianCalendar.JULY, 27);
String input=" %1$tm";
System.out.format(input + " , %1$terd ", c);
}
대충 봐 도 괜 찮 지만, 우리 input 에는 포맷 정보 가 포함 되 어 있 습 니 다. 마지막 출력 결과:
07 , 27rd
변 형 된 것 은 우리 가 시스템 내부 의 정 보 를 얻 었 기 때문에 어떤 상황 에서 시스템 의 내부 논 리 를 폭로 할 수 있다.
위의 예 에서 우 리 는 input 도 하나의 매개 변수 로 해 야 한다. 다음 과 같다.
public void rightFormat(){
Calendar c = new GregorianCalendar(2020, GregorianCalendar.JULY, 27);
String input=" %1$tm";
System.out.format("%s , %terd ",input, c);
}
출력 결과:
%1$tm , 27rd
Runtime. exec () 사용 조심
Runtime. exec () 가 시스템 명령 을 호출 하 는 데 사용 되 는 것 을 알 고 있 습 니 다. 악의 적 인 사용자 가 "rm - rf /" 를 호출 하면 모든 것 이 망 합 니 다.
따라서 저 희 는 Runtime. exec () 를 호출 할 때 사용자 의 입력 을 조심해 야 합 니 다.
다음 의 예 를 보십시오.
public void wrongExec() throws IOException {
String dir = System.getProperty("dir");
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(new String[] {"sh", "-c", "ls " + dir});
}
위의 예 에서, 우 리 는 시스템 속성 에서 dir 를 읽 은 다음, 시스템 의 ls 명령 을 실행 하여 dir 의 내용 을 보 았 다.
만약 악성 사용자 가 dir 에 값 을 부여 한다 면:
/usr & rm -rf /
그러면 시스템 이 실제로 실행 하 는 명령 은:
sh -c 'ls /usr & rm -rf /'
악의 적 으로 삭제 된다.
위의 문 제 를 해결 하 는 데 도 몇 가지 방법 이 있 습 니 다. 첫 번 째 방법 은 입력 에 대해 검 사 를 하 는 것 입 니 다. 예 를 들 어 우 리 는 dir 에 특정한 문자 만 포함 하 는 것 입 니 다.
public void correctExec1() throws IOException {
String dir = System.getProperty("dir");
if (!Pattern.matches("[0-9A-Za-z@.]+", dir)) {
// Handle error
}
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(new String[] {"sh", "-c", "ls " + dir});
}
두 번 째 방법 은 switch 문 구 를 사용 하여 특정한 입력 을 제한 하 는 것 이다.
public void correctExec2(){
String dir = System.getProperty("dir");
switch (dir){
case "/usr":
System.out.println("/usr");
break;
case "/local":
System.out.println("/local");
break;
default:
break;
}
}
또 하 나 는 Runtime. exec () 방법 을 사용 하지 않 고 자바 자체 가 져 오 는 방법 이다.
정규 표현 식 의 일치
정규 표현 식 을 구축 하 는 과정 에서 사용자 정의 입력 을 사용 하면 같은 것 도 입력 검 사 를 해 야 합 니 다.
다음 정규 표현 식 을 고려 합 니 다:
(.*? +public\[\d+\] +.*.*)
위의 표현 식 은 public [1234] 와 같은 로그 정보 에서 사용자 의 입력 을 검색 하려 는 것 입 니 다.
그러나 사용 자 는 실제로 아래 의 정 보 를 입력 할 수 있다.
.*)|(.*
최종 적 으로 정규 표현 식 이 아래 모양 으로 변 합 니 다:
(.*? +public\[\d+\] +.*.*)|(.*.*)
모든 로그 정보 와 일치 합 니 다.
해결 방법 도 두 가지 가 있 는데 하 나 는 화이트 리스트 를 사용 하여 사용자 의 입력 을 판단 하 는 것 이다.하 나 는 Pattern. quote () 를 사용 하여 악성 문 자 를 바 꾸 는 것 입 니 다.
본문 코드:
learn-java-base-9-to-20/tree/master/security
본문 은 이미 수록 되 었 다.http://www.flydean.com/java-security-code-line-input/
가장 통속 적 인 해석, 가장 깊 은 건어물, 가장 간결 한 튜 토리 얼, 당신 이 모 르 는 작은 기술 들 이 당신 을 기다 리 고 있 습 니 다!
나의 공식 번호 에 관심 을 가 져 주 십시오. "프로그램 그런 일 들", 기술 을 알 고 당신 을 더 잘 알 고 있 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.