Skip to content

Instantly share code, notes, and snippets.

@afuggini
Created February 9, 2026 18:22
Show Gist options
  • Select an option

  • Save afuggini/ea21977a1ba9859d1d40e639261dded0 to your computer and use it in GitHub Desktop.

Select an option

Save afuggini/ea21977a1ba9859d1d40e639261dded0 to your computer and use it in GitHub Desktop.
Clarin.com HTTP Methods Security PoC - Non-Destructive Test Script
#!/bin/bash
#
# ClarΓ­n Security PoC - HTTP Methods Vulnerability Demonstration
#
# Author: Security Researcher
# Date: 2026-02-09
# Target: www.clarin.com
#
# PURPOSE: Demonstrate dangerous HTTP methods are enabled
# NOTE: All tests are NON-DESTRUCTIVE - uses non-existent test paths
#
# Usage: ./clarin-security-poc.sh
#
set -e
TARGET="https://www.clarin.com"
TEST_PATH="/security-test-$(date +%s)-deleteme"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo ""
echo "╔════════════════════════════════════════════════════════════════╗"
echo "β•‘ CLARÍN SECURITY POC - HTTP METHODS VULNERABILITY β•‘"
echo "β•‘ NON-DESTRUCTIVE TEST β•‘"
echo "β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•"
echo ""
echo -e "${BLUE}Target:${NC} $TARGET"
echo -e "${BLUE}Date:${NC} $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
echo ""
# ============================================================
# TEST 1: OPTIONS - Check which methods are advertised
# ============================================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${YELLOW}TEST 1: OPTIONS Request - Check Allowed Methods${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Command: curl -s -X OPTIONS $TARGET -I"
echo ""
OPTIONS_RESPONSE=$(curl -s -X OPTIONS "$TARGET" -I 2>&1)
echo "$OPTIONS_RESPONSE" | head -20
# Extract Allow header
ALLOW_HEADER=$(echo "$OPTIONS_RESPONSE" | grep -i "^Allow:" || echo "Not found")
echo ""
echo -e "${BLUE}Allow Header:${NC} $ALLOW_HEADER"
if echo "$ALLOW_HEADER" | grep -qi "PUT\|DELETE\|CONNECT"; then
echo -e "${RED}⚠️ VULNERABLE: Dangerous methods advertised in Allow header${NC}"
else
echo -e "${YELLOW}Note: Allow header may not be present, testing methods directly...${NC}"
fi
echo ""
# ============================================================
# TEST 2: PUT - Attempt to upload (non-existent test path)
# ============================================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${YELLOW}TEST 2: PUT Request - File Upload Attempt${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo -e "${BLUE}Test Path:${NC} $TARGET$TEST_PATH.txt"
echo "Command: curl -s -X PUT $TARGET$TEST_PATH.txt -d 'security-test' -w '%{http_code}'"
echo ""
PUT_CODE=$(curl -s -X PUT "$TARGET$TEST_PATH.txt" \
-H "Content-Type: text/plain" \
-d "security-test-content" \
-o /tmp/put_response.txt \
-w "%{http_code}" 2>&1)
echo -e "Response Code: ${BLUE}$PUT_CODE${NC}"
echo "Response Body (first 200 chars):"
head -c 200 /tmp/put_response.txt 2>/dev/null || echo "(empty)"
echo ""
if [[ "$PUT_CODE" == "405" ]]; then
echo -e "${GREEN}βœ… SECURE: PUT method properly rejected (405 Method Not Allowed)${NC}"
elif [[ "$PUT_CODE" == "403" ]]; then
echo -e "${YELLOW}⚠️ PARTIAL: PUT blocked by authorization (403), but method is accepted${NC}"
elif [[ "$PUT_CODE" == "200" || "$PUT_CODE" == "201" || "$PUT_CODE" == "204" ]]; then
echo -e "${RED}🚨 CRITICAL: PUT method SUCCEEDED - file upload possible!${NC}"
else
echo -e "${YELLOW}⚠️ PUT returned $PUT_CODE - method may be accepted but blocked elsewhere${NC}"
fi
echo ""
# ============================================================
# TEST 3: DELETE - Attempt to delete (non-existent test path)
# ============================================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${YELLOW}TEST 3: DELETE Request - Resource Deletion Attempt${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo -e "${BLUE}Test Path:${NC} $TARGET$TEST_PATH-delete"
echo "Command: curl -s -X DELETE $TARGET$TEST_PATH-delete -w '%{http_code}'"
echo ""
DELETE_CODE=$(curl -s -X DELETE "$TARGET$TEST_PATH-delete" \
-o /tmp/delete_response.txt \
-w "%{http_code}" 2>&1)
echo -e "Response Code: ${BLUE}$DELETE_CODE${NC}"
echo "Response Body (first 200 chars):"
head -c 200 /tmp/delete_response.txt 2>/dev/null || echo "(empty)"
echo ""
if [[ "$DELETE_CODE" == "405" ]]; then
echo -e "${GREEN}βœ… SECURE: DELETE method properly rejected (405 Method Not Allowed)${NC}"
elif [[ "$DELETE_CODE" == "403" ]]; then
echo -e "${YELLOW}⚠️ PARTIAL: DELETE blocked by authorization (403), but method is accepted${NC}"
elif [[ "$DELETE_CODE" == "200" || "$DELETE_CODE" == "204" ]]; then
echo -e "${RED}🚨 CRITICAL: DELETE method ACCEPTED - resource deletion possible!${NC}"
else
echo -e "${YELLOW}⚠️ DELETE returned $DELETE_CODE - method may be accepted${NC}"
fi
echo ""
# ============================================================
# TEST 4: CONNECT - Proxy tunneling attempt
# ============================================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${YELLOW}TEST 4: CONNECT Request - Proxy Tunnel Attempt${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Command: curl -s -X CONNECT $TARGET -w '%{http_code}'"
echo ""
CONNECT_CODE=$(curl -s -X CONNECT "$TARGET" \
-o /tmp/connect_response.txt \
-w "%{http_code}" 2>&1 || echo "000")
echo -e "Response Code: ${BLUE}$CONNECT_CODE${NC}"
echo "Response Body (first 200 chars):"
head -c 200 /tmp/connect_response.txt 2>/dev/null || echo "(empty)"
echo ""
if [[ "$CONNECT_CODE" == "405" ]]; then
echo -e "${GREEN}βœ… SECURE: CONNECT method properly rejected (405)${NC}"
elif [[ "$CONNECT_CODE" == "400" ]]; then
echo -e "${GREEN}βœ… SECURE: CONNECT rejected as bad request (400)${NC}"
elif [[ "$CONNECT_CODE" == "403" ]]; then
echo -e "${YELLOW}⚠️ PARTIAL: CONNECT blocked (403), but method recognized${NC}"
elif [[ "$CONNECT_CODE" == "200" ]]; then
echo -e "${RED}🚨 HIGH: CONNECT method ACCEPTED - proxy tunneling possible!${NC}"
else
echo -e "${YELLOW}⚠️ CONNECT returned $CONNECT_CODE${NC}"
fi
echo ""
# ============================================================
# TEST 5: PATCH - Resource modification attempt
# ============================================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${YELLOW}TEST 5: PATCH Request - Resource Modification Attempt${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo -e "${BLUE}Test Path:${NC} $TARGET$TEST_PATH-patch"
echo "Command: curl -s -X PATCH $TARGET$TEST_PATH-patch -d '{\"test\":true}' -w '%{http_code}'"
echo ""
PATCH_CODE=$(curl -s -X PATCH "$TARGET$TEST_PATH-patch" \
-H "Content-Type: application/json" \
-d '{"security_test": true}' \
-o /tmp/patch_response.txt \
-w "%{http_code}" 2>&1)
echo -e "Response Code: ${BLUE}$PATCH_CODE${NC}"
echo "Response Body (first 200 chars):"
head -c 200 /tmp/patch_response.txt 2>/dev/null || echo "(empty)"
echo ""
if [[ "$PATCH_CODE" == "405" ]]; then
echo -e "${GREEN}βœ… SECURE: PATCH method properly rejected (405)${NC}"
elif [[ "$PATCH_CODE" == "403" ]]; then
echo -e "${YELLOW}⚠️ PARTIAL: PATCH blocked (403), but method accepted${NC}"
elif [[ "$PATCH_CODE" == "200" || "$PATCH_CODE" == "204" ]]; then
echo -e "${RED}🚨 MEDIUM: PATCH method ACCEPTED - resource modification possible!${NC}"
else
echo -e "${YELLOW}⚠️ PATCH returned $PATCH_CODE${NC}"
fi
echo ""
# ============================================================
# TEST 6: TRACE - XST (Cross-Site Tracing) check
# ============================================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${YELLOW}TEST 6: TRACE Request - Cross-Site Tracing Check${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
TRACE_CODE=$(curl -s -X TRACE "$TARGET" \
-o /tmp/trace_response.txt \
-w "%{http_code}" 2>&1)
echo -e "Response Code: ${BLUE}$TRACE_CODE${NC}"
if [[ "$TRACE_CODE" == "405" ]]; then
echo -e "${GREEN}βœ… SECURE: TRACE properly disabled${NC}"
elif [[ "$TRACE_CODE" == "200" ]]; then
echo -e "${RED}⚠️ TRACE enabled - Cross-Site Tracing possible${NC}"
else
echo -e "${GREEN}βœ… TRACE returned $TRACE_CODE - likely disabled${NC}"
fi
echo ""
# ============================================================
# SUMMARY
# ============================================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${YELLOW}SUMMARY - FINDINGS${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "| Method | Response | Status |"
echo "|---------|----------|---------------------------|"
echo "| PUT | $PUT_CODE | $([ "$PUT_CODE" == "405" ] && echo "βœ… Blocked" || echo "⚠️ Needs review") |"
echo "| DELETE | $DELETE_CODE | $([ "$DELETE_CODE" == "405" ] && echo "βœ… Blocked" || echo "⚠️ Needs review") |"
echo "| CONNECT | $CONNECT_CODE | $([ "$CONNECT_CODE" == "405" ] && echo "βœ… Blocked" || echo "⚠️ Needs review") |"
echo "| PATCH | $PATCH_CODE | $([ "$PATCH_CODE" == "405" ] && echo "βœ… Blocked" || echo "⚠️ Needs review") |"
echo "| TRACE | $TRACE_CODE | $([ "$TRACE_CODE" == "405" ] && echo "βœ… Blocked" || echo "⚠️ Check") |"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${YELLOW}RECOMMENDED FIX (Nginx)${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
cat << 'NGINX'
# Add to nginx server block:
if ($request_method !~ ^(GET|HEAD|POST|OPTIONS)$) {
return 405;
}
# Or more restrictive:
limit_except GET HEAD POST {
deny all;
}
NGINX
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${YELLOW}RECOMMENDED FIX (Apache)${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
cat << 'APACHE'
# Add to .htaccess or httpd.conf:
<LimitExcept GET HEAD POST OPTIONS>
Require all denied
</LimitExcept>
# Disable TRACE:
TraceEnable Off
APACHE
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${BLUE}Test completed at $(date -u '+%Y-%m-%d %H:%M:%S UTC')${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Cleanup
rm -f /tmp/put_response.txt /tmp/delete_response.txt /tmp/connect_response.txt /tmp/patch_response.txt /tmp/trace_response.txt 2>/dev/null
echo -e "${GREEN}Done! All tests used non-existent paths - no actual changes made.${NC}"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment