1013 lines
42 KiB
HTML
1013 lines
42 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="tr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>SecurePrompt — Web Güvenlik Denetimi Prompt Oluşturucu</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Syne:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
||
<style>
|
||
:root {
|
||
--bg: #0a0c10;
|
||
--bg2: #0f1318;
|
||
--bg3: #151a22;
|
||
--bg4: #1c2330;
|
||
--border: #1e2d3d;
|
||
--border2: #243447;
|
||
--text: #e2e8f0;
|
||
--text2: #8899aa;
|
||
--text3: #4a5568;
|
||
--accent: #00d4ff;
|
||
--accent2: #0099cc;
|
||
--green: #00e5a0;
|
||
--green2: #00a070;
|
||
--red: #ff4757;
|
||
--orange: #ff9f43;
|
||
--yellow: #ffd32a;
|
||
--fe: #7c6af5;
|
||
--be: #00e5a0;
|
||
--db: #ff6b6b;
|
||
--inf: #45aaf2;
|
||
--font-head: 'Syne', sans-serif;
|
||
--font-mono: 'JetBrains Mono', monospace;
|
||
}
|
||
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
|
||
html { scroll-behavior: smooth; }
|
||
|
||
body {
|
||
background: var(--bg);
|
||
color: var(--text);
|
||
font-family: var(--font-mono);
|
||
min-height: 100vh;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
/* NOISE TEXTURE */
|
||
body::before {
|
||
content: '';
|
||
position: fixed;
|
||
inset: 0;
|
||
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.04'/%3E%3C/svg%3E");
|
||
pointer-events: none;
|
||
z-index: 0;
|
||
opacity: 0.4;
|
||
}
|
||
|
||
/* GRID BG */
|
||
body::after {
|
||
content: '';
|
||
position: fixed;
|
||
inset: 0;
|
||
background-image:
|
||
linear-gradient(var(--border) 1px, transparent 1px),
|
||
linear-gradient(90deg, var(--border) 1px, transparent 1px);
|
||
background-size: 40px 40px;
|
||
opacity: 0.3;
|
||
pointer-events: none;
|
||
z-index: 0;
|
||
}
|
||
|
||
.layout {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: grid;
|
||
grid-template-columns: 320px 1fr;
|
||
grid-template-rows: auto 1fr;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
/* ── HEADER ── */
|
||
header {
|
||
grid-column: 1 / -1;
|
||
padding: 1rem 1.5rem;
|
||
border-bottom: 1px solid var(--border);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 1rem;
|
||
background: rgba(10,12,16,0.95);
|
||
backdrop-filter: blur(8px);
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 100;
|
||
}
|
||
|
||
.logo {
|
||
font-family: var(--font-head);
|
||
font-size: 20px;
|
||
font-weight: 800;
|
||
letter-spacing: -0.5px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.logo-icon {
|
||
width: 32px; height: 32px;
|
||
background: linear-gradient(135deg, var(--accent), var(--fe));
|
||
border-radius: 8px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.logo span { color: var(--accent); }
|
||
|
||
.header-meta {
|
||
margin-left: auto;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
|
||
.badge {
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
padding: 3px 8px;
|
||
border-radius: 4px;
|
||
border: 1px solid;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
}
|
||
.badge-green { color: var(--green); border-color: var(--green2); background: rgba(0,229,160,0.08); }
|
||
.badge-blue { color: var(--accent); border-color: var(--accent2); background: rgba(0,212,255,0.08); }
|
||
|
||
.stat-chips { display: flex; gap: 8px; }
|
||
.chip {
|
||
font-size: 11px;
|
||
padding: 4px 10px;
|
||
border-radius: 6px;
|
||
background: var(--bg3);
|
||
border: 1px solid var(--border);
|
||
color: var(--text2);
|
||
display: flex; align-items: center; gap: 5px;
|
||
}
|
||
.chip strong { color: var(--text); font-weight: 600; }
|
||
|
||
/* ── SIDEBAR ── */
|
||
.sidebar {
|
||
border-right: 1px solid var(--border);
|
||
background: var(--bg2);
|
||
padding: 1.25rem;
|
||
overflow-y: auto;
|
||
height: calc(100vh - 57px);
|
||
position: sticky;
|
||
top: 57px;
|
||
}
|
||
|
||
.section { margin-bottom: 1.5rem; }
|
||
|
||
.section-title {
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
color: var(--text3);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.12em;
|
||
margin-bottom: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
.section-title::after {
|
||
content: '';
|
||
flex: 1;
|
||
height: 1px;
|
||
background: var(--border);
|
||
}
|
||
|
||
.pills { display: flex; flex-wrap: wrap; gap: 6px; }
|
||
|
||
.pill {
|
||
font-family: var(--font-mono);
|
||
font-size: 11px;
|
||
padding: 4px 10px;
|
||
border-radius: 5px;
|
||
border: 1px solid var(--border2);
|
||
background: transparent;
|
||
color: var(--text2);
|
||
cursor: pointer;
|
||
transition: all 0.15s;
|
||
}
|
||
.pill:hover { border-color: var(--accent2); color: var(--text); }
|
||
.pill.on { background: rgba(0,212,255,0.12); border-color: var(--accent); color: var(--accent); }
|
||
|
||
/* LAYER TABS */
|
||
.layer-tabs {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 6px;
|
||
margin-bottom: 10px;
|
||
}
|
||
.ltab {
|
||
font-family: var(--font-mono);
|
||
font-size: 11px;
|
||
padding: 6px 8px;
|
||
border-radius: 6px;
|
||
border: 1px solid var(--border2);
|
||
background: transparent;
|
||
color: var(--text2);
|
||
cursor: pointer;
|
||
transition: all 0.15s;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
}
|
||
.ltab:hover { background: var(--bg3); color: var(--text); }
|
||
.ltab.on { background: var(--bg4); border-color: var(--border2); color: var(--text); }
|
||
.ltab.on[data-l="fe"] { border-color: var(--fe); color: var(--fe); background: rgba(124,106,245,0.1); }
|
||
.ltab.on[data-l="be"] { border-color: var(--be); color: var(--be); background: rgba(0,229,160,0.08); }
|
||
.ltab.on[data-l="db"] { border-color: var(--db); color: var(--db); background: rgba(255,107,107,0.08); }
|
||
.ltab.on[data-l="inf"] { border-color: var(--inf); color: var(--inf); background: rgba(69,170,242,0.08); }
|
||
|
||
.dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
|
||
.dot-fe { background: var(--fe); }
|
||
.dot-be { background: var(--be); }
|
||
.dot-db { background: var(--db); }
|
||
.dot-inf { background: var(--inf); }
|
||
|
||
/* CAT CARDS */
|
||
.cat-grid { display: flex; flex-direction: column; gap: 5px; }
|
||
|
||
.ccard {
|
||
border: 1px solid var(--border);
|
||
border-radius: 7px;
|
||
padding: 8px 10px;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 8px;
|
||
transition: all 0.15s;
|
||
background: var(--bg);
|
||
}
|
||
.ccard:hover { border-color: var(--border2); background: var(--bg3); }
|
||
.ccard.on { border-color: var(--fe); background: rgba(124,106,245,0.08); }
|
||
.ccard.on[data-layer="be"] { border-color: var(--be); background: rgba(0,229,160,0.06); }
|
||
.ccard.on[data-layer="db"] { border-color: var(--db); background: rgba(255,107,107,0.06); }
|
||
.ccard.on[data-layer="inf"] { border-color: var(--inf); background: rgba(69,170,242,0.06); }
|
||
|
||
.ccheck {
|
||
width: 14px; height: 14px;
|
||
border-radius: 3px;
|
||
border: 1.5px solid var(--border2);
|
||
flex-shrink: 0;
|
||
margin-top: 2px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
transition: all 0.15s;
|
||
}
|
||
.ccard.on .ccheck { background: var(--fe); border-color: var(--fe); }
|
||
.ccard.on[data-layer="be"] .ccheck { background: var(--be); border-color: var(--be); }
|
||
.ccard.on[data-layer="db"] .ccheck { background: var(--db); border-color: var(--db); }
|
||
.ccard.on[data-layer="inf"] .ccheck { background: var(--inf); border-color: var(--inf); }
|
||
|
||
.ccheck svg { display: none; width: 9px; height: 9px; }
|
||
.ccard.on .ccheck svg { display: block; }
|
||
|
||
.clbl { font-size: 12px; font-weight: 500; color: var(--text); line-height: 1.2; }
|
||
.cdesc { font-size: 10px; color: var(--text2); margin-top: 3px; line-height: 1.4; }
|
||
|
||
.sev {
|
||
font-size: 9px;
|
||
padding: 1px 5px;
|
||
border-radius: 3px;
|
||
margin-left: 5px;
|
||
font-weight: 600;
|
||
vertical-align: middle;
|
||
letter-spacing: 0.04em;
|
||
}
|
||
.sev-c { background: rgba(255,71,87,0.15); color: var(--red); border: 1px solid rgba(255,71,87,0.3); }
|
||
.sev-h { background: rgba(255,159,67,0.15); color: var(--orange); border: 1px solid rgba(255,159,67,0.3); }
|
||
.sev-m { background: rgba(69,170,242,0.15); color: var(--inf); border: 1px solid rgba(69,170,242,0.3); }
|
||
|
||
.select-all-btn {
|
||
font-family: var(--font-mono);
|
||
font-size: 10px;
|
||
padding: 3px 8px;
|
||
border-radius: 4px;
|
||
border: 1px solid var(--border2);
|
||
background: transparent;
|
||
color: var(--text3);
|
||
cursor: pointer;
|
||
transition: all 0.15s;
|
||
margin-left: auto;
|
||
}
|
||
.select-all-btn:hover { color: var(--text2); border-color: var(--border2); }
|
||
|
||
.section-title-row {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 10px;
|
||
}
|
||
.section-title-row .section-title { margin-bottom: 0; flex: 1; }
|
||
|
||
/* ── MAIN ── */
|
||
main {
|
||
display: grid;
|
||
grid-template-rows: 1fr auto;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.prompt-area {
|
||
padding: 1.5rem;
|
||
overflow-y: auto;
|
||
height: calc(100vh - 57px - 80px);
|
||
}
|
||
|
||
.prompt-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
.prompt-header h2 {
|
||
font-family: var(--font-head);
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: var(--text2);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.1em;
|
||
}
|
||
|
||
.line-count {
|
||
font-size: 10px;
|
||
color: var(--text3);
|
||
margin-left: auto;
|
||
}
|
||
|
||
/* PROMPT EDITOR */
|
||
.prompt-container {
|
||
position: relative;
|
||
border: 1px solid var(--border);
|
||
border-radius: 10px;
|
||
overflow: hidden;
|
||
background: var(--bg2);
|
||
}
|
||
|
||
.prompt-container::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0; left: 0; right: 0;
|
||
height: 2px;
|
||
background: linear-gradient(90deg, var(--accent), var(--fe), var(--be), var(--db));
|
||
}
|
||
|
||
.line-numbers {
|
||
position: absolute;
|
||
left: 0; top: 0; bottom: 0;
|
||
width: 44px;
|
||
background: var(--bg);
|
||
border-right: 1px solid var(--border);
|
||
padding: 1rem 0;
|
||
overflow: hidden;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.line-num {
|
||
font-size: 10px;
|
||
color: var(--text3);
|
||
text-align: right;
|
||
padding: 0 8px;
|
||
line-height: 1.75;
|
||
font-family: var(--font-mono);
|
||
height: 20.3px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
#prompt-output {
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
line-height: 1.75;
|
||
color: var(--text);
|
||
padding: 1rem 1rem 1rem 56px;
|
||
white-space: pre-wrap;
|
||
word-break: break-word;
|
||
min-height: 400px;
|
||
outline: none;
|
||
background: transparent;
|
||
width: 100%;
|
||
border: none;
|
||
resize: none;
|
||
caret-color: var(--accent);
|
||
}
|
||
|
||
/* SYNTAX HIGHLIGHT */
|
||
.hl-h1 { color: var(--accent); font-weight: 600; }
|
||
.hl-h2 { color: var(--green); font-weight: 600; }
|
||
.hl-h3 { color: var(--fe); font-weight: 500; }
|
||
.hl-bold { color: var(--orange); font-weight: 600; }
|
||
.hl-code { color: var(--yellow); background: rgba(255,211,42,0.08); padding: 0 3px; border-radius: 3px; }
|
||
.hl-bullet { color: var(--text2); }
|
||
.hl-dash { color: var(--accent2); }
|
||
|
||
/* BOTTOM BAR */
|
||
.bottom-bar {
|
||
height: 80px;
|
||
border-top: 1px solid var(--border);
|
||
background: rgba(10,12,16,0.98);
|
||
backdrop-filter: blur(8px);
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 1.5rem;
|
||
gap: 10px;
|
||
}
|
||
|
||
.btn {
|
||
font-family: var(--font-mono);
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
padding: 9px 18px;
|
||
border-radius: 7px;
|
||
cursor: pointer;
|
||
transition: all 0.15s;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: linear-gradient(135deg, var(--accent2), var(--accent));
|
||
border: 1px solid var(--accent);
|
||
color: #000;
|
||
font-weight: 600;
|
||
}
|
||
.btn-primary:hover { opacity: 0.9; transform: translateY(-1px); box-shadow: 0 4px 20px rgba(0,212,255,0.3); }
|
||
|
||
.btn-secondary {
|
||
background: var(--bg3);
|
||
border: 1px solid var(--border2);
|
||
color: var(--text);
|
||
}
|
||
.btn-secondary:hover { border-color: var(--accent2); color: var(--accent); background: rgba(0,212,255,0.06); }
|
||
|
||
.btn-green {
|
||
background: rgba(0,229,160,0.1);
|
||
border: 1px solid var(--green2);
|
||
color: var(--green);
|
||
}
|
||
.btn-green:hover { background: rgba(0,229,160,0.18); transform: translateY(-1px); }
|
||
|
||
.btn-orange {
|
||
background: rgba(255,159,67,0.1);
|
||
border: 1px solid rgba(255,159,67,0.4);
|
||
color: var(--orange);
|
||
}
|
||
.btn-orange:hover { background: rgba(255,159,67,0.18); transform: translateY(-1px); }
|
||
|
||
.toast {
|
||
position: fixed;
|
||
bottom: 100px;
|
||
right: 24px;
|
||
background: var(--bg4);
|
||
border: 1px solid var(--green2);
|
||
color: var(--green);
|
||
font-size: 12px;
|
||
padding: 10px 18px;
|
||
border-radius: 8px;
|
||
z-index: 999;
|
||
opacity: 0;
|
||
transform: translateY(10px);
|
||
transition: all 0.25s;
|
||
pointer-events: none;
|
||
}
|
||
.toast.show { opacity: 1; transform: translateY(0); }
|
||
|
||
/* EMPTY STATE */
|
||
.empty {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 100%;
|
||
min-height: 300px;
|
||
color: var(--text3);
|
||
gap: 8px;
|
||
}
|
||
.empty-icon { font-size: 40px; opacity: 0.3; }
|
||
.empty-text { font-size: 13px; }
|
||
|
||
/* SCROLLBAR */
|
||
::-webkit-scrollbar { width: 6px; }
|
||
::-webkit-scrollbar-track { background: var(--bg); }
|
||
::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 3px; }
|
||
::-webkit-scrollbar-thumb:hover { background: var(--text3); }
|
||
|
||
/* PROGRESS BAR */
|
||
.progress-bar {
|
||
height: 3px;
|
||
background: var(--bg3);
|
||
border-radius: 2px;
|
||
margin-top: 6px;
|
||
overflow: hidden;
|
||
}
|
||
.progress-fill {
|
||
height: 100%;
|
||
background: linear-gradient(90deg, var(--accent), var(--fe));
|
||
border-radius: 2px;
|
||
transition: width 0.3s ease;
|
||
}
|
||
|
||
/* MODAL */
|
||
.modal-overlay {
|
||
position: fixed;
|
||
inset: 0;
|
||
background: rgba(0,0,0,0.7);
|
||
backdrop-filter: blur(4px);
|
||
z-index: 200;
|
||
display: none;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.modal-overlay.show { display: flex; }
|
||
.modal {
|
||
background: var(--bg2);
|
||
border: 1px solid var(--border2);
|
||
border-radius: 12px;
|
||
padding: 1.5rem;
|
||
max-width: 480px;
|
||
width: 90%;
|
||
}
|
||
.modal h3 {
|
||
font-family: var(--font-head);
|
||
font-size: 16px;
|
||
margin-bottom: 1rem;
|
||
color: var(--accent);
|
||
}
|
||
.modal-btns { display: flex; gap: 8px; margin-top: 1.25rem; justify-content: flex-end; }
|
||
.modal-format-list { display: flex; flex-direction: column; gap: 8px; }
|
||
.modal-opt {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
padding: 10px 12px;
|
||
border: 1px solid var(--border);
|
||
border-radius: 7px;
|
||
cursor: pointer;
|
||
transition: all 0.15s;
|
||
}
|
||
.modal-opt:hover { border-color: var(--border2); background: var(--bg3); }
|
||
.modal-opt.sel { border-color: var(--accent); background: rgba(0,212,255,0.08); }
|
||
.modal-opt-icon { font-size: 20px; }
|
||
.modal-opt-title { font-size: 13px; font-weight: 500; color: var(--text); }
|
||
.modal-opt-desc { font-size: 11px; color: var(--text2); }
|
||
|
||
/* ANIM */
|
||
@keyframes fadeIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
|
||
.ccard { animation: fadeIn 0.15s ease; }
|
||
|
||
/* RESPONSIVE */
|
||
@media (max-width: 768px) {
|
||
.layout { grid-template-columns: 1fr; }
|
||
.sidebar { height: auto; position: static; border-right: none; border-bottom: 1px solid var(--border); }
|
||
main { height: auto; }
|
||
.prompt-area { height: auto; }
|
||
.stat-chips { display: none; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="layout">
|
||
|
||
<!-- HEADER -->
|
||
<header>
|
||
<div class="logo">
|
||
<div class="logo-icon">🛡</div>
|
||
Secure<span>Prompt</span>
|
||
</div>
|
||
<span class="badge badge-green">v2.0</span>
|
||
<span class="badge badge-blue">TR</span>
|
||
<div class="header-meta">
|
||
<div class="stat-chips">
|
||
<div class="chip">Kategori: <strong id="h-cat">0</strong></div>
|
||
<div class="chip">Kontrol: <strong id="h-chk">~0</strong></div>
|
||
<div class="chip">Katman: <strong id="h-lay">0</strong></div>
|
||
<div class="chip">Token: <strong id="h-tok">~0</strong></div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- SIDEBAR -->
|
||
<aside class="sidebar">
|
||
|
||
<!-- APP TYPE -->
|
||
<div class="section">
|
||
<div class="section-title">Uygulama Türü</div>
|
||
<div class="pills" id="app-pills">
|
||
<button class="pill on" data-v="fullstack">Full-stack</button>
|
||
<button class="pill" data-v="spa">SPA / React</button>
|
||
<button class="pill" data-v="api">REST / GraphQL</button>
|
||
<button class="pill" data-v="docker">Docker</button>
|
||
<button class="pill" data-v="iot">IoT / Edge</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- LAYER + CATS -->
|
||
<div class="section">
|
||
<div class="section-title-row">
|
||
<div class="section-title" style="margin-bottom:0;flex:1">Güvenlik Katmanı</div>
|
||
<button class="select-all-btn" id="all-btn">tümünü seç</button>
|
||
</div>
|
||
<div class="layer-tabs" id="layer-tabs">
|
||
<button class="ltab on" data-l="fe"><span class="dot dot-fe"></span>Frontend</button>
|
||
<button class="ltab" data-l="be"><span class="dot dot-be"></span>Backend</button>
|
||
<button class="ltab" data-l="db"><span class="dot dot-db"></span>Veritabanı</button>
|
||
<button class="ltab" data-l="inf"><span class="dot dot-inf"></span>Altyapı</button>
|
||
</div>
|
||
<div class="cat-grid" id="cat-grid"></div>
|
||
<div class="progress-bar"><div class="progress-fill" id="progress-fill" style="width:0%"></div></div>
|
||
<div style="font-size:10px;color:var(--text3);margin-top:4px;text-align:right" id="progress-txt">0 / 0 kategori</div>
|
||
</div>
|
||
|
||
<!-- OUTPUT -->
|
||
<div class="section">
|
||
<div class="section-title">Çıktı Formatı</div>
|
||
<div class="pills" id="out-pills">
|
||
<button class="pill on" data-v="report">Markdown</button>
|
||
<button class="pill" data-v="json">JSON/SARIF</button>
|
||
<button class="pill" data-v="pr">Pull Request</button>
|
||
<button class="pill" data-v="fix">Düzeltme</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- PRIORITY -->
|
||
<div class="section">
|
||
<div class="section-title">Öncelik Filtresi</div>
|
||
<div class="pills" id="prio-pills">
|
||
<button class="pill on" data-v="all">Tümü</button>
|
||
<button class="pill" data-v="critical">Kritik</button>
|
||
<button class="pill" data-v="high">Kritik+Yüksek</button>
|
||
</div>
|
||
</div>
|
||
|
||
</aside>
|
||
|
||
<!-- MAIN CONTENT -->
|
||
<main>
|
||
<div class="prompt-area">
|
||
<div class="prompt-header">
|
||
<h2>// Generated Prompt</h2>
|
||
<span class="line-count" id="line-count">0 satır · 0 karakter</span>
|
||
</div>
|
||
|
||
<div class="prompt-container" id="prompt-container">
|
||
<div class="line-numbers" id="line-numbers"></div>
|
||
<div id="prompt-output" contenteditable="false" spellcheck="false">
|
||
<div class="empty">
|
||
<div class="empty-icon">⚡</div>
|
||
<div class="empty-text">Sol panelden kategori seçin...</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- BOTTOM BAR -->
|
||
<div class="bottom-bar">
|
||
<button class="btn btn-primary" id="btn-copy">
|
||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||
Kopyala
|
||
</button>
|
||
<button class="btn btn-green" id="btn-md">
|
||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14,2 14,8 20,8"/></svg>
|
||
.md İndir
|
||
</button>
|
||
<button class="btn btn-orange" id="btn-pdf">
|
||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14,2 14,8 20,8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
|
||
PDF İndir
|
||
</button>
|
||
<button class="btn btn-secondary" id="btn-reset" style="margin-left:auto">
|
||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="1,4 1,10 7,10"/><path d="M3.51 15a9 9 0 1 0 .49-3.08"/></svg>
|
||
Sıfırla
|
||
</button>
|
||
</div>
|
||
</main>
|
||
|
||
</div>
|
||
|
||
<!-- TOAST -->
|
||
<div class="toast" id="toast"></div>
|
||
|
||
<script>
|
||
var CATS = {
|
||
fe:[
|
||
{id:'owasp',lbl:'OWASP Top 10',sev:'c',desc:'Injection, XSS, IDOR, SSRF, XXE',chk:14,tok:180},
|
||
{id:'auth',lbl:'Kimlik Doğrulama',sev:'c',desc:'JWT, session, OAuth, MFA',chk:9,tok:120},
|
||
{id:'headers',lbl:'HTTP Başlıkları',sev:'h',desc:'CSP, HSTS, CORS, X-Frame-Options',chk:5,tok:70},
|
||
{id:'secrets',lbl:'Gizli Veri Sızıntısı',sev:'c',desc:'API key, .env, kaynak kod tespiti',chk:7,tok:110}
|
||
],
|
||
be:[
|
||
{id:'injection',lbl:'Injection Saldırıları',sev:'c',desc:'SQL, NoSQL, OS, LDAP, SSTI, XXE',chk:12,tok:200},
|
||
{id:'waf',lbl:'Saldırı Tespiti & Önleme',sev:'c',desc:'WAF, rate limit, anomali, brute force',chk:10,tok:160},
|
||
{id:'api',lbl:'API Güvenliği',sev:'h',desc:'Rate limiting, input validation, schema',chk:8,tok:120},
|
||
{id:'bizlogic',lbl:'İş Mantığı Hataları',sev:'h',desc:'Race condition, fiyat manipülasyonu',chk:7,tok:110},
|
||
{id:'fileup',lbl:'Dosya Yükleme',sev:'h',desc:'MIME bypass, path traversal, webshell',chk:6,tok:95},
|
||
{id:'crypto',lbl:'Kriptografi',sev:'h',desc:'Zayıf algoritma, key yönetimi, TLS',chk:5,tok:75}
|
||
],
|
||
db:[
|
||
{id:'sqli',lbl:'SQL Injection (Derin)',sev:'c',desc:'Blind, time-based, ORM bypass',chk:10,tok:180},
|
||
{id:'nosqli',lbl:'NoSQL Injection',sev:'c',desc:'MongoDB, Redis, Elasticsearch',chk:7,tok:130},
|
||
{id:'dbaccess',lbl:'Erişim Kontrolü',sev:'c',desc:'Least privilege, RLS, tenant izolasyon',chk:8,tok:120},
|
||
{id:'dbenc',lbl:'Şifreleme & Maskeleme',sev:'h',desc:'At-rest, in-transit, PII maskeleme',chk:6,tok:95},
|
||
{id:'dbconf',lbl:'Yapılandırma Güvenliği',sev:'h',desc:'Default cred, public erişim, backup',chk:5,tok:80}
|
||
],
|
||
inf:[
|
||
{id:'docker',lbl:'Docker & Container',sev:'h',desc:'Root kullanıcı, cap-drop, image tarama',chk:8,tok:110},
|
||
{id:'deps',lbl:'Bağımlılık Güncellemeleri',sev:'h',desc:'CVE tarama, package audit, SCA',chk:6,tok:90},
|
||
{id:'network',lbl:'Ağ & Firewall',sev:'h',desc:'Açık port, segmentasyon, TLS',chk:5,tok:75},
|
||
{id:'logging',lbl:'Loglama & İzleme',sev:'m',desc:'Audit trail, SIEM, anomali',chk:4,tok:65}
|
||
]
|
||
};
|
||
|
||
var TEXTS = {
|
||
owasp:'### OWASP Top 10\n- A01 Kırık Erişim Kontrolü: IDOR, path traversal, yetkisiz endpoint\n- A02 Kriptografik Başarısızlıklar: açık metin iletim, zayıf şifreleme\n- A03 Injection: SQL/NoSQL/OS/LDAP/template — tüm giriş noktaları\n- A04 Güvensiz Tasarım: iş mantığı açıkları, tehdit modeli eksiklikleri\n- A05 Güvenlik Yapılandırma Hataları: default credential, debug mode\n- A06 Savunmasız Bileşenler: CVE veritabanıyla karşılaştır\n- A07 Kimlik Doğrulama Hataları: brute force, credential stuffing\n- A08 Yazılım Bütünlüğü Hataları: CI/CD güvenliği, unsigned update\n- A09 Güvenlik Loglama Eksiklikleri: kritik olayların loglanması\n- A10 SSRF: kullanıcı kontrolündeki URL doğrulama ve filtreleme',
|
||
auth:'### Kimlik Doğrulama & Yetkilendirme\n- JWT: alg=none saldırısı, weak secret, expiry, refresh token rotasyonu\n- Session: fixation, CSRF, secure/httpOnly bayraklar, idle timeout\n- OAuth/OIDC: redirect_uri doğrulama, state parametresi, PKCE\n- MFA: bypass senaryoları, backup code güvenliği, rate limiting\n- RBAC/ABAC: yetki yükseltme vektörleri\n- Password: bcrypt/argon2 kullanımı, account lockout politikası',
|
||
headers:'### HTTP Güvenlik Başlıkları\n- CSP: unsafe-inline/unsafe-eval tespiti; nonce/hash tabanlı politika öner\n- HSTS: max-age ≥ 31536000, includeSubDomains, preload\n- X-Frame-Options / frame-ancestors: clickjacking koruması\n- CORS: wildcard (*) origin, credentialed request uyumsuzluğu\n- Permissions-Policy: gereksiz browser özellik izinleri\n- Referrer-Policy: hassas URL sızıntısı önleme',
|
||
secrets:'### Gizli Veri & Sızıntı Tespiti\n- Kaynak kodda hardcoded API key, token, şifre tara\n- .env dosyaları .gitignore kapsamında mı?\n- Git geçmişinde accidental secret commit tara\n- Hata mesajları ve stack trace production\'da gizleniyor mu?\n- Browser DevTools üzerinden erişilebilir hassas veri tespiti',
|
||
injection:'### Injection Saldırıları — Kapsamlı Denetim\n\n**SQL Injection**\nTüm kullanıcı giriş noktalarını tara (form, URL param, header, cookie):\n- Classic: \' OR \'1\'=\'1 — string terminasyonu testi\n- Blind Boolean: AND 1=1 / AND 1=2 ile koşullu yanıt farkı\n- Time-based: SLEEP(5), WAITFOR DELAY ile gecikme testi\n- Error-based: EXTRACTVALUE(), UPDATEXML() ile hata mesajı sızdırma\n- Union-based: kolon sayısı tespiti ve veri exfiltration\n- ORM Bypass: raw query, format string birleştirme tespiti\n- Second-order: veritabanına yazılan, sonra çalıştırılan payload\n\n**NoSQL Injection**\n- MongoDB: $where, $gt, $ne, $regex operatör enjeksiyonu\n- Redis: KEYS *, FLUSHALL komut enjeksiyonu\n- Elasticsearch: script injection, aggregation manipulation\n\n**OS Command Injection**\n- exec(), system(), popen(), subprocess kullanımları\n- Payload: ; ls -la, | cat /etc/passwd, `id`, $(id)\n- Kontrol: shell=False, argüman listesi kullanımı\n\n**Template Injection (SSTI)**\n- Jinja2: {{7*7}}, motor tespiti ve RCE zinciri\n- Twig, Pebble, Velocity, Freemarker motor tespiti\n\n**LDAP & XPath Injection**\n- DN ve filter stringe özel karakter enjeksiyonu\n- XPath: \' or \'1\'=\'1 ile authentication bypass',
|
||
waf:'### Saldırı Tespiti & Önleme Mekanizmaları\n\n**WAF Denetimi**\n- WAF varlığını doğrula (ModSecurity, AWS WAF, Cloudflare)\n- OWASP CRS kural seti aktif mi?\n- Bypass senaryoları: encoding, case variation, fragmentation\n\n**Rate Limiting & Brute Force Önleme**\n- Login endpoint: IP ve hesap bazlı throttle var mı?\n- API endpoint bazında limit (örn. 100 req/min per IP)\n- Token bucket / sliding window algoritması\n- 429 yanıtında Retry-After header\n- CAPTCHA entegrasyonu (başarısız deneme eşiği)\n\n**Anomali Tespiti**\n- Olağandışı istek hacmi alerting\n- Coğrafi anomali: olağandışı bölge erişimi\n- User agent analizi: bot/scanner fingerprint\n- Honeypot endpoint: sahte endpointe erişim alarmı\n\n**DDoS Önleme**\n- Connection limit per IP (nginx: limit_conn)\n- Request size limit (max body, max header)\n- Slowloris koruması (keepalive timeout)\n\n**Input Sanitization Pipeline**\n- Tüm giriş noktaları için merkezi validation katmanı\n- Allowlist vs blocklist (allowlist tercih edilmeli)\n- Output encoding: context-aware (HTML, JS, URL, SQL)',
|
||
api:'### API Güvenliği\n- Rate limiting: endpoint bazında, IP ve kullanıcı bazlı throttling\n- Input validation: tip, uzunluk, format doğrulaması; allowlist yaklaşımı\n- GraphQL: introspection productionda kapalı mı? query depth/complexity limit?\n- Mass assignment: DTO whitelist, ORM güvenli property binding\n- Verb tampering: GET ile state değiştirme mümkün mü?\n- Pagination: keyset pagination güvenliği, offset injection riski',
|
||
bizlogic:'### İş Mantığı & Uygulama Katmanı\n- Race condition / TOCTOU: eşzamanlı istek ile bakiye/stok manipülasyonu\n- Negatif değer: fiyat alanına -100 ile kredi kazanma\n- Akış atlama: çok adımlı işlemlerde adım atlama (step 1 → step 3)\n- İş kural bypass: indirim kodu çoklu kullanım, referral loop\n- Parametre manipülasyonu: başkasına ait kaynak IDsi ile CRUD\n- Async işlem yarışı: webhooklar arası durum tutarsızlığı',
|
||
fileup:'### Dosya Yükleme Güvenliği\n- MIME type doğrulaması: Content-Typea güvenme, magic byte kontrolü\n- Uzantı whitelist: .jpg .png .pdf dışını reddet\n- Dosya boyutu limiti: frontend ve backendde zorunlu\n- Depolama yolu: web root dışına kaydet; path traversal önle\n- Antivirus tarama: yükleme sonrası otomatik tarama\n- Webshell tespiti: .php .jsp .aspx yüklenebiliyor mu?\n- Metadata sızdırma: EXIF verisi (GPS, cihaz bilgisi) temizleme',
|
||
crypto:'### Kriptografi & Şifreleme (Backend)\n- MD5/SHA1 kullanımını tespit et; SHA-256+ veya bcrypt/argon2 öner\n- AES-ECB modunu tespit et; GCM veya CBC+HMAC öner\n- RSA key uzunluğu: minimum 2048-bit\n- Math.random() güvenlik bağlamında kullanılıyor mu?\n- Key rotation politikası, HSM/KMS entegrasyonu\n- Sertifika geçerliliği ve pinning durumu',
|
||
sqli:'### SQL Injection — Derinlemesine Veritabanı Testi\n\n**Tespit Metodolojisi**\n1. Hata tabanlı: \' -- ve \' OR \'1\'=\'1\' --\n2. Boolean blind: AND 1=1 (true) vs AND 1=2 (false)\n3. Time-based blind: SLEEP(5) / pg_sleep(5) / WAITFOR DELAY\n4. Out-of-band: DNS/HTTP exfiltration\n\n**ORM Güvenlik Denetimi**\n- Django ORM: raw(), extra() kullanımları\n- SQLAlchemy: text() ile ham query, format string birleştirme\n- Sequelize: literal() kullanımı where clauseda\n- Hibernate: createNativeQuery() ile birleştirme\n- TypeORM: getRepository().query() raw kullanımı\n\n**Stored Procedure Güvenliği**\n- SP içindeki dinamik SQL: EXEC(@sql) pattern tespiti\n- SP parametrelerinin tiplendiğini doğrula\n\n**Araç**\n```bash\nsqlmap -u "https://target.com/api?id=1" --batch --level=3\ngrep -rn "raw(|text(|createNativeQuery" --include="*.py" .\n```',
|
||
nosqli:'### NoSQL Injection Denetimi\n\n**MongoDB**\n- Operatör injection: {"$gt":""}, {"$ne":null}, {"$where":"1==1"}\n- Auth bypass: {"username":{"$gt":""},"password":{"$gt":""}}\n- Mongoose: schema type enforcement; Mixed type kullanımından kaçın\n\n**Redis**\n- KEYS * ile keyspace enumeration\n- EVAL ile Lua script çalıştırma\n- CONFIG SET ile RCE riski\n- requirepass aktif mi?\n\n**Elasticsearch**\n- _search endpoint authentication zorunlu mu?\n- Script injection riski\n- Unlimited aggregation ile DoS',
|
||
dbaccess:'### Veritabanı Erişim Kontrolü\n- Least privilege: SELECT/INSERT/UPDATE yetkisi yeterli mi?\n- Rol ayrımı: readonly, readwrite, admin rolleri\n- PostgreSQL public schema erişimi kısıtlandı mı?\n- Row Level Security (RLS): çok kiracılı mimari\n- Connection string: şifre kaynak koduna gömülmüş mü?\n- Superuser bağlantı: postgres/root user ile bağlantı tespiti',
|
||
dbenc:'### Veri Şifreleme & Maskeleme\n- At-rest encryption: TDE aktif mi?\n- In-transit: SSL/TLS zorunlu mu? (sslmode=require)\n- Kolon bazlı şifreleme: TCKN, kart numarası — AES-256-GCM\n- PII maskeleme: log dosyalarında e-posta, telefon maskeleniyor mu?\n- Audit log: DML işlemleri loglanıyor mu?\n- Backup şifreleme ve off-site güvenliği\n- Key management: anahtarlar veritabanından ayrı mı?',
|
||
dbconf:'### Veritabanı Yapılandırma Güvenliği\n- Default credential: postgres/postgres, root/root testi\n- Public internet erişimi: 5432, 3306, 27017 açık mı?\n- Firewall: yalnızca uygulama sunucusu IPsine izin ver\n- trust authentication veya 0.0.0.0 binding tespiti\n- Gereksiz extension: xp_cmdshell devre dışı mı?\n- CVE patch durumu ve version güncelliği',
|
||
docker:'### Docker & Container Güvenliği\n- Root kullanıcı: USER nobody / USER 1001 kullanımı\n- Read-only filesystem: --read-only flag\n- Capability drop: --cap-drop ALL\n- no-new-privileges güvenlik flag\n- Image tarama: trivy ile CVE tarama\n- Secret yönetimi: ENV yerine Docker secrets / Vault\n- Network isolation: servis bazlı network\n- Distroless / minimal base image',
|
||
deps:'### Bağımlılık & Supply Chain Güvenliği\n- npm audit / pip-audit / trivy ile CVE önceliklendirme\n- Güncel olmayan major/minor versiyonlar\n- package-lock.json / poetry.lock commit edildi mi?\n- Typosquatting riski taşıyan paket isimleri\n- Lisans uyumsuzluğu: GPL contamination\n- GitHub Actions: third-party actionların pinned hash kullanımı',
|
||
network:'### Ağ Güvenliği & Firewall\n- Gereksiz açık port tespiti: nmap/netstat\n- Ingress/egress kısıtlaması\n- Network segmentasyon: veritabanı ayrı subnet\n- TLS 1.0/1.1 devre dışı mı? Güçlü cipher suite\n- VPN/bastion: doğrudan SSH erişimi kapalı mı?',
|
||
logging:'### Loglama, İzleme & Olay Müdahalesi\n- Kritik olaylar loglanıyor mu? (login failure, privilege change)\n- Log tampering koruması: append-only, log signing\n- Anomali tespiti: brute force, unusual access alerting\n- Log retention ve KVKK/GDPR uyumu\n- Incident response playbook varlığı'
|
||
};
|
||
|
||
var APP_LABELS = {
|
||
fullstack:'Full-stack web uygulaması', spa:'SPA (React/Vue/Angular)',
|
||
api:'REST/GraphQL API servisi', docker:'Docker/Container mimarisi', iot:'IoT/Edge uygulaması'
|
||
};
|
||
var OUT_LABELS = {
|
||
report:'Markdown formatında yapılandırılmış güvenlik raporu',
|
||
json:'JSON/SARIF formatında makine okunabilir çıktı',
|
||
pr:'Her bulgu için pull request açıklama şablonu',
|
||
fix:'Önceliklendirilmiş düzeltme adımları listesi'
|
||
};
|
||
var PRIO_LABELS = {
|
||
all:'Tüm seviyelerdeki bulgular',
|
||
critical:'Yalnızca Kritik (CVSS ≥ 9.0)',
|
||
high:'Kritik ve Yüksek (CVSS ≥ 7.0)'
|
||
};
|
||
|
||
var state = {
|
||
app:'fullstack', layer:'fe',
|
||
cats:{'owasp':1,'auth':1,'injection':1,'waf':1,'sqli':1,'nosqli':1,'dbaccess':1},
|
||
out:'report', prio:'all'
|
||
};
|
||
|
||
var ALL_IDS = Object.values(CATS).flat().map(function(c){return c.id;});
|
||
var TOTAL = ALL_IDS.length;
|
||
|
||
function allCatsList() { return Object.values(CATS).flat(); }
|
||
|
||
// PILLS
|
||
function bindPills(id, stateKey, cb) {
|
||
var cont = document.getElementById(id);
|
||
cont.querySelectorAll('.pill').forEach(function(btn) {
|
||
btn.classList.toggle('on', btn.getAttribute('data-v') === state[stateKey]);
|
||
btn.onclick = function() {
|
||
cont.querySelectorAll('.pill').forEach(function(b){b.classList.remove('on');});
|
||
btn.classList.add('on');
|
||
state[stateKey] = btn.getAttribute('data-v');
|
||
if (cb) cb();
|
||
renderPrompt();
|
||
};
|
||
});
|
||
}
|
||
|
||
// LAYER TABS
|
||
function renderLayerTabs() {
|
||
document.querySelectorAll('#layer-tabs .ltab').forEach(function(tab) {
|
||
var l = tab.getAttribute('data-l');
|
||
tab.classList.toggle('on', l === state.layer);
|
||
tab.onclick = function() {
|
||
state.layer = l;
|
||
renderLayerTabs();
|
||
renderCats();
|
||
};
|
||
});
|
||
}
|
||
|
||
// CAT GRID
|
||
function renderCats() {
|
||
var grid = document.getElementById('cat-grid');
|
||
grid.innerHTML = '';
|
||
var layer = state.layer;
|
||
CATS[layer].forEach(function(cat) {
|
||
var on = !!state.cats[cat.id];
|
||
var card = document.createElement('div');
|
||
card.className = 'ccard' + (on ? ' on' : '');
|
||
if (on) card.setAttribute('data-layer', layer);
|
||
var sevClass = cat.sev==='c'?'sev-c':cat.sev==='h'?'sev-h':'sev-m';
|
||
var sevTxt = cat.sev==='c'?'KRİTİK':cat.sev==='h'?'YÜKSEK':'ORTA';
|
||
card.innerHTML =
|
||
'<div class="ccheck"><svg viewBox="0 0 10 8" fill="none" stroke="white" stroke-width="2"><polyline points="1,4 3.5,7 9,1"/></svg></div>' +
|
||
'<div><div class="clbl">' + cat.lbl + '<span class="sev ' + sevClass + '">' + sevTxt + '</span></div>' +
|
||
'<div class="cdesc">' + cat.desc + '</div></div>';
|
||
card.onclick = function() {
|
||
if (state.cats[cat.id]) {
|
||
if (Object.keys(state.cats).length > 1) delete state.cats[cat.id];
|
||
} else {
|
||
state.cats[cat.id] = 1;
|
||
}
|
||
renderCats();
|
||
updateStats();
|
||
renderPrompt();
|
||
};
|
||
grid.appendChild(card);
|
||
});
|
||
updateProgress();
|
||
}
|
||
|
||
function updateProgress() {
|
||
var selected = Object.keys(state.cats).length;
|
||
var pct = Math.round(selected / TOTAL * 100);
|
||
document.getElementById('progress-fill').style.width = pct + '%';
|
||
document.getElementById('progress-txt').textContent = selected + ' / ' + TOTAL + ' kategori seçili';
|
||
}
|
||
|
||
// STATS
|
||
function updateStats() {
|
||
var all = allCatsList();
|
||
var chk = 0, tok = 400, layers = {};
|
||
Object.keys(state.cats).forEach(function(id) {
|
||
var cat = all.find(function(c){return c.id===id;});
|
||
if (!cat) return;
|
||
chk += cat.chk; tok += cat.tok;
|
||
Object.keys(CATS).forEach(function(k){
|
||
if (CATS[k].find(function(c){return c.id===id;})) layers[k]=1;
|
||
});
|
||
});
|
||
var n = Object.keys(state.cats).length;
|
||
document.getElementById('h-cat').textContent = n;
|
||
document.getElementById('h-chk').textContent = '~' + chk;
|
||
document.getElementById('h-lay').textContent = Object.keys(layers).length;
|
||
document.getElementById('h-tok').textContent = '~' + tok;
|
||
}
|
||
|
||
// BUILD PROMPT
|
||
function buildPrompt() {
|
||
var parts = Object.keys(state.cats).map(function(id){return TEXTS[id]||'';}).filter(Boolean);
|
||
if (!parts.length) return '';
|
||
return '# Web Uygulaması Güvenlik Denetimi — Ajan Talimatları\n\n' +
|
||
'## Görev\nSen uzman bir güvenlik mühendisisin. **' + APP_LABELS[state.app] + '** üzerinde kapsamlı güvenlik denetimi gerçekleştireceksin. Her bulgu için somut kanıt (dosya yolu, satır numarası, kod parçası) sunacaksın.\n\n' +
|
||
'- Uygulama türü: ' + APP_LABELS[state.app] + '\n' +
|
||
'- Öncelik filtresi: ' + PRIO_LABELS[state.prio] + '\n' +
|
||
'- Çıktı formatı: ' + OUT_LABELS[state.out] + '\n\n' +
|
||
'## Adım 1 — Keşif\nProje yapısını incele: dizin ağacı, bağımlılık dosyaları, Dockerfile, docker-compose.yml, CI/CD config, nginx/apache config, ORM model ve migration dosyaları.\n\n' +
|
||
'## Adım 2 — Otomatik Tarama\n```bash\nnpm audit --json 2>/dev/null || pip-audit --format json\ngrep -rn -E "(raw\\(|execute\\(|query\\(.*\\+|SLEEP\\(|WAITFOR)" --include="*.{js,ts,py}" .\ngrep -rn -E "SELECT.*\\+|WHERE.*\\+|INSERT.*\\+" --include="*.{py,js,ts,java,php}" .\ngrep -rn -E "\\$where|\\$gt.*req\\.|\\$ne.*req\\." --include="*.{js,ts}" .\ntrivy image <image_name> --severity HIGH,CRITICAL\n```\n\n' +
|
||
'## Adım 3 — Denetim Kategorileri\n\n' + parts.join('\n\n') + '\n\n' +
|
||
'## Bulgu Formatı\nHer bulgu için:\n- **Önem**: Kritik / Yüksek / Orta / Düşük\n- **CVSS Skoru**\n- **Katman**: Frontend / Backend / Veritabanı / Altyapı\n- **Konum**: `dosya/yolu:satır`\n- **Açıklama**: teknik detay\n- **Kanıt**: ilgili kod parçası\n- **Sömürü Senaryosu**: saldırgan nasıl kullanır?\n- **Düzeltme**: somut kod/config değişikliği\n- **Referans**: CVE / CWE / OWASP\n\n' +
|
||
'## Kurallar\n1. Gerçek kanıt olmadan bulgu raporlama\n2. Her kategoride en az 3 somut kontrol gerçekleştir\n3. Kritik bulgular için acil düzeltme adımlarını önceliklendir\n4. Injection bulgularında güvenli alternatif kod örneği ekle\n\n' +
|
||
'## Denetim Sonu\n- Bulgu özet tablosu (Kritik/Yüksek/Orta/Düşük × Katman matrisi)\n- Genel güvenlik puanı (0-100)\n- Kısa vadeli (≤1 hafta): acil patch\n- Orta vadeli (≤1 ay): mimari iyileştirmeler\n- Uzun vadeli: güvenlik olgunluk roadmap\n\n**Denetimi başlat. Önce keşif adımını tamamla ve proje yapısını özetle.**';
|
||
}
|
||
|
||
// RENDER PROMPT WITH SYNTAX HIGHLIGHT + LINE NUMBERS
|
||
function renderPrompt() {
|
||
var txt = buildPrompt();
|
||
var el = document.getElementById('prompt-output');
|
||
var lnEl = document.getElementById('line-numbers');
|
||
|
||
if (!txt) {
|
||
el.innerHTML = '<div class="empty"><div class="empty-icon">⚡</div><div class="empty-text">Sol panelden kategori seçin...</div></div>';
|
||
lnEl.innerHTML = '';
|
||
document.getElementById('line-count').textContent = '0 satır · 0 karakter';
|
||
return;
|
||
}
|
||
|
||
var lines = txt.split('\n');
|
||
var html = lines.map(function(line) {
|
||
var esc = line.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||
if (/^# /.test(line)) return '<span class="hl-h1">' + esc + '</span>';
|
||
if (/^## /.test(line)) return '<span class="hl-h2">' + esc + '</span>';
|
||
if (/^### /.test(line)) return '<span class="hl-h3">' + esc + '</span>';
|
||
if (/^```/.test(line)) return '<span class="hl-code">' + esc + '</span>';
|
||
esc = esc.replace(/\*\*([^*]+)\*\*/g, '<span class="hl-bold">**$1**</span>');
|
||
esc = esc.replace(/`([^`]+)`/g, '<span class="hl-code">`$1`</span>');
|
||
if (/^- /.test(line)) esc = '<span class="hl-dash">-</span>' + esc.slice(1);
|
||
return esc;
|
||
}).join('\n');
|
||
|
||
el.innerHTML = html;
|
||
|
||
// Line numbers
|
||
var numHtml = lines.map(function(_, i) {
|
||
return '<div class="line-num">' + (i+1) + '</div>';
|
||
}).join('');
|
||
lnEl.innerHTML = numHtml;
|
||
|
||
document.getElementById('line-count').textContent = lines.length + ' satır · ' + txt.length + ' karakter';
|
||
updateStats();
|
||
updateProgress();
|
||
}
|
||
|
||
// COPY
|
||
document.getElementById('btn-copy').onclick = function() {
|
||
var txt = buildPrompt();
|
||
if (!txt) { showToast('⚠ Önce kategori seçin'); return; }
|
||
navigator.clipboard.writeText(txt).then(function() {
|
||
showToast('✓ Prompt kopyalandı!');
|
||
}).catch(function() {
|
||
var ta = document.createElement('textarea');
|
||
ta.value = txt; document.body.appendChild(ta);
|
||
ta.select(); document.execCommand('copy');
|
||
document.body.removeChild(ta);
|
||
showToast('✓ Prompt kopyalandı!');
|
||
});
|
||
};
|
||
|
||
// MARKDOWN DOWNLOAD
|
||
document.getElementById('btn-md').onclick = function() {
|
||
var txt = buildPrompt();
|
||
if (!txt) { showToast('⚠ Önce kategori seçin'); return; }
|
||
var blob = new Blob([txt], {type: 'text/markdown;charset=utf-8'});
|
||
var url = URL.createObjectURL(blob);
|
||
var a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = 'security-audit-prompt-' + new Date().toISOString().slice(0,10) + '.md';
|
||
a.click();
|
||
URL.revokeObjectURL(url);
|
||
showToast('✓ Markdown indirildi!');
|
||
};
|
||
|
||
// PDF DOWNLOAD
|
||
document.getElementById('btn-pdf').onclick = function() {
|
||
var txt = buildPrompt();
|
||
if (!txt) { showToast('⚠ Önce kategori seçin'); return; }
|
||
try {
|
||
var jspdf = window.jspdf || (window.jsPDF ? {jsPDF: window.jsPDF} : null);
|
||
if (!jspdf && typeof jspdf === 'undefined') {
|
||
// fallback: print
|
||
var w = window.open('', '_blank');
|
||
w.document.write('<html><head><title>Security Audit Prompt</title><style>body{font-family:monospace;font-size:11px;line-height:1.7;padding:2rem;white-space:pre-wrap;}</style></head><body>' + txt.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>') + '</body></html>');
|
||
w.document.close(); w.print();
|
||
showToast('✓ Yazdırma diyaloğu açıldı');
|
||
return;
|
||
}
|
||
var doc = new jspdf.jsPDF({orientation:'p', unit:'mm', format:'a4'});
|
||
doc.setFont('courier', 'normal');
|
||
doc.setFontSize(8);
|
||
var lines = doc.splitTextToSize(txt, 180);
|
||
var y = 15, pageH = 285;
|
||
for (var i = 0; i < lines.length; i++) {
|
||
if (y > pageH) { doc.addPage(); y = 15; }
|
||
doc.text(lines[i], 15, y);
|
||
y += 4;
|
||
}
|
||
doc.save('security-audit-prompt-' + new Date().toISOString().slice(0,10) + '.pdf');
|
||
showToast('✓ PDF indirildi!');
|
||
} catch(e) {
|
||
showToast('⚠ PDF hatası, Markdown deneyin');
|
||
}
|
||
};
|
||
|
||
// RESET
|
||
document.getElementById('btn-reset').onclick = function() {
|
||
state.cats = {injection:1, sqli:1};
|
||
state.app = 'fullstack'; state.out = 'report'; state.prio = 'all';
|
||
bindPills('app-pills','app');
|
||
bindPills('out-pills','out');
|
||
bindPills('prio-pills','prio');
|
||
renderCats(); updateStats(); renderPrompt();
|
||
showToast('✓ Sıfırlandı');
|
||
};
|
||
|
||
// SELECT ALL
|
||
document.getElementById('all-btn').onclick = function() {
|
||
var allOn = ALL_IDS.every(function(id){return !!state.cats[id];});
|
||
state.cats = {};
|
||
if (!allOn) { ALL_IDS.forEach(function(id){state.cats[id]=1;}); }
|
||
else { state.cats = {injection:1,sqli:1}; }
|
||
renderCats(); updateStats(); renderPrompt();
|
||
};
|
||
|
||
// TOAST
|
||
function showToast(msg) {
|
||
var t = document.getElementById('toast');
|
||
t.textContent = msg;
|
||
t.classList.add('show');
|
||
setTimeout(function(){ t.classList.remove('show'); }, 2500);
|
||
}
|
||
|
||
// INIT
|
||
bindPills('app-pills','app');
|
||
bindPills('out-pills','out');
|
||
bindPills('prio-pills','prio');
|
||
renderLayerTabs();
|
||
renderCats();
|
||
updateStats();
|
||
renderPrompt();
|
||
</script>
|
||
</body>
|
||
</html>
|