⬡ Attack Surface Map
The complaint form at /mp-portal/ includes a file upload field for "तस्विर वा कागजात" (Photo or Document). The HTML input has NO accept="" attribute restriction, meaning any file type can be selected and submitted. If the backend does not enforce strict MIME type validation and stores files inside the web root with their original extension, an attacker can upload a PHP/ASP/JSP shell script disguised as an image. When the server processes or serves that file, the script executes — giving the attacker full remote code execution on the web server.
accept="image/jpeg,image/png,image/webp,application/pdf" to the input (defense-in-depth only).2. Server-side: Validate MIME type using file magic bytes — NOT the extension or Content-Type header.
3. Store uploads OUTSIDE web root (e.g.,
/var/uploads/ not /var/www/html/uploads/).4. Rename uploaded files to a random UUID — never use the original filename.
5. Serve files via a controller that streams the file, never direct URL access.
6. Set max file size limit (e.g., 5MB) on both client and server.
The complaint form contains two free-text input areas: "गुनासो विवरण" (complaint description) and "सम्पर्क" (contact info). If these values are stored in a database and later displayed in an admin panel or public dashboard without HTML encoding/sanitization, any JavaScript injected by an attacker will execute in the admin's browser. This is Stored (Persistent) XSS — one of the most dangerous XSS variants because it targets privileged users like administrators, not random visitors.
< → <, > → >, " → " before rendering.2. Use a server-side sanitization library (e.g., DOMPurify on Node, HTMLPurifier on PHP).
3. Implement a strict Content Security Policy (CSP) header:
Content-Security-Policy: default-src 'self'; script-src 'self'4. Set
HttpOnly and Secure flags on all session cookies so they can't be stolen via JS.5. Validate input on server: reject or strip HTML tags from plain-text fields.
The /mulyankan/ (People's Assessment) page allows users to cast 👍/👎 votes on government actions. There is zero authentication required — no login, no phone verification, no CAPTCHA. The only defense (if any) would be a cookie or IP-based check, both of which are trivially bypassed. A single attacker or bot can cast thousands of votes in minutes, completely poisoning the civic data that this platform claims represents public opinion on government performance.
2. If anonymous voting is required: use signed, single-use tokens (UUID stored in DB) — one per browser session.
3. Implement server-side rate limiting: max 1 vote per IP per action per hour.
4. Add CAPTCHA (Google reCAPTCHA v3 invisible) before vote submission.
5. Flag anomalous voting patterns (e.g., 100+ votes/minute from same subnet) and quarantine them.
The complaint form does not use a traditional HTML <form> tag and likely submits via JavaScript fetch. There is no visible CSRF token in the page HTML. Without a CSRF token, any malicious third-party website can trick a user's browser into silently submitting a fake complaint on their behalf — using their session/cookies — without their knowledge. For a civic platform where complaint authenticity matters, this is serious.
X-CSRF-Token). Validate it on every POST. Also set SameSite=Strict on session cookies.
The complaint form prominently displays: "🔒 तपाईंको गुनासो गोप्य र बेनामी रहनेछ। / Your complaint is confidential and anonymous." However, the optional "सम्पर्क" (Contact) field collects personal information. More critically, web servers by default log the IP address of every request — including complaint submissions. If the server stores both the complaint content and the requester's IP (which it does unless explicitly configured not to), anonymity is technically impossible. This is a deceptive privacy claim that could expose political complainants in Nepal to real-world harm.
Option B — Honest language: replace "anonymous" with "confidential — your identity is protected to the extent possible but submissions may be linked to your IP by server infrastructure."
Based on the site's structure (likely a static/CMS host without explicit header configuration), critical HTTP security headers are expected to be missing. These headers are the browser's first line of defense against XSS, clickjacking, MIME sniffing, and protocol downgrade attacks. Their absence leaves every user of the platform exposed.
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; object-src 'none'X-Frame-Options: DENYX-Content-Type-Options: nosniffStrict-Transport-Security: max-age=31536000; includeSubDomainsReferrer-Policy: strict-origin-when-cross-originVerify at: securityheaders.com
The complaint endpoint at /mp-portal/ accepts unauthenticated POST requests with no visible rate limiting. An attacker can flood the endpoint with thousands of fake complaints per second — either to spam/pollute the complaint database, exhaust server resources (DoS), or bury legitimate complaints with noise. Since the "success" state shows regardless of server response, the attacker gets no feedback to slow them down.
The site loads commitment, MP, and voting data from backend API endpoints (likely /api/commitments, /api/mps, /api/votes). These appear to be unauthenticated public endpoints. Without rate limiting or pagination guards, a single script can bulk-scrape the entire dataset — including 275 MP profiles, all complaints, and vote tallies — in seconds. Sensitive MP data or unmoderated complaint content could be exposed.
The constituency map at /mp-portal/ appears to be an inline SVG (or canvas) rendered directly in the DOM. Inline SVGs support JavaScript event handlers (onload, onclick, etc.). If the SVG map data is fetched from an API or user-influenced source without sanitization, an injected SVG payload could execute JavaScript. Additionally, SVG files accepted as "evidence uploads" in the complaint form are a known XSS vector — SVGs can contain embedded <script> tags.
2. If rendering inline SVG from an API, sanitize it server-side with a strict SVG allowlist (DOMPurify with SVG config).
3. Serve SVG files as
Content-Type: image/svg+xml from a sandboxed domain, not inline.
The MP profile popup contains a link: [📋 विस्तृत प्रोफाइल](#) — a placeholder anchor pointing to #. Without X-Frame-Options: DENY, the entire site can be embedded in an iframe on a malicious page. An attacker overlays invisible buttons over real UI elements to trick users into clicking (e.g., submitting a pre-filled complaint or casting a vote) without their knowledge — a classic clickjacking attack.
X-Frame-Options: DENY HTTP header (covered in SEC-006). Also add CSP: frame-ancestors 'none'. Replace all href="#" placeholder links — they also cause page-jump UX bugs.
MP photo rendered as <img src="" alt="MP Photo">. Some older browsers send a GET request to the current page URL when src is empty, causing an extra unintended HTTP request and possible request loop.
img[src=""] { display: none } via CSS.The commitment modal contains 𝕏 (Twitter), Facebook, and link share buttons. If the shared URL contains tracking parameters, complaint IDs, or session-related query strings, sharing could expose internal identifiers to third-party platforms. Referrer header leakage is also possible without a strict Referrer-Policy.
Referrer-Policy: no-referrer to headers. Audit what parameters are included in share links.If any JavaScript libraries are loaded from external CDNs without Subresource Integrity (SRI) hashes, a compromised CDN could serve malicious JS to all visitors. This is a supply-chain attack vector.
integrity="sha384-..." and crossorigin="anonymous" to all external <script> and <link> tags. Generate hashes at: srihash.orgThe site collects complaint data (potentially with contact info and file uploads) with no visible privacy policy page, data retention period, or disclosure of what happens to submitted data. This is both a legal compliance issue and a trust concern for a civic accountability platform.