⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.48
Server IP:
78.40.11.138
Server:
Linux tango.o2switch.net 4.18.0-553.30.1.lve.el8.x86_64 #1 SMP Tue Dec 3 01:21:19 UTC 2024 x86_64
Server Software:
Apache
PHP Version:
7.4.33
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
home
/
sc1voni9410
/
sb-gate
/
scripts
/
Edit File: sb-checks-v31.sh
#!/usr/bin/env bash # sb-checks-v31.sh — checks PURS de la couche v3.1 (sécurité, track, cache, monét, légal, seo, geo). # Testables hors-ligne (fixtures). 0=CONFORME, 1=VIOLATION. Portable nawk/bash 3.2. set -uo pipefail # ── P-087 : display/AdSense banni ──────────────────────────────────────────── chk_no_display(){ local h; h=$(cat "$1") local hit; hit=$(printf '%s' "$h" | grep -aoiE 'adsbygoogle|googlesyndication|doubleclick\.net|ca-pub-[0-9]+' | head -1) [[ -n "$hit" ]] && { echo "FAIL P-087: régie display détectée ($hit)"; return 1; }; echo "PASS P-087"; return 0; } # ── P-086 : fonts self-hosted (aucune font tierce) ─────────────────────────── chk_fonts_selfhosted(){ local h; h=$(cat "$1") printf '%s' "$h" | grep -aoiE 'fonts\.(googleapis|gstatic)\.com' | head -1 | grep -q . \ && { echo "FAIL P-086: font Google tierce"; return 1; }; echo "PASS P-086"; return 0; } # ── P-080/P-075 : snippet SB-TRACK sans cookie ni localStorage ─────────────── chk_sbtrack_nocookie(){ local s; s=$(cat "$1") # bannis : cookie + localStorage PERSISTANT. sessionStorage (session, effacé à la fermeture) = autorisé (P-077). printf '%s' "$s" | grep -aoiE 'document\.cookie|(^|[^n])localStorage' | head -1 | grep -q . \ && { echo "FAIL P-075: cookie ou localStorage persistant dans le snippet"; return 1; }; echo "PASS P-075"; return 0; } # ── P-100 : bloc citable (classe fact + <time datetime> + source liée + id) ── chk_citable(){ local h; h=$(cat "$1" | tr '\n' ' ') printf '%s' "$h" | grep -qiE 'class="[^"]*fact' || { echo "FAIL P-100: aucun élément .fact"; return 1; } printf '%s' "$h" | grep -qiE '<time[^>]+datetime=' || { echo "FAIL P-100: pas de <time datetime=>"; return 1; } printf '%s' "$h" | grep -qiE '<a [^>]*href=' || { echo "FAIL P-100: pas de source liée"; return 1; } echo "PASS P-100"; return 0; } # ── P-097 : fraîcheur des prix (constaté en AAAA >= annéecourante-1) ───────── chk_freshness(){ local f="$1"; local cur="${2:-$(date +%Y)}"; local min=$((cur-1)) local bad; bad=$(grep -aoiE 'constat[ée]s? en (20[0-9]{2})' "$f" | grep -aoE '20[0-9]{2}' | while read -r y; do (( y < min )) && echo "$y"; done | head -1) [[ -n "$bad" ]] && { echo "FAIL P-097: prix daté périmé ($bad < $min)"; return 1; }; echo "PASS P-097"; return 0; } # ── P-096 : dédup de la requête principale entre briefs d'un site ──────────── chk_brief_dedup(){ local d="$1" local dup; dup=$(grep -rhiE '^[[:space:]]*requ[eê]te principale[[:space:]]*:' "$d"/*.md 2>/dev/null \ | sed -E 's/.*:[[:space:]]*//' | tr 'A-Z' 'a-z' | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//' | sort | uniq -d | head -1) [[ -n "$dup" ]] && { echo "FAIL P-096: requête dupliquée « $dup »"; return 1; }; echo "PASS P-096"; return 0; } # ── P-098 : titles uniques + 30-65 caractères (fichier = 1 title/ligne) ───── chk_titles(){ local f="$1" local dup; dup=$(sort "$f" | sed '/^[[:space:]]*$/d' | uniq -d | head -1) [[ -n "$dup" ]] && { echo "FAIL P-098: title dupliqué « $dup »"; return 1; } local bad=""; while IFS= read -r t; do [[ -z "$t" ]] && continue; local n=${#t}; (( n<30 || n>65 )) && bad="$n:$t"; done < "$f" [[ -n "$bad" ]] && { echo "FAIL P-098: title hors 30-65 ($bad)"; return 1; }; echo "PASS P-098"; return 0; } # ── P-092 : mentions = bloc hébergeur o2switch + code postal ───────────────── chk_mentions_hebergeur(){ local h; h=$(cat "$1") printf '%s' "$h" | grep -qi 'o2switch' || { echo "FAIL P-092: hébergeur o2switch absent des mentions"; return 1; } printf '%s' "$h" | grep -qE '\b[0-9]{5}\b' || { echo "FAIL P-092: pas de code postal hébergeur"; return 1; } echo "PASS P-092"; return 0; } # ── P-093 : confidentialité (clause transfert + durée) ────────────────────── chk_privacy(){ local h; h=$(cat "$1") printf '%s' "$h" | grep -qi 'transfert' || { echo "FAIL P-093: clause de transfert d'activité absente"; return 1; } printf '%s' "$h" | grep -qiE '[0-9]+[[:space:]]*mois|durée de conservation' || { echo "FAIL P-093: durée de conservation absente"; return 1; } echo "PASS P-093"; return 0; } # ── P-099 : mentions hors sitemap ──────────────────────────────────────────── chk_sitemap_exclusion(){ local s; s=$(cat "$1") printf '%s' "$s" | grep -qiE 'mentions?-l[ée]gales?|/mentions?/' \ && { echo "FAIL P-099: page mentions présente dans le sitemap"; return 1; }; echo "PASS P-099"; return 0; } # ── P-101 : mentions lient l'entité groupe ─────────────────────────────────── chk_group_link(){ local h; h=$(cat "$1"); local grp="${2:?url groupe}" local gd; gd=$(printf '%s' "$grp" | sed -E 's#https?://##; s#/.*##; s/^www\.//') printf '%s' "$h" | grep -qiE "href=\"https?://([a-z0-9.-]*\.)?${gd//./\\.}" \ || { echo "FAIL P-101: mentions ne lient pas l'entité groupe ($gd)"; return 1; }; echo "PASS P-101"; return 0; } # ── P-065 : admins conformes à admins.txt ──────────────────────────────────── chk_admins(){ local cur="$1"; local allow="$2"; local rogue="" while IFS= read -r a; do [[ -z "$a" ]] && continue; grep -qixF "$a" "$allow" 2>/dev/null || rogue+="$a "; done < "$cur" [[ -n "$rogue" ]] && { echo "FAIL P-065: admin(s) hors admins.txt → $rogue"; return 1; }; echo "PASS P-065"; return 0; } # ── P-069 : plugins conformes à l'allowlist ────────────────────────────────── chk_plugin_allowlist(){ local inst="$1"; local allow="$2"; local bad="" while IFS= read -r p; do [[ -z "$p" ]] && continue; grep -qixF "$p" "$allow" 2>/dev/null || bad+="$p "; done < "$inst" [[ -n "$bad" ]] && { echo "FAIL P-069: plugin(s) hors allowlist → $bad"; return 1; }; echo "PASS P-069"; return 0; } # ── P-066 : liens sortants dofollow conformes à la baseline (groupe excepté) ─ chk_links_baseline(){ local html; html=$(cat "$1"); local base="$2"; local grp="${3:-__none__}"; local self="${4:-__none__}" local bad; bad=$(printf '%s' "$html" | grep -aoiE '<a [^>]*>' | while read -r tag; do printf '%s' "$tag" | grep -qiE 'href="https?://' || continue href=$(printf '%s' "$tag" | grep -aoiE 'href="https?://[^"]+"' | head -1 | sed -E 's/href="//; s/"$//') host=$(printf '%s' "$href" | sed -E 's#https?://##; s#/.*##; s/^www\.//') printf '%s' "$tag" | grep -qiE 'rel="[^"]*(nofollow|sponsored)' && continue # pas dofollow [[ "$host" == "$grp" || "$host" == *".$grp" ]] && continue # groupe excepté (P-101) [[ "$host" == "$self" || "$host" == *".$self" ]] && continue # lien interne grep -qixF "$host" "$base" 2>/dev/null || echo "$host" done | sort -u | head -3) [[ -n "$bad" ]] && { echo "FAIL P-066: lien dofollow hors baseline → $bad"; return 1; }; echo "PASS P-066"; return 0; } # ── P-081/083 : ORACLE de décision de cache (spec testable ; advanced-cache.php la reflète) ── # echo 1 = cacheable, 0 = non. Args : method uri cookies track_path sb_cache_decision(){ local method="$1" uri="$2" cookies="$3" track="${4:-__track__}" [[ "$method" != "GET" ]] && { echo 0; return; } case "$uri" in *\?*) echo 0; return;; esac case "$uri" in */wp-admin/*|*/wp-json/*|*wp-login.php*) echo 0; return;; esac [[ "$uri" == "$track" ]] && { echo 0; return; } printf '%s' "$cookies" | grep -qiE 'wordpress_logged_in|comment_author|wp-postpass' && { echo 0; return; } echo 1; } chk_cache_decision(){ local ok=1 t(){ local exp="$1"; shift; local got; got=$(sb_cache_decision "$@"); [[ "$got" == "$exp" ]] || { echo " cas KO exp=$exp got=$got ($*)"; ok=0; }; } t 1 GET /article/ "" /trk t 0 GET "/article/?utm=x" "" /trk t 0 POST /article/ "" /trk t 0 GET /article/ "wordpress_logged_in_abc=1" /trk t 0 GET /wp-admin/edit.php "" /trk t 0 GET /wp-json/wp/v2/posts "" /trk t 0 GET /trk "" /trk t 0 GET /page/ "wp-postpass_x=1" /trk (( ok )) && { echo "PASS P-081/083 (8 cas)"; return 0; }; echo "FAIL P-081/083"; return 1; } # ── P-090 : ORACLE de validation de lead (email + tel FR + domaines jetables) ── # args : email phone [disposable_file]. echo OK / ERR:<motif> sb_lead_validate(){ local email="$1" phone="$2" disp="${3:-}" printf '%s' "$email" | grep -qiE '^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$' || { echo "ERR:email"; return; } local dom; dom=$(printf '%s' "$email" | sed -E 's/.*@//' | tr 'A-Z' 'a-z') if [[ -n "$disp" && -f "$disp" ]]; then grep -qixF "$dom" "$disp" && { echo "ERR:jetable"; return; }; fi local d; d=$(printf '%s' "$phone" | tr -cd '0-9+') printf '%s' "$d" | grep -qE '^(\+33[1-9][0-9]{8}|0[1-9][0-9]{8})$' || { echo "ERR:tel"; return; } echo "OK"; } chk_lead_validate(){ local ok=1; local disp="${1:-}" t(){ local exp="$1"; shift; local got; got=$(sb_lead_validate "$@" "$disp"); [[ "$got" == "$exp"* ]] || { echo " cas KO exp=$exp got=$got ($1|$2)"; ok=0; }; } t OK "julie@gmail.com" "0612345678" t OK "a.b@site.fr" "+33612345678" t ERR "pasdemail" "0612345678" t ERR "x@y.fr" "12" (( ok )) && { echo "PASS P-090 (4 cas)"; return 0; }; echo "FAIL P-090"; return 1; } # Dispatch if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then fn="${1:-}"; shift || true case "$fn" in chk_*|sb_cache_decision|sb_lead_validate) "$fn" "$@";; *) echo "usage: sb-checks-v31.sh <chk_*|sb_cache_decision|sb_lead_validate> <args>"; exit 2;; esac fi
Simpan