Debug School

rakesh kumar
rakesh kumar

Posted on

How Websites Get Hacked: HTTP Requests, Scripts, Webshells, and Common Security Weaknesses Explained

Meta description: Understand how attackers abuse web requests, uploads, credentials, and vulnerable software, with safe code examples and practical PHP/Laravel defenses.

Suggested slug: how-websites-get-hacked-http-scripts-webshell-security

A website is usually compromised because a weakness allows an unauthorized action. The attacker might send requests from a browser, cURL, or a script. The tool is the delivery mechanism; the vulnerability is the weakness that makes an attack succeed.

The examples below use localhost, fake data, or defensive code. They are learning examples, not a complete security test suite. Responses are expected examples, not results observed on your server.

First Understand These Four Terms

Term Meaning Is it automatically malicious?
HTTP request A message sent to a web server No; every normal website uses requests
cURL A command-line tool for making requests and transferring data No; developers use it for testing
Script A program automating actions No; legitimate automation also uses scripts
Webshell Server-side code providing unauthorized remote control In this context, it is an attacker control mechanism

A scanner searches for weaknesses. It does not automatically compromise a site. A webshell usually appears after an attacker has already obtained a way to upload or write executable code.

1. Direct HTTP Requests: Bypassing the Visible Form

Scenario: An application hides an admin button but forgets to protect the backend endpoint. An attacker does not need to click that button; they can request the endpoint directly.

Harmless request to a local test server:

curl -i --max-time 5 http://127.0.0.1:8000/admin
Enter fullscreen mode Exit fullscreen mode

Expected protected behavior: a login redirect or a 401/403 response, depending on whether it is a browser page or API.

Protection: Enforce authentication and authorization on the server. Hidden buttons and JavaScript checks are only user-interface controls.

2. cURL: A Delivery Tool, Not a Vulnerability

Scenario: A client submits JSON without using your frontend. The server must validate it exactly as it validates a browser request.

curl -i --max-time 5 \
  -H 'Content-Type: application/json' \
  -d '{"title":"Example booking","quantity":2}' \
  http://127.0.0.1:8000/api/demo-bookings
Enter fullscreen mode Exit fullscreen mode

Syntax: -H adds a header; -d sends a body and normally selects POST; -i includes response headers. This example assumes you created the local demo endpoint.

Protection: Validate fields, verify ownership and permissions, and calculate trusted prices on the server. Restricting a User-Agent containing curl does not establish security because headers can be changed.

3. Scripts and Bots: Automating Requests

Scenario: Automation repeatedly exercises expensive endpoints. Without capacity controls, even valid requests may overwhelm resources.

Safe example making only one local health request:

from urllib.request import urlopen

with urlopen("http://127.0.0.1:8000/health", timeout=5) as response:
    print(response.status)
Enter fullscreen mode Exit fullscreen mode

Expected output for a healthy demo endpoint:

200
Enter fullscreen mode Exit fullscreen mode

Protection: Set rate limits, bounded queues, request deadlines, and per-account quotas. Rate limiting by IP alone may affect users sharing a network and can miss distributed abuse.

4. Login Abuse and Stolen Passwords

Scenario: Someone tries reused credentials obtained elsewhere. An application with no throttling or MFA is easier to abuse.

Laravel example of applying a configured rate limiter:

Route::post('/login', [LoginController::class, 'store'])
    ->middleware('throttle:login');
Enter fullscreen mode Exit fullscreen mode

This assumes a named login limiter is defined in your application's rate-limiter configuration.

Expected response after the limit is reached:

429 Too Many Requests
Enter fullscreen mode Exit fullscreen mode

Protection: MFA, secure password hashing, careful throttling, generic failure messages, and monitoring. Use fake accounts when testing. Do not log submitted passwords.

5. SQL Injection: Input Becomes Database Instructions

Scenario: A developer concatenates input into a SQL statement. The database may interpret input as query syntax rather than a value.

Defensive Laravel example:

$user = DB::selectOne(
    'SELECT id, name FROM users WHERE email = ?',
    [$request->input('email')]
);
Enter fullscreen mode Exit fullscreen mode

The placeholder binds email as data. Expected result: one matching row or no matching row; user input does not become additional SQL instructions.

Protection: Parameterized queries and least-privilege database accounts. Bound parameters do not replace authorization, and dynamic column/table names require separate allowlists.

6. Cross-Site Scripting: Untrusted Content Reaches a Browser

Scenario: A public comment is inserted into HTML without appropriate escaping. Untrusted content could run in another user's browser.

Safe Blade text output:

<p>{{ $comment->body }}</p>
Enter fullscreen mode Exit fullscreen mode

If a user submits <b>Hello</b>, ordinary escaped text output displays the characters rather than interpreting them as markup.

Protection: Context-appropriate output encoding, sanitization when allowing rich HTML, and a suitable Content Security Policy. HTML escaping alone is not sufficient for every JavaScript, CSS, or URL context.

7. Broken Access Control: Reading Another User's Booking

Scenario: A logged-in user changes a booking identifier. If the API checks only that they are logged in, it may disclose another person's booking.

Defensive ownership check:

$booking = Booking::query()
    ->where('user_id', $request->user()->id)
    ->findOrFail($bookingId);
Enter fullscreen mode Exit fullscreen mode

Expected result: the owner's booking is returned; another user's identifier produces 404. Applications with organizer/admin sharing should use an appropriate authorization policy instead of this simplified rule.

Protection: Check permissions for every object and action. Unpredictable IDs help reduce guessing but do not substitute for authorization.

8. Unsafe Uploads and Webshells

Scenario: An attacker finds a way to place server-executable code in a web-accessible directory. If the server executes it, it can become a webshell.

Harmless defensive upload example:

$request->validate([
    'document' => ['required', 'file', 'mimes:pdf,txt', 'max:5120'],
]);

$path = $request->file('document')->store('contracts', 'local');
Enter fullscreen mode Exit fullscreen mode

Verify that this disk is actually private in your application's filesystem configuration. max:5120 is a 5,120 KiB Laravel file-size rule.

Expected behavior: an allowed document is stored privately under a generated path; forbidden types are rejected. MIME validation cannot prove a parser will safely process every file.

Protection: Private storage, non-executable upload paths, generated filenames, parser isolation, and patched libraries. A sample executable webshell is unnecessary for understanding or testing these controls.

Read-only review example for unexpected PHP files in a known upload directory:

find /srv/myapp/storage/app/uploads -type f -iname '*.php' -print
Enter fullscreen mode Exit fullscreen mode

This is an indicator search, not proof of compromise or a comprehensive scanner. Preserve suspicious files and evidence rather than executing them.

9. OS Command Injection: Input Becomes a Shell Command

Scenario: An application builds a shell command by joining a utility name with user-supplied text. Shell operators in that input may change what executes.

Defensive Python example:

import subprocess

result = subprocess.run(
    ["/usr/bin/printf", "%s", "sample-report.pdf"],
    check=True,
    capture_output=True,
    text=True,
    timeout=5,
)
print(result.stdout)
Enter fullscreen mode Exit fullscreen mode

Expected output:

sample-report.pdf
Enter fullscreen mode Exit fullscreen mode

An argument list avoids shell interpretation here. Real external programs can still interpret dangerous options or input; validate arguments and use a fixed executable. Prefer native library operations where possible.

10. Path Traversal: Accessing Files Outside the Intended Folder

Scenario: A download endpoint accepts arbitrary filesystem paths. An attacker could try to access configuration or secret files.

Defensive design using a server-managed ID:

$document = Document::findOrFail($documentId);
$this->authorize('view', $document);
return Storage::disk('local')->download($document->storage_path);
Enter fullscreen mode Exit fullscreen mode

Expected behavior: only an authorized document is returned. The stored path must be generated and controlled by the server, not blindly copied from client input.

Protection: Map IDs to approved paths, enforce ownership, and carefully validate canonical paths if accepting any path input. Removing one ../ substring is not a complete solution.

11. Exposed Secrets and Debug Information

Scenario: A web root exposes .env, backups, source repositories, or logs. No code-execution exploit is needed if a password can simply be downloaded.

Laravel production setting:

APP_ENV=production
APP_DEBUG=false
Enter fullscreen mode Exit fullscreen mode

Apache document-root example:

DocumentRoot /srv/myapp/public
Enter fullscreen mode Exit fullscreen mode

Expected behavior: application source and private configuration remain outside the public document root. Check aliases, symlinks, backups, and cached configuration as well.

Protection: Restrict access and rotate any exposed credentials. Hiding an error page or version header does not fix a vulnerable application.

12. Runtime and Dependency Vulnerabilities

Scenario: A runtime or library has an implementation bug. A crafted request or file reaches that vulnerable code path, potentially before application checks.

Version inventory examples:

php -v
php-fpm8.4 -v
composer audit
Enter fullscreen mode Exit fullscreen mode

These do different jobs: version commands inventory binaries; Composer audit checks known dependency advisories. None proves every deployed component is secure. CLI PHP and FPM may be different runtimes.

Protection: Verify official advisories, install supported fixed versions, test compatibility, and ensure serving workers actually load the update. A WAF or Laravel validation is not a substitute for a runtime patch.

13. Resource Exhaustion: Keeping the Server Too Busy

Scenario: Many costly searches or document jobs consume memory, CPU, disk, or database connections.

Illustrative pool limit:

pm = ondemand
pm.max_children = 3
Enter fullscreen mode Exit fullscreen mode

This bounds that pool's PHP workers, not total host memory or all request volume. Expected behavior under saturation: requests queue or time out according to configured backlog and server behavior.

Protection: Request size limits, rate limits, processing deadlines, bounded queues, pagination, concurrency controls, and host-capacity planning. Test small controlled workloads in staging rather than generating an uncontrolled flood.

14. CSRF: An Unwanted Action Using a Browser Session

Scenario: A site relies on browser cookies for authentication but does not verify that a state-changing request originated through its protected flow.

Laravel Blade form:

<form method="POST" action="/profile">
    @csrf
    <input name="display_name" value="Example">
    <button type="submit">Save</button>
</form>
Enter fullscreen mode Exit fullscreen mode

The token is effective only when the relevant CSRF middleware verifies it. Expected behavior: a missing/invalid token is rejected by that flow. API token authentication and browser cookie authentication require different design considerations.

15. SSRF: Making Your Server Request an Unwanted Destination

Scenario: A preview service fetches any URL supplied by a user. It could be abused to access internal services using the server's network position.

A defensive interface can accept predefined sources rather than arbitrary URLs:

SOURCES = {"help": "https://example.com/help"}
source_id = "help"
url = SOURCES[source_id]
Enter fullscreen mode Exit fullscreen mode

Expected result: the selected URL comes from an approved mapping. Real fetchers still need network egress controls, redirect policy, destination/IP validation, and limits. A hostname check alone may be insufficient.

Example Relationship Between the Methods

A script can send HTTP requests through cURL or a programming library. If an upload vulnerability allows executable code to be written, a webshell may provide later control. If permissions are broad, the compromised process might access more files and credentials. This is a possible sequence, not an inevitable result of receiving a request.

Practical Defense Checklist

  • Patch the real web runtime and application dependencies.
  • Enforce authentication and per-resource authorization.
  • Validate input and use safe database and process APIs.
  • Keep secrets and source code outside public storage.
  • Prevent uploads from executing; isolate risky file parsers.
  • Use restricted users and separate credentials for services.
  • Bound request sizes, processing time, queues, and concurrency.
  • Protect sessions and browser forms appropriately.
  • Monitor suspicious patterns and preserve incident evidence.
  • Maintain tested backups and restore procedures.

References

Colourful Architecture: Delivery, Weakness, Impact, and Defense

Top comments (0)