---
title: "Testing Your Own Website's Defenses With Permission: The Basics"
url: https://phatdev.net/en/blog/authorized-web-pentest-basics
lang: en
updated: 2026-10-21
alternate:
  vi: https://phatdev.net/vi/blog/authorized-web-pentest-basics
markdown: https://phatdev.net/en/blog/authorized-web-pentest-basics.md
---

# Testing Your Own Website's Defenses With Permission: The Basics

> How to legally test your own website's defenses: permission and scope, a five-step process, testing permissions with two accounts, and writing a report others can act on.

Categories: Security | Published: 2026-10-19 | Level: Beginner | 6 min read

Tags: pentest, owasp, idor, zap, burp, nuclei, scope, reporting

A shop owner gets a strange email: "I found a hole in your website. Send money and I'll tell you where." Permitted penetration testing exists to avoid that scene. The idea is simple: invite someone to play the attacker, inside an agreed scope and time window, to find weak spots before a real attacker does. The whole thing hinges on the word "permitted".

This post covers the process at a basic level and **applies only to your own systems, or systems you hold a written contract or permission for**. I do not explain how to attack anyone else's system and I do not include exploit code. Every test here ran against a sample app I wrote, deliberately flawed, on my own machine.

![A permitted-scope ring with app blocks inside, out-of-scope blocks fenced off, and a stamped permission slip](https://phatdev.net/uploads/blog/authorized-web-pentest-basics/scope-1920.webp)

## Step 0: permission and scope

Before typing the first command, get a document signed by someone with authority over the system. People in the trade call it the Rules of Engagement, roughly an agreement on how the work will be done. It states five things. Scope: which domains and applications may be tested, and what may not, such as a third party's payment system or the hosting provider's shared services. Time: the dates and hours allowed, avoiding peak traffic. Type of testing: whether overloading the system is allowed (usually no), whether real accounts may be used, whether data may be written or deleted. Emergency contact: who to call right away if the system slows down or something serious turns up. And data handling: if you accidentally touch real data, stop, note it, report it, and do not copy it.

If the app sits on a cloud or hosting provider, read their testing policy. Unauthorised access to someone else's system is illegal almost everywhere, and "I was only looking" is not an accepted reason.

I have a habit of turning scope into code: a small script reads the scope file and refuses to send a request if the host, time, method or path is outside it. Without that gate, automated tools easily wander onto an out-of-scope host by following a link or a redirect. I re-ran it today with a sample scope file:

```python
def check_request(scope, method, url, today=None):
    # (the valid_from..valid_until date check sits at the top, trimmed here for brevity)
    u = urlparse(url)
    if u.netloc not in scope['in_scope_hosts']:
        raise OutOfScope(f'host {u.netloc} is not in scope')
    if any(u.path.startswith(p) for p in scope['out_of_scope_paths']):
        raise OutOfScope(f'path {u.path} is excluded')
    if method.upper() not in scope['allowed_methods']:
        raise OutOfScope(f'method {method} is not allowed')
```

```
ALLOW GET http://127.0.0.1:4100/
BLOCK GET http://example.org/                       -> host example.org is not in scope
BLOCK GET http://127.0.0.1:4100/admin/delete-all    -> path /admin/delete-all is excluded
BLOCK POST http://127.0.0.1:4100/login              -> method POST is not allowed
BLOCK (date 05/11) -> outside the permitted time window
```

## How to do it: the five-step process

![A four-stage improvement loop: find, report, fix, re-check](https://phatdev.net/uploads/blog/authorized-web-pentest-basics/cycle-1920.webp)

Step one is learning about the target without touching it: public pages, the technology in use, `robots.txt`, `sitemap.xml`, the HTTPS certificate. The aim is a map of features, kinds of users and APIs.

Step two is checking configuration: security headers, cookie flags, sensitive files, error pages, leaked software versions. Machines do this part well. I used the same self-check script from [Self-Check Your Website's Security with the OWASP Top 10 (2025)](https://phatdev.net/en/blog/owasp-top10-audit-checklist): on the deliberately weak sample app it reports 13 failures, and on the fixed version none.

Step three is sign-in and sessions: is there a limit on wrong attempts, is password reset safe, does the session ID change after login, is the login token checked for signature, expiry and audience (see [A Shared JWT Login Token for Node.js, PHP, Python and C#](https://phatdev.net/en/blog/jwt-across-languages)).

Step four is permissions. A common flaw is called IDOR: a user changes an ID number in a request to read someone else's data. The basic test uses two test accounts: take account B's resource ID and call it with account A's session. I re-ran this on the sample app:

```
                                        weak version    fixed version
alice reads alice's order (id 1)             200             200
alice reads bob's order   (id 2)             200             404   <- flaw in the weak version
signed-out read of order  (id 2)             401             401
```

The pass rule is simple: every pair of (user, resource that is not theirs) must be refused.

Step five is what users type in. Check whether it gets glued straight into a query, a command or an HTML page. At a basic level, try a single apostrophe in the input fields on a test environment and watch for odd errors. The fix is parameterised queries and encoding output, as run in the OWASP post. I leave exploit code out, because the goal is to find and fix.

Beyond these five steps sit **business logic flaws**, like reusing a discount code or skipping the payment step. Machines almost never see these. It takes someone who understands the business to sit down and try.

## Common defensive tools

I did not run these tools for this post, so I describe roles only and report no results. OWASP ZAP is both an intercepting proxy and an automated scanner; its "baseline" mode scans passively and suits CI, while active scans send a lot of requests and belong on a test environment. Burp Suite Community is a proxy for viewing, editing and replaying requests by hand, very good for permission and logic testing. nuclei scans with YAML templates for misconfigurations and known flaws; read the template and limit the rate before running it.

Whatever you use, tool output is a hint, not a finding. Verify by hand to weed out false alarms, because tools do not understand the business and will miss a lot.

## Writing a report people can act on

A good report lets a developer fix things without guessing. Each finding should follow this shape:

```markdown
### F-03: IDOR on GET /api/orders/{id}
- Severity: High (another user's order can be read)
- Description: the API checks that you are signed in, not that you own the order.
- Steps to reproduce (staging, 2 test accounts): call the API with A's session and B's order id.
- Evidence: response code 200, the total field; personal data masked.
- Impact: every customer's order details are exposed.
- Fix: check owner == caller in the query itself, return 404 on mismatch.
- Reference: OWASP A01:2025 Broken Access Control.
```

Order the findings by severity, state clearly what was checked and passed, mask sensitive data in the evidence, and store the report as a confidential document. Most important is the last loop: after the fix, re-test exactly the cases you reported. For the web server side of the fixes, see [Making Your Nginx Website Safer, Step by Step](https://phatdev.net/en/blog/nginx-web-hardening).

## Mistakes I see

I often see work start before permission exists, or a scope so vague nobody knows what may be tested. Heavy scanning at peak hours is familiar too, along with spilling onto a third party's payment gateway or embedded service. Some reports are just pasted tool output that nobody verified, and after the fix nobody re-checks.

## What to do next

If you want an outsider to test your system, first write the five-point agreement from step 0, then run one round yourself with two test accounts to clear the easy problems. That way the money you pay the tester goes toward hard findings instead of ones visible at a glance. If you need someone to do this for your website, get in touch and I am happy to talk it through.

## References

- [OWASP Web Security Testing Guide (WSTG)](https://owasp.org/www-project-web-security-testing-guide/)
- [NIST SP 800-115 - Technical Guide to Information Security Testing and Assessment](https://csrc.nist.gov/pubs/sp/800/115/final)
- [OWASP ZAP](https://www.zaproxy.org/)
- [PortSwigger - Burp Suite Community Edition](https://portswigger.net/burp/communitydownload)
- [ProjectDiscovery - nuclei](https://docs.projectdiscovery.io/tools/nuclei/overview)
- [OWASP Top 10:2025 - A01 Broken Access Control](https://top10.owasp.org/2025)

## Related posts

- [Self-Check Your Website's Security with the OWASP Top 10 (2025)](https://phatdev.net/en/blog/owasp-top10-audit-checklist.md)
- [Making Your Nginx Website Safer, Step by Step](https://phatdev.net/en/blog/nginx-web-hardening.md)
- [A Shared JWT Login Token for Node.js, PHP, Python and C#](https://phatdev.net/en/blog/jwt-across-languages.md)
