HTTP Requests: Practical Guide to GET, POST, WebSocket, and Low-Level Testing

Understanding how to craft and manipulate HTTP requests is essential for web security testing, API interaction, and reconnaissance. Whether you're using curl, Python's requests library, or low-level tools like telnet and OpenSSL, mastering these techniques allows you to interact with web services at every level - from simple GET requests to encrypted HTTPS and WebSocket connections.

This guide covers practical methods for sending HTTP requests, uploading files, handling cookies and headers, and testing encrypted and real-time communication - all critical for mapping and reducing your organization's attack surface.

GET Requests

Using curl

Always wrap URLs in quotes to avoid shell interpretation issues:

curl "http://example.com"

Add custom headers and cookies:

curl "http://example.com" \
-H "Content-Type: application/json" \
--cookie "sessionid=abc123"

Using Python (requests)

import requests

cookies = dict(sessionid='abc123')
headers = {"Content-Type": "application/json"}
r = requests.get("http://example.com", cookies=cookies, headers=headers)
print(r.text)

POST Requests

Using curl

Explicit POST with headers and form data:

curl -X POST http://example.com \
-H "Content-Length: 10" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "key=value"

Alternatively, using --data automatically sets the method to POST:

curl http://example.com --data "key=value"

For JSON payloads (ensure proper escaping):

curl http://example.com \
-H "Content-Type: application/json" \
-d "{\"key\": \"value\"}"

Note: JSON uses ASCII characters; special symbols must be escaped.

HTML Encoding

When injecting into HTML contexts, encode special characters:

  • " -> "
  • < -> &lt;
  • > -> &gt;

File Uploads

Use -F to simulate multipart form uploads:

curl -F "upload=@localfile.txt;filename=../../malicious.txt" http://example.com/upload
  • First filename: local file to read.
  • Second filename: name sent in the HTTP request (can be used for path traversal).

Using Python (requests)

import requests

cookies = dict(key="value")
headers = {"Content-Type": "application/x-www-form-urlencoded"}
data = {'key': 'value'}
r = requests.post("http://example.com", cookies=cookies, headers=headers, data=data)
print(r.text)

WebSocket Communication

WebSockets enable real-time, bidirectional communication. You can test them directly in the browser:

This connects to a WebSocket server, sends a message on open, and displays incoming messages.

Telnet to Port 80 (Raw HTTP)

Use telnet to manually send HTTP requests:

telnet example.com 80

Once connected:

GET / HTTP/1.1
HOST: example.com

Press Enter twice to send the request. This method helps understand raw HTTP and bypass tools that abstract the protocol.

HTTPS Requests with OpenSSL

To interact with HTTPS services at the TLS level:

openssl s_client -connect example.com:443

After establishing the TLS handshake, you can manually send:

GET / HTTP/1.1
Host: example.com

This is useful for testing SSL/TLS configurations, certificate chains, and debugging encrypted services.

Security Impact: Mapping the Attack Surface

As defined by Wikipedia, the attack surface is the sum of all entry points where an attacker can interact with a system - including HTTP endpoints, APIs, WebSockets, and file upload forms.

Every HTTP request you craft reveals potential vulnerabilities:

  • Unvalidated input -> XSS, SQLi
  • Insecure file uploads -> RCE
  • Exposed WebSocket endpoints -> data leakage
  • Missing security headers -> session hijacking

Tools like Shodan help identify internet-facing web servers, but only manual testing with curl, Python, or raw sockets can uncover the logic flaws and injection points hidden behind them.

Implementing an Attack Surface Management (ASM) program ensures continuous discovery and hardening of all HTTP-accessible endpoints before they are exploited.

See Also

Published on Aug 21, 2025