내 정규식이 치명적인 역 추적에 취약한 지 테스트하는 방법이 있습니까?
이 주제에 대해 많은 질문이 있지만 내 정규식이 취약한 지 아닌지 잘 모르겠습니다. 다음 정규식은 이메일 유효성 검사에 사용하는 것입니다.
/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)
몇 군데에서 *를 사용하고 있기 때문에 그럴 수 있다고 생각합니다.
내 코드에서 문제가 있는지 테스트 할 수 있기를 바랍니다.
Node.js를 사용하고 있으므로 이벤트 루프의 단일 스레드 특성을 고려할 때 서버를 완전히 종료 할 수 있습니다.
답변
좋은 질문. 예, 올바른 입력이 주어지면 취약하고 폭주 정규식이 전체 노드 프로세스를 차단하여 서비스를 사용할 수 없게 만듭니다.
치명적인 역 추적이 발생하기 쉬운 정규식의 기본 예는 다음과 같습니다.
^(\w+)*$
주어진 정규식에서 여러 번 찾을 수있는 패턴.
정규식에 선택적 수량자가 포함되어 있고 입력에 결국 일치 할 수없는 긴 시퀀스가 포함 된 경우 JS 정규식 엔진은 많은 것을 역 추적하고 CPU를 소모해야합니다. 입력이 충분히 길면 광고 무한대 일 수 있습니다. ( 설정에서 시간 제한 값을 조정하여 regex101 에서도이를 사용할 수 있습니다.)
일반적으로
- 괴물을 피하고 ,
- 가능할 때마다 (프런트 엔드에서) HTML5 입력 유효성 검사를 사용합니다.
- 공통 입력에 대해 확립 된 유효성 검사 라이브러리를 사용합니다 (예 : validator.js ).
- safe-regex 및 vuln-regex-detector 와 같은 도구를 사용하여 잠재적으로 치명적인 지수 시간 정규 표현식을 미리 감지하려고 시도하십시오 (이들은 여러분이 염두에 두었던 것을 거의 제공합니다).
- 당신의 물건을 알고 1 , 2 , 3 (I 세 번째 링크는 문제가 최선을 설명 생각한다).
node.js에서 치명적인 역 추적을 완화하기위한보다 과감한 접근 방식은 자식 프로세스 또는 vm컨텍스트 에서 정규식 작업을 래핑 하고 의미있는 시간 제한을 설정하는 것입니다. (완벽한 세상에서 JavaScript의 RegExp
생성자는 언젠가는 타임 아웃 매개 변수를 가질 것입니다.)
자식 프로세스를 사용하는 방법은 여기 에 설명되어 있습니다 .
VM 컨텍스트 (샌드 박싱) 접근 방식은 여기 에 설명되어 있습니다 .
const Joi = require('@hapi/joi');
function isEmail(emailAsStr) {
const schema = Joi.object({ email: Joi.string().email() });
const result = schema.validate({ email: emailAsStr });
const validated = result.error ? false : true;
if (validated) return true;
return [false, result.error.details[0].message];
}
여기에 또 다른 방법이 있습니다. 라이브러리를 사용하세요! :) 일반적인 치명적인 역 추적 정규식에 대해 테스트했습니다. 내 원래 질문에 대한 대답은 npm lib를 사용하는 것입니다. safe-regex,하지만 정규식없이이 문제를 해결하는 방법에 대한 또 다른 예를 공유하겠다고 생각했습니다.