Cyberlium

Python › Module 2 › Lesson 2

BeginnerModule 2Lesson 2/5

HTTP Requests (requests library)

Fetch URLs, inspect status codes and headers, and use requests for defensive checks

15 min+21 XP3 quiz
Module progress2 of 5
https://🔒
HTTP GET · Status · Headers

Opening

Defenders speak HTTP every day — one GET with a timeout is a health check, not a password cannon.

Is the site up? Did it redirect to HTTPS? What Server string did it advertise? Does Content-Security-Policy exist on a page you own? Those are boring, high-value questions. The Python requests library turns them into a few lines: get or head, timeout=, then status_code and headers. The same library can be abused to spray login forms. This course uses it the first way only. You will GET or HEAD https://example.com (IANA’s documentation site, intended for examples) or a local server you start on YOUR machine (python -m http.server). You will not attack, not send SQLi payloads, not credential-stuff, not brute a “practice” bank. timeout= is mandatory so a hung path fails instead of freezing your script. Next lesson designs a port scanner — still 127.0.0.1 only. Carry the socket rule: other people’s networks are not your lab.

1. GET fetches a representation; HEAD asks for headers without the body

HTTP methods are verbs. GET asks a server for the resource at a URL. A successful GET to https://example.com typically returns 200 and an HTML body — enough to confirm “this host answered HTTP(S) for this path.” HEAD asks for the same metadata (status, headers) without transferring the body. HEAD is the lighter health check when you only need status and headers. requests.get(url, timeout=5) and requests.head(url, timeout=5) are the two calls you need for this lesson. You are not learning POST login, not crafting Transfer-Encoding tricks, not fuzzing. A third-party site that is not example.com and not a server you run is out of scope even if GET “is harmless.” Harmless-looking GETs at scale are still someone else’s logs and sometimes against their terms. One documented example host, or localhost, is the classroom.

Install once on the machine you administer: pip install requests (or pip3 / py -m pip). That installs a library into YOUR Python environment — not a scanner appliance, not a Magisk module, not permission to hit production. After import requests, every call still needs timeout=. Follow redirects only when you intend to (allow_redirects=True is the default for GET). For a defensive “did they send me to HTTPS?” check on a site you own, you may inspect r.url and r.history. For example.com, print status and a couple of headers and stop. Do not write a crawler. Do not download every path.

2. Status codes are a map, not a score: 200, 301, 403, 404

200 OK means the request succeeded and the server is sending a representation of the resource — “the page is here” from this vantage point, not “the site is secure.” 301 Moved Permanently (and 302 Found) means a redirect; look at the Location header and, if you followed redirects, the final r.url. A site you own that still serves http:// and never 301s to https:// is a defensive finding you can write down. 403 Forbidden means the server understood the request and refuses to authorize it — not an invitation to bypass. 404 Not Found means no resource at that path. None of these codes authorize a second tool, a wordlist, or a SQL payload. 401/403 on a login form especially does not mean “try 10,000 passwords.”

Read the number, write one sentence of meaning, stop. A monitoring script on YOUR staging site might alert if status leaves the 2xx/3xx set you expect. A classroom GET to example.com should print 200 (or whatever example.com returns today) and move on. Do not loop paths looking for hidden admin panels. Do not treat 403 as a puzzle. This is observation of a willing example host or of a process you started, not vulnerability research on strangers.

3. Headers Server and CSP are defensive notes on YOUR site or example.com — not fingerprints for an attack plan

Response headers are metadata. Server may advertise software (or be omitted or generically named — both are data). Content-Security-Policy (CSP) is a browser-side restriction policy; its presence or absence on a site you own is a hardening signal you can record. Strict-Transport-Security (HSTS) tells browsers to stick to HTTPS. On YOUR site or lab app, missing HSTS or a surprising Server string is a ticket, not a hack. On example.com, you print r.headers.get("server") and r.headers.get("content-security-policy") (or strict-transport-security) so you practice the API. You do not use those strings to pick exploits. You do not scan the internet for “Server: apache” banners. Observation of a single allowed URL is literacy. Banner databases aimed at strangers are not this lesson.

r.headers is a case-insensitive mapping. .get("server") returns None if absent — that is a valid finding. Do not disable TLS verification. verify=False makes HTTPS lie to you and is not a classroom default. If a lab VM uses a homemade cert, fix trust on that VM; do not teach “just verify False.” timeout= still applies to TLS handshake delays. Keep the body out of shared notes if it could contain cookies; this lesson should not need cookies at all.

4. timeout= is mandatory; never brute a login form — GET is not credential stuffing

requests without timeout= can hang forever if the server never completes. In a loop that is a stuck SOC script. Always pass timeout=5 (seconds) or a tuple (connect timeout, read timeout). That is the same lesson as socket settimeout: fail instead of freeze. The other hard rule: do not POST to /login with password lists, do not spray default creds, do not send injection strings in query parameters, and do not “test SQLi” on example.com or on a school portal. Those are attacks. If you need a form to practice later, you will build YOUR own local Flask/Django app in a different, authorized lab — not this module.

pip install requests on YOUR machine is in-scope. Hitting a production login “because I have the library now” is how people get banned, fired, or charged. The legal line is identical to sockets: example.com as a single documented GET/HEAD, or a server bound on your loopback. Not café captive portals. Not the ISP’s router UI. Not a random internet host.

5. Wrong vs right: stuffing a login vs one timed GET to example.com (or YOUR local server)

Worked failure — same requests library, opposite intent. Right is one defensive GET/HEAD, never a wordlist.

  • Wrong

    POST passwords at a school portal, a bank, or a “test” site you do not own. Send SQLi payloads in query strings. Disable verify=False to silence warnings. Omit timeout and let the process hang. Crawl every path looking for /admin. Use Server headers to pick CVEs against strangers. Hit a café captive portal 1,000 times. Credential stuffing, even with “only 10 passwords,” is still stuffing. This course does not teach bypasses or login spray.

  • Right

    pip install requests on your machine. requests.get("https://example.com", timeout=5) or HEAD the same URL, or GET http://127.0.0.1:8000 if you started python -m http.server 8000 on YOUR box. Print status_code and headers.get for Server and CSP/HSTS. Write notes to $HOME/cyberlium-lab with chmod 600 — no cookies, no passwords. Next lesson is scanner design for loopback, not a bigger HTTP attack.

6. Practical: one GET to example.com (or YOUR http.server) with timeout=5

Install requests if needed, then run the block. Prefer https://example.com. If you are offline, start python -m http.server 8000 in another terminal on YOUR machine and GET http://127.0.0.1:8000 instead — still your process, still a timeout. Print status, Server, and CSP or HSTS. That is the whole lab. Do not add a wordlist. Do not follow this with a scan of the LAN. Save a redacted one-liner under $HOME/cyberlium-lab if you want an artifact; chmod 600; never paste Set-Cookie values.

Command guide

Defensive GET — example.com or YOUR local server, always timeout=

DEFENSIVE. One GET/HEAD. No logins, no SQLi, no wordlists, no verify=False. Target: IANA example.com OR a server YOU start: python -m http.server 8000

Command — copy this

import requests

Command — copy this

URL = "https://example.com"  # or "http://127.0.0.1:8000" if you run http.server locally

NEVER: school portals, banks, café capture pages, random internet hosts, /login spray

Command — copy this

r = requests.get(URL, timeout=5)
print("status:", r.status_code)
print("final_url:", r.url)
print("server:", r.headers.get("server"))
print("csp:", r.headers.get("content-security-policy"))
print("hsts:", r.headers.get("strict-transport-security"))

Optional HEAD (headers only, no body):

Optional command

h = requests.head(URL, timeout=5)

print("head_status:", h.status_code)

Optional notes (no cookies, no passwords):

Optional command

mkdir -p "$HOME/cyberlium-lab"
echo "example.com GET recorded" >> "$HOME/cyberlium-lab/http-demo.txt"
chmod 600 "$HOME/cyberlium-lab/http-demo.txt"

NEVER: requests.post(login_url, data={"password": ...}) NEVER: payloads in params, verify=False as a habit, crawlers, credential stuffing

Mission: one timed GET, status + two headers

1) Explain GET vs HEAD, and what 200, 301, 403, and 404 mean without treating them as an attack map. 2) pip install requests on YOUR machine. GET https://example.com with timeout=5 (or GET http://127.0.0.1:8000 if you started http.server). Print status_code plus Server and CSP or HSTS. 3) Write why timeout= is required and why login brute force / SQLi is out of scope. Optional: notes in $HOME/cyberlium-lab with chmod 600, no cookies. Do not attack any host. Do not stuff credentials.

Stuck? Ask Cyberlium AI Mentor

If 403 still feels like “try harder” or a missing Server header feels like you should scan more hosts, ask for a hint — not a payload. Try: "Hint only: why is requests.get(example.com, timeout=5) a defensive check, what do 200 vs 301 vs 404 mean, and why must I never POST password lists or verify=False?" You still run one GET. No SQLi, no stuffing, no café/ISP/school targets.

You now install requests on your own box, always pass timeout=, and read status plus a couple of headers from example.com or a local server you run. 200/301/403/404 are a map of what the server said, not a to-do list. Server and CSP are defensive notes, not exploit selectors. Login forms are off limits. Next — Port Scanner Script — designs a loop of TCP connects with the same scope lock: YOUR loopback, small port list, timeout, no unauthorized scanning.

Knowledge Check

1

APPLY: You GET https://example.com with timeout=5 and see 200 plus a Server header. A classmate wants to POST 5,000 passwords at the school portal “to learn requests.” Correct move?

Multiple choice

Knowledge Check

2

APPLY: True or False: HEAD is for downloading the body faster, 403 means you should send SQLi, and missing CSP on example.com authorizes scanning the ISP for more banners.

True or False

Knowledge Check

3

APPLY: Match the code to the ethics. Which snippet is the lesson?

Multiple choice

← Previous

Answer all 3 knowledge checks to continue. (0/3 answered)