수동적 외부 스캔입니다. 모든 진단 결과에는 스캐너가 수집한 원본 관찰 기록과 직접 실행해 재현할 수 있는 명령어가 포함되어 있습니다. 모델이 작성한 내용은 없습니다.
14 검사 그룹:
DNS를 확인하고 CAA를 검사하는 중 · SPF 및 DMARC 확인 중 · TLS 인증서 및 프로토콜 버전 검사 중 · HTTP에서 HTTPS로의 리디렉션 테스트 중 · 응답의 보안 헤더 읽는 중 · 쿠키 속성 확인 중 · CORS 정책 검사 중 · 버전 배너 검색 중 · 허용된 HTTP 메서드 확인 중 · 홈페이지에서 혼합 콘텐츠 및 안전하지 않은 폼 스캔 중 · 노출된 구성 및 버전 관리 파일 검색 중 · 디렉터리 목록 노출 확인 중 · robots.txt 및 security.txt 읽는 중 · 노출된 서비스 포트 확인 중
시작 중…
0%
정보 웹사이트 보안 스캔
많은 스캐너가 알파벳 등급과 무서운 단어 목록을 건넵니다. 이 도구도 등급을 매기지만, 깎는 점수 하나하나가 실제로 받은 응답과 같은 응답을 직접 얻을 수 있는 한 줄 명령을 보여 주는 발견 사항에 연결되어 있습니다. 그래서 발견 사항은 믿어야 하는 것이 아니라 확인할 수 있는 것입니다.
기능
DNS와 CAA, SPF와 DMARC, TLS 인증서와 TLS 1.0/1.1, HTTPS 리디렉션, 보안 헤더, 쿠키 속성, CORS, 버전 배너, HTTP 메서드, 혼합 콘텐츠, 민감한 경로 23개, 디렉터리 목록, robots.txt, security.txt, 서비스 포트 12개를 점검합니다.
모든 발견 사항에는 원시 관찰 결과와 이를 재현할 수 있는 셸 명령어가 포함됩니다.
실행할 수 없었던 검사는 "확인되지 않음"으로 보고됩니다 - 조용히 통과로 처리되는 일은 없습니다.
보고서는 Markdown 또는 JSON으로 다운로드됩니다.
작동 방식
1책임지고 있는 도메인을 입력하세요.
2스캔은 수동적인 탐색을 실행합니다 - 일반적인 요청이며, 악용은 없습니다.
3각 발견 사항을 증거와 함께 읽고, 중요한 것을 검증하세요.
어떤 발견 사항도 지어내지 않습니다
스캐너에는 언어 모델이 전혀 없습니다. 심각도, 영향, 해결 방법은 점검마다 고정되어 있고, 모든 발견 사항은 실제 관측에서 만들어집니다. 화면의 보고서와 Markdown, JSON 다운로드는 같은 발견 사항으로 만들어지며 어디에도 모델이 관여하지 않습니다.
등급 계산 방법
점수는 100에서 시작해 치명 발견 사항마다 34점, 높음 13점, 중간 5점, 낮음 1.5점이 깎이며, 심각도별 합계에는 상한이 있습니다(높음 45, 중간 22, 낮음 9). 정보성 결과와 통과 결과는 감점되지 않습니다. 90 이상은 A, 75 이상 B, 60 이상 C, 40 이상 D, 그 아래는 F입니다. 노출된 .env 파일 하나나 접근 가능한 데이터베이스 포트 하나만으로도 문제없던 사이트가 100에서 66, 즉 C로 떨어지고, 이런 발견 사항이 두 개면 32, 즉 F가 됩니다.
오탐을 피하는 방법
/.git/HEAD나 /backup.sql 같은 경로를 확인하기 전에 스캐너는 존재할 수 없는 임의 주소를 요청하고 사이트의 응답을 기록합니다. 경로가 HTTP 200을 반환하고, 이 찾을 수 없음 기준과 다르며, 해당 파일 고유의 서명과 일치할 때만 노출로 보고합니다. 그래서 모든 URL에 홈페이지로 응답하는 사이트가 치명 발견 사항으로 뒤덮이지 않습니다.
깨끗한 보고서가 인증서는 아닙니다
이것들은 실행 중인 사이트에 대한 수동적 검사입니다. 애플리케이션 로직, 인증, 접근 제어, 또는 로그인 뒤에 있는 어떤 것도 다루지 않습니다 - 실제 침해가 보통 시작되는 곳입니다. 완료할 수 없었던 검사는 바로 이런 이유로 확인되지 않음으로 표시됩니다: 실패한 연결에서 나온 통과는 거짓된 안도감이며, 발견 사항이 없는 스캔은 아무것도 발견되지 않았다는 뜻일 뿐, 거기에 아무것도 없다는 뜻은 아닙니다.
자신의 것만 스캔하세요
소유하고 있거나 테스트할 서면 허가를 받은 도메인만 스캔하세요. 이 도구는 비공개 또는 내부 주소로 확인되는 호스트를 거부하며 IP당 속도 제한이 있지만, 승인에 대한 책임은 여전히 당신에게 있습니다.
질문
이것은 활성 공격인가요?
아닙니다. 일반적인 GET, HEAD, OPTIONS 요청, TLS 핸드셰이크(TLS 1.0과 1.1 시도 포함), Cloudflare DNS-over-HTTPS를 통한 DNS 조회, 12개 포트에 대한 단순 TCP 연결만 합니다. 아무것도 악용하지 않고, 양식을 제출하지 않으며, 아무것도 변경하지 않습니다.
어떤 웹사이트든 스캔할 수 있나요?
소유하고 있거나 테스트할 권한이 있는 웹사이트만 가능합니다. 허가 없이 제3자 인프라를 스캔하는 것은 당신이 있는 지역에서 불법일 수 있습니다.
검사가 왜 "확인되지 않음"이라고 표시되나요?
완료될 수 없었기 때문입니다 - 보통 해당 출처에서 아무 응답이 없었기 때문입니다. 이는 통과로 기록되는 대신 정직하게 보고됩니다.
보고서를 내보낼 수 있나요?
네, Markdown이나 JSON으로 한 시간 동안 가능합니다. 다운로드가 되도록 보고서가 그동안 서버 캐시에 보관되고, 이후 만료됩니다. 어떤 내보내기도 모델을 쓰지 않습니다. 사용 기록에는 도메인이 아니라 발견 사항 수와 등급만 남습니다.
어떤 파일과 포트를 검사하나요?
파일: /.git/HEAD, /.git/config, /.env, /.env.local, /.env.production, /.aws/credentials, /id_rsa, /backup.zip, /backup.sql, /dump.sql, /wp-config.php.bak, /phpinfo.php, /server-status, /actuator/env 등 고정 경로 23개를 확인하며, 응답이 해당 파일 고유의 시그니처와 일치할 때만 보고합니다. /.well-known/security.txt가 게시되어 있으면 유리하게 반영됩니다. 포트: 21 FTP, 23 Telnet, 25 SMTP, 3306 MySQL, 5432 PostgreSQL, 6379 Redis, 27017 MongoDB, 9200 Elasticsearch, 3389 RDP, 5900 VNC, 11211 Memcached, 8080에 단순한 TCP 연결만 시도하며 로그인은 절대 시도하지 않습니다. 외부에서 접근 가능한 데이터베이스 포트(MySQL, PostgreSQL, Redis, MongoDB, Elasticsearch)나 Telnet은 심각으로 평가됩니다.
SPF와 DMARC 검사는 무엇을 지적하나요?
두 레코드 모두 공개 DNS에서 읽으며, 메일을 보내지 않는 사이트도 확인합니다. 이 레코드가 없으면 누구나 내 도메인에서 온 것처럼 메일을 보낼 수 있기 때문입니다. SPF 레코드가 없으면 중간, 인터넷의 모든 서버를 허용하는 +all이 들어간 SPF는 높음입니다. _dmarc에 DMARC 레코드가 없으면 중간, p=none(또는 p= 태그 없음)은 모니터링만 하므로 낮음, p=quarantine 또는 p=reject는 통과입니다. 메일을 전혀 보내지 않는 도메인은 v=spf1 -all을 게시할 수 있습니다.
어떤 보안 헤더를 점검하고, 어떤 값이면 통과하나요?
홈페이지 응답의 헤더 6개입니다. 없을 경우 HSTS와 Content-Security-Policy는 높음, X-Content-Type-Options와 X-Frame-Options는 중간, Referrer-Policy와 Permissions-Policy는 낮음입니다. Strict-Transport-Security는 max-age가 15552000(180일) 이상이어야 하며, 더 짧으면 낮음, max-age=0이면 중간입니다. script-src가 'unsafe-inline'을 허용하거나, 정책이 'unsafe-eval'을 허용하거나, default-src 또는 script-src에 단독 * 와일드카드가 있으면 Content-Security-Policy는 약화됨(중간)으로 표시됩니다. X-Content-Type-Options는 정확히 nosniff여야 합니다. X-Frame-Options는 DENY 또는 SAMEORIGIN이어야 하며, CSP가 frame-ancestors를 설정하면 필요 없습니다. Referrer-Policy는 unsafe-url 또는 no-referrer-when-downgrade일 때만 표시됩니다. Permissions-Policy는 있기만 하면 됩니다. 없거나 약한 헤더마다 직접 확인할 수 있는 curl -sI 명령이 함께 제공됩니다.
쿠키 속성(Secure, HttpOnly, SameSite)은 어떻게 검사하나요?
홈페이지 응답의 모든 Set-Cookie 헤더(최대 12개 쿠키)를 읽고 각각 Secure, HttpOnly, SameSite를 검사합니다. Secure나 HttpOnly가 없으면 중간, SameSite만 없으면 낮음이며, Secure 없는 SameSite=None은 브라우저가 그 쿠키를 거부하므로 따로 알려 줍니다. 세 가지가 모두 있으면 통과입니다. 일반적인 해결책은 Secure; HttpOnly; SameSite=Lax입니다(Django에서는 SESSION_COOKIE_SECURE, SESSION_COOKIE_HTTPONLY, SESSION_COOKIE_SAMESITE). 스캔은 로그인하지 않으므로 로그인한 뒤에만 설정되는 쿠키는 보지 못합니다. 직접 확인하려면 curl -sI https://your-site/ | grep -i set-cookie
CORS 검사는 어떻게 동작하며, 언제 심각인가요?
홈페이지에 Origin: https://scanner-probe.example 헤더를 붙인 GET 요청을 한 번 보내고, 응답의 Access-Control-Allow-Origin과 Access-Control-Allow-Credentials를 읽습니다. Access-Control-Allow-Origin 헤더가 없거나 테스트 출처를 되돌려 주지 않는 고정 출처면 통과입니다. 테스트 출처를 Access-Control-Allow-Credentials: true와 함께 되돌려 주면 심각입니다. 로그인한 사용자가 방문하는 어떤 사이트든 그 사용자의 응답을 읽을 수 있기 때문입니다. 자격 증명 없이 출처를 되돌려 주면 중간입니다. 와일드카드 *는 낮음이며, 자격 증명도 허용하면 중간입니다(브라우저는 이 조합을 거부합니다). 홈페이지만 검사하고 OPTIONS 프리플라이트는 보내지 않으므로, API 경로는 curl -sI -H "Origin: https://scanner-probe.example" https://your-site/api/ | grep -i access-control 로 따로 확인하세요.
TLS 검사는 무엇을 테스트하나요(인증서 만료, TLS 1.0 및 1.1)?
443 포트에 연결해 인증서 체인과 호스트 이름을 검증합니다. 검증되지 않는 인증서는 높음, 만료된 인증서는 추가로 심각으로 표시되며, 남은 기간이 15일 미만이면 보통입니다. 그 외에는 주체, 발급자, 만료일, SAN 이름이 통과로 표시됩니다. 협상된 프로토콜은 TLS 1.2 또는 TLS 1.3이어야 하며 그보다 오래된 버전은 높음입니다. 이어서 TLS 1.0 핸드셰이크와 TLS 1.1 핸드셰이크를 각각 따로 시도합니다. 둘 중 하나라도 받아들이는 서버는 보통 등급의 결과를 받습니다. 둘 다 RFC 8996으로 사용 중단되었기 때문입니다. 스캐너 자체의 OpenSSL이 이전 버전을 제시할 수 없으면 추측하지 않고 아무것도 보고하지 않습니다. nginx 수정 방법은 ssl_protocols TLSv1.2 TLSv1.3; 날짜는 다음 명령으로 직접 확인할 수 있습니다: echo | openssl s_client -connect your-site:443 -servername your-site 2>/dev/null | openssl x509 -noout -dates
HTTP가 HTTPS로 리디렉션되는지도 확인하나요?
네. 리디렉션을 따라가지 않고 http://your-site/ 를 요청합니다. https:// 주소로의 301 또는 308은 통과입니다. HTTPS로의 302, 303, 307은 낮음입니다. 브라우저가 임시 리디렉션을 기억하지 않아 새 방문마다 암호화되지 않은 요청이 한 번 발생하기 때문입니다. 암호화되지 않은 HTTP로 페이지를 제공하면(2xx 응답) 높음입니다. 80 포트가 전혀 응답하지 않으면 실패가 아니라 정보입니다. nginx 수정 방법은 server { listen 80; return 301 https://$host$request_uri; } 이며, 그다음 Strict-Transport-Security를 추가합니다. 다음 명령으로 직접 확인할 수 있습니다: curl -I http://your-site/
어떤 HTTP 메서드를 지적하나요(TRACE, PUT, DELETE)?
홈페이지에 OPTIONS 요청을 한 번 보내 Allow 헤더를 읽고, Allow가 없으면 Access-Control-Allow-Methods를 읽습니다. TRACE, TRACK, PUT, DELETE 중 하나라도 제시되면 보통, PATCH나 CONNECT만 있으면 낮음, 표준 읽기 메서드만 있으면 통과입니다. 서버가 두 헤더를 모두 보내지 않으면 아무것도 보고하지 않습니다. 메서드가 제시되었다고 실제로 동작한다는 뜻은 아니므로, 무엇이든 바꾸기 전에 확인하세요. TRACE는 쿠키를 포함한 요청 헤더를 호출자에게 그대로 되돌려 줄 수 있습니다(Cross-Site Tracing). nginx는 기본적으로 TRACE를 거부하며, Apache에서는 TraceEnable Off를 설정합니다. PUT과 DELETE는 필요한 API 경로에만 두고 인증 뒤에 배치하세요. 다음 명령으로 직접 확인할 수 있습니다: curl -X OPTIONS -i https://your-site/
디렉터리 리스팅("Index of /")은 어떻게 탐지하나요?
7개 경로를 요청합니다: /, /static/, /assets/, /uploads/, /images/, /files/ 및 /backup/. HTTP 200으로 응답하면서 제목이나 주 제목이 "Index of /"로 시작하는 페이지를 돌려주는 경로는 보통으로 보고됩니다(CWE-548). 어디에서도 링크되지 않은 파일, 예를 들어 백업, 내보내기 파일, 이전 버전이 목록으로 드러나기 때문입니다. 해당하는 경로가 없으면 통과이고, 사이트에 접속할 수 없으면 수행되지 않음으로 보고됩니다. nginx 수정 방법은 autoindex off; (이것이 기본값이므로 명시적으로 적힌 autoindex on을 찾으세요), Apache에서는 Options -Indexes이며, 그다음 민감한 것은 모두 웹 루트 밖으로 옮깁니다. 다음 명령으로 직접 확인할 수 있습니다: curl -s https://your-site/uploads/ | head -20
혼합 콘텐츠와 HTTP로 전송하는 폼을 찾아내나요?
네, 홈페이지에서 찾습니다. 서버가 보내는 HTML을 그대로 읽고(JavaScript는 실행하지 않음) src 또는 href가 http://로 시작하는 script, link, iframe, img 태그를 모두 나열합니다. 그중 .js나 .css 파일이 있으면 중간 위험입니다. 전송 중에 바꿔치기된 스크립트나 스타일시트가 HTTPS 페이지 안에서 실행되기 때문입니다. 이미지와 프레임만 있으면 낮음, 하나도 없으면 통과입니다(CWE-311). action이 http://로 시작하는 폼은 높음(CWE-319)으로 보고됩니다. 거기에 입력한 모든 내용이 비밀번호를 포함해 암호화 없이 전송되기 때문입니다. 해결책은 그 URL을 https://로 바꾸거나 상대 경로로 만들고, 안전망으로 Content-Security-Policy: upgrade-insecure-requests 헤더를 추가하는 것입니다. 직접 확인: curl -s https://your-site/ | grep -Eo "(src|href|action)=.http://[^ >]*"
robots.txt와 security.txt에서 무엇을 확인하나요?
robots.txt: /robots.txt를 가져와 HTTP 200 텍스트 파일이면 처음 8000자 안의 Disallow 줄을 읽습니다. admin, internal, private, backup, config, staging, test, api, secret, dev 중 하나가 들어간 Disallow 경로는 낮음(CWE-200)으로 보고됩니다. robots.txt는 공개 파일이고 규칙을 지키는 크롤러에게 들어오지 말라고 부탁할 뿐이라, 그런 경로를 적으면 오히려 광고하는 셈입니다. 로그인으로 보호하고, 검색에서 빼려는 페이지에는 noindex를 쓰세요. security.txt: RFC 9116이 정한 위치인 /.well-known/security.txt를 요청하고, 파일에 Contact: 줄이 있으면 가점으로 칩니다. 파일이 없어도 감점은 없습니다. RFC 9116은 Expires: 필드도 필수로 요구하지만 스캔은 이를 확인하지 않으므로 둘 다 게시하세요. 예: Contact: mailto:security@your-site, Expires: 2027-06-30T23:00:00Z. 직접 확인: curl -s https://your-site/.well-known/security.txt
CAA 검사는 무엇을 보며, CAA 레코드는 어떻게 추가하나요?
입력한 호스트 이름의 CAA 레코드(RFC 8659)를 Cloudflare DNS-over-HTTPS로 조회합니다. 레코드가 있으면 검사를 통과하고 증거에 최대 5개를 보여 줍니다. 하나도 없으면 "No CAA record"를 낮음으로 보고합니다. 이 경우 어떤 공개 인증 기관이든 그 이름의 인증서를 발급할 수 있기 때문입니다. CAA 레코드에는 실제로 사용하는 CA를 나열합니다. 예: your-site. IN CAA 0 issue "letsencrypt.org", 그리고 보고를 받으려면 0 iodef "mailto:security@your-site". 사용하는 CA마다 issue 줄을 하나씩 추가하고, 와일드카드 인증서를 다른 CA에서 받는다면 issuewild 줄도 추가하세요. 직접 확인: dig CAA your-site
www나 하위 도메인을 스캔하면 왜 CAA, SPF, DMARC가 없다고 나오나요?
모든 DNS 검사는 입력한 이름 그대로 실행되므로 www.example.com은 example.com이 아니라 www.example.com으로 조회되며, 세 레코드는 상속 방식이 서로 다릅니다. CAA: www.example.com에서 CAA 레코드를 찾지 못한 인증 기관은 example.com으로 올라가 그 레코드를 사용합니다(RFC 8659 섹션 3). 따라서 하위 도메인의 "No CAA record"는 오탐일 수 있습니다. DMARC: 수신 측은 조직 도메인의 정책으로 대체하며, 이 정책은 sp=로 하위 도메인용 정책을 따로 정할 수 있습니다(RFC 7489를 대체한 RFC 9989). 따라서 _dmarc.www.example.com에 레코드가 없어도 보통 _dmarc.example.com이 적용됩니다. SPF: 상속이 없으므로(RFC 7208) 그 이름에 대한 "No SPF record"는 정확합니다. 메일을 보내지 않는 호스트 이름은 v=spf1 -all을 게시할 수 있습니다. DNS 조회가 실패해도 레코드 없음으로 표시됩니다. www 없는 도메인도 스캔하거나 dig CAA example.com과 dig TXT _dmarc.example.com으로 확인하세요