Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ jobs:
root / 'passive-scanner' / 'report' / 'index.html',
root / 'online-passive-scanner' / 'index.html',
root / 'online-passive-scanner' / 'report.html',
root / 'online-passive-scanner' / 'report-legacy.html',
]
missing_html = [str(p) for p in html_files if not p.exists()]
if missing_html:
Expand All @@ -48,14 +47,6 @@ jobs:

pattern = re.compile(r'(?:href|src)=["\']([^"\']+)["\']')
missing_targets = []
ignore_exact = {
'link',
'link_to_plugin',
}
ignore_regex = [
re.compile(r'^http__.+\.html$'),
]

for html_file in html_files:
text = html_file.read_text(encoding='utf-8')
for target in pattern.findall(text):
Expand All @@ -75,12 +66,6 @@ jobs:
if not normalized:
continue

if normalized in ignore_exact:
continue

if any(regex.match(normalized) for regex in ignore_regex):
continue

if normalized.startswith('/'):
candidate = root / normalized[1:]
else:
Expand Down
9 changes: 0 additions & 9 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ jobs:
Path('passive-scanner/report/index.html'),
Path('online-passive-scanner/index.html'),
Path('online-passive-scanner/report.html'),
Path('online-passive-scanner/report-legacy.html'),
]
pattern = re.compile(r'(?:href|src)=["\']([^"\']+)["\']')
ignore_exact = {'link', 'link_to_plugin'}
ignore_regex = [re.compile(r'^http__.+\.html$')]

missing_targets = []
for html_file in html_files:
Expand All @@ -74,12 +71,6 @@ jobs:
if not normalized:
continue

if normalized in ignore_exact:
continue

if any(regex.match(normalized) for regex in ignore_regex):
continue

if normalized.startswith('/'):
candidate = root / normalized[1:]
else:
Expand Down
19 changes: 8 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,16 @@ The generated output is written to `_site/` and should not be committed.

The initial Jekyll migration preserves existing OWTF landing page content and formatting. Modernization changes should be made incrementally after parity sign-off.

## Passive scanner source
## Passive scanner routes

Passive scanner integration in this repository is pinned to upstream `owtf/online-passive-scanner`:

- https://github.com/owtf/online-passive-scanner

See `/docs/PASSIVE_SCANNER_SOURCE.md` for the integration contract.

The scanner is vendored at `/online-passive-scanner/` and is accessible at:
The online passive scanner is now implemented as a Jekyll-processed Tailwind + vanilla JS experience in this repository:

- `/online-passive-scanner/`
- `/online-passive-scanner/report.html`

Compatibility routes are kept for older links and redirect to the online scanner routes:

A Jekyll-native launcher page is available at:
- `/passive-scanner/` -> `/online-passive-scanner/`
- `/passive-scanner/report/` -> `/online-passive-scanner/report.html`

- `/passive-scanner/`
- `/passive-scanner/report/`
See `/docs/PASSIVE_SCANNER_SOURCE.md` for implementation details and maintenance scope.
2 changes: 1 addition & 1 deletion _includes/header.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<header class="section-container pt-10"><nav class="flex items-center justify-between rounded-full border border-slate-200 bg-white/80 px-6 py-4 shadow-card backdrop-blur"><a class="flex items-center gap-3" href="/"><span class="flex h-10 w-10 items-center justify-center rounded-full border border-slate-200 bg-white text-sm font-semibold text-slate-900">OW</span><span class="hidden text-sm font-medium tracking-wide text-slate-600 sm:inline">Offensive Web Testing Framework</span></a><div class="hidden items-center gap-8 text-sm text-slate-600 md:flex">
<a href="#overview" class="transition hover:text-slate-900">Overview</a><a href="#capabilities" class="transition hover:text-slate-900">Capabilities</a><a href="#standards" class="transition hover:text-slate-900">Standards</a><a href="/passive-scanner/" class="transition hover:text-slate-900">Scanner</a><a href="https://owtf.readthedocs.io/en/develop/" class="transition hover:text-slate-900">Docs</a>
<a href="#overview" class="transition hover:text-slate-900">Overview</a><a href="#capabilities" class="transition hover:text-slate-900">Capabilities</a><a href="#standards" class="transition hover:text-slate-900">Standards</a><a href="/online-passive-scanner/" class="transition hover:text-slate-900">Scanner</a><a href="https://owtf.readthedocs.io/en/develop/" class="transition hover:text-slate-900">Docs</a>
</div>
<div class="flex items-center gap-3">
<a href="https://github.com/owtf/owtf" class="hidden whitespace-nowrap rounded-full border border-slate-200 px-3 py-2 text-xs font-semibold text-slate-700 transition hover:border-slate-300 hover:text-slate-900 lg:inline-flex">GitHub</a><a href="https://github.com/owtf/owtf/releases" class="inline-flex items-center gap-2 rounded-full bg-slate-900 px-4 py-2 text-xs font-semibold text-white transition hover:bg-slate-700">Get OWTF<span class="text-base leading-none">&rarr;</span></a>
Expand Down
33 changes: 17 additions & 16 deletions docs/PASSIVE_SCANNER_SOURCE.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
# Passive Scanner Source of Truth
# Passive Scanner Implementation Scope

The passive scanner integration in this repository must use upstream code from:
The scanner experience published in this repository is now a local implementation (Jekyll + Tailwind + vanilla JavaScript), served from:

- `https://github.com/owtf/online-passive-scanner`
- `/online-passive-scanner/`
- `/online-passive-scanner/report.html`

## Integration contract
## Design goals

1. Do not reimplement scanner logic locally when upstream code is available.
2. Use a sync model (git subtree or submodule) and record the upstream commit/version used.
3. Keep wrapper logic in this repository limited to configuration, execution, and report shaping for site publishing.
1. Keep scanner UI and report pages fully Jekyll-compatible for GitHub Pages.
2. Avoid legacy iframe embedding and legacy jQuery/Bootstrap dependencies.
3. Preserve compatibility for historical links via redirects:
- `/passive-scanner/` redirects to `/online-passive-scanner/`
- `/passive-scanner/report/` redirects to `/online-passive-scanner/report.html`

## Planned implementation
## Current scanner behavior

Current implementation in this repository:
1. URL posture checks (scheme, credentials in URL, risky route patterns, sensitive query keys).
2. DNS posture checks through DNS-over-HTTPS (`dns.google/resolve`) for A/AAAA/CAA/MX/NS/TXT.
3. Risk scoring and findings rendering in-browser.

1. Upstream scanner is vendored under `online-passive-scanner/`.
2. Upstream provenance is tracked in `online-passive-scanner/UPSTREAM_SOURCE.txt`.
3. Sync helper script is available at `scripts/sync-online-passive-scanner.sh`.
## Maintenance notes

Planned next implementation:

1. Add a local wrapper entrypoint under `tools/passive_scanner/`.
2. Add scheduled workflow to run passive scan automation and publish `_data/passive_scan/latest.json`.
1. Keep logic and UX inside repository-owned pages under `online-passive-scanner/`.
2. If upstream OWTF scanner work is reused, treat it as reference input and port intentionally rather than embedding legacy runtime directly.
242 changes: 78 additions & 164 deletions online-passive-scanner/index.html
Original file line number Diff line number Diff line change
@@ -1,175 +1,89 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="OWASP OWTF Summary Report" />
<meta name="author" content="OWASP OWTF Team" />
<title>OWASP OWTF Summary Report</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>
<style>
body {
background-color: #f5f7fa;
min-height: 100vh;
position: relative;
}

.github-ribbon {
position: fixed;
top: 1rem;
right: -3.5rem;
display: block;
width: 12rem;
padding: 0.75rem 0;
background: linear-gradient(135deg, #1f2328, #24292f);
color: #f8fbff;
text-align: center;
text-decoration: none;
font-weight: 600;
font-size: 0.9rem;
letter-spacing: 0.05em;
text-transform: uppercase;
transform: rotate(45deg);
transform-origin: top right;
box-shadow: 0 6px 12px rgba(15, 23, 42, 0.35);
z-index: 1000;
}

.github-ribbon:focus-visible {
outline: 2px solid #f0f6ff;
outline-offset: 2px;
}
---
layout: default
title: "OWTF Online Passive Scanner"
description: "Run OWTF passive URL and DNS reconnaissance checks from a modern Tailwind interface."
---
<div class="pointer-events-none absolute inset-x-0 top-0 -z-10 h-[420px] bg-gradient-to-b from-slate-100 via-white to-white"></div>
<div class="relative flex min-h-screen flex-col">
{% include header.html %}
<main class="space-y-32 pb-16">
<section class="section-container pb-24 pt-24">
<div class="max-w-3xl space-y-6">
<p class="text-xs font-semibold uppercase tracking-[0.4em] text-slate-500">Online passive scanner</p>
<h1 class="text-4xl font-semibold tracking-tight text-slate-900 sm:text-5xl">Quick passive reconnaissance for web targets</h1>
<p class="text-lg leading-relaxed text-slate-600">This scanner reviews a target URL and its DNS posture for externally visible risk indicators. It is passive-only and does not run exploit payloads against the target.</p>
</div>

@media (max-width: 576px) {
.github-ribbon {
width: 10rem;
right: -3rem;
font-size: 0.75rem;
}
}
<div class="mt-12 rounded-3xl border border-slate-200 bg-white p-8 shadow-card">
<label for="target-url" class="text-sm font-semibold text-slate-900">Target URL</label>
<input id="target-url" type="url" placeholder="https://www.example.com" class="mt-3 block rounded-2xl border border-slate-200 bg-white p-5 text-sm text-slate-900" style="width:100%" autocomplete="url" />
<p id="scan-error" class="mt-2 text-sm text-slate-600" style="display:none"></p>
<div class="mt-6 flex flex-col gap-4 sm:flex-row sm:items-center">
<button id="open-report" class="inline-flex items-center justify-center gap-2 rounded-full bg-slate-900 px-6 py-3 text-sm font-semibold text-white transition hover:bg-slate-700">Run passive scan<span class="text-lg leading-none">&rarr;</span></button>
<a href="https://github.com/owtf/online-passive-scanner" class="inline-flex items-center justify-center gap-2 rounded-full border border-slate-200 px-6 py-3 text-sm font-semibold text-slate-700 transition hover:border-slate-300 hover:text-slate-900">Scanner source</a>
</div>
</div>

.page-header img {
max-width: 150px;
}
<div class="mt-8 grid gap-4 md:grid-cols-3">
<div class="rounded-2xl border border-slate-200 bg-white p-6 shadow-inset">
<p class="text-sm font-semibold text-slate-900">URL posture checks</p>
<p class="mt-2 text-sm text-slate-600">Flags insecure schemes, exposed credentials, risky parameters, and suspicious route patterns.</p>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-6 shadow-inset">
<p class="text-sm font-semibold text-slate-900">DNS posture checks</p>
<p class="mt-2 text-sm text-slate-600">Queries A, AAAA, CAA, MX, NS, and TXT records through DNS-over-HTTPS for baseline exposure signals.</p>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-6 shadow-inset">
<p class="text-sm font-semibold text-slate-900">Shareable report URLs</p>
<p class="mt-2 text-sm text-slate-600">Each report can be reopened by sharing a link with the encoded `#q=` target value.</p>
</div>
</div>
</section>
</main>
{% include footer.html %}
</div>

.page-header h1 {
font-size: 2rem;
margin-bottom: 0;
}
<script>
(function () {
var input = document.getElementById('target-url');
var button = document.getElementById('open-report');
var error = document.getElementById('scan-error');
var reportPath = "{{ '/online-passive-scanner/report.html' | relative_url }}";

#targetbar h2 {
font-weight: 600;
function setError(message) {
if (!message) {
error.style.display = 'none';
error.textContent = '';
return;
}
error.style.display = 'block';
error.textContent = message;
}

.error-message {
display: none;
function openReport() {
setError('');
var value = (input.value || '').trim();
if (!value) {
setError('Please enter a URL to continue.');
input.focus();
return;
}
</style>
<script>
const isGithubPages =
window.location.hostname === "owtf.github.io" &&
window.location.pathname.startsWith("/online-passive-scanner");

if (isGithubPages && window.location.protocol === "http:") {
const { host, pathname, search, hash } = window.location;
window.location.replace(`https://${host}${pathname}${search}${hash}`);
try {
var parsed = new URL(value);
window.location.assign(reportPath + '#q=' + encodeURIComponent(parsed.href));
} catch (err) {
setError('The value provided is not a valid URL.');
input.focus();
}
</script>
</head>
<body>
<div class="container py-5">
<a
href="https://github.com/owtf/online-passive-scanner"
aria-label="Fork me on GitHub"
class="github-ribbon"
>
Fork me on GitHub
</a>
<header class="page-header row align-items-center g-4 mb-5">
<div class="col-md-3 text-center text-md-start">
<a href="https://owasp.org/www-project-owtf/">
<img
src="images/owtf-logo.svg"
class="img-fluid rounded"
alt="OWASP OWTF Logo"
width="150"
height="150"
/>
</a>
</div>
<div class="col-md-9">
<h1 class="fw-semibold">Online Passive Scanner</h1>
<p class="text-muted mb-0">
Version 1.0.1 · Release <strong>Lionheart</strong>
<span class="visually-hidden" id="seed">2NfaMaxkF_</span>
</p>
</div>
</header>
<section id="targetbar" class="row mb-4">
<div class="col">
<h2 class="h4">Enter the target URL</h2>
<p class="text-muted">
Paste the URL you would like to review. We will generate a passive report using the
bundled sample data.
</p>
</div>
</section>
<form class="row gy-3" novalidate>
<div class="col-lg-8">
<label class="form-label" for="q">Target URL</label>
<input
type="url"
id="q"
name="q"
class="form-control form-control-lg"
placeholder="https://www.example.com"
autocomplete="url"
required
/>
<p id="error" class="error-message text-danger mt-2" role="alert"></p>
</div>
<div class="col-lg-4 d-flex align-items-end">
<button type="submit" class="btn btn-primary btn-lg w-100" id="submit">Generate report</button>
</div>
</form>
<footer id="footer" class="mt-5 text-muted">
Built during GSoC 2014 by the <a href="https://owtf.github.io/">OWTF team</a>.
</footer>
</div>
<script>
const form = document.querySelector("form");
const input = document.getElementById("q");
const errorMessage = document.getElementById("error");
}

form.addEventListener("submit", (event) => {
button.addEventListener('click', openReport);
input.addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
event.preventDefault();
errorMessage.style.display = "none";
errorMessage.textContent = "";

const value = input.value.trim();
if (!value) {
errorMessage.textContent = "Please enter a URL to continue.";
errorMessage.style.display = "block";
input.focus();
return;
}

try {
const parsed = new URL(value);
const destination = new URL("report.html", window.location.href);
destination.hash = `q=${encodeURIComponent(parsed.href)}`;
window.location.assign(destination.toString());
} catch (error) {
errorMessage.textContent = "The value provided is not a valid URL. Please check and try again.";
errorMessage.style.display = "block";
input.focus();
}
});
</script>
</body>
</html>
openReport();
}
});
})();
</script>
Loading