Q&A Laufend: Gitea Spam-Angriff & HĂ€rtung

Channel: #laufend
Kategorie: Q&A
Datum: 30.03.2026
Status: ✅ Gelöst
Persona: Deepbit 🔧


Was ist passiert?

28.–29. MĂ€rz 2026: Rund 50 Spam-Accounts wurden auf git.crumbforest.org erstellt.
Die Registrierung war 16 Monate lang offen — erster Angriff ĂŒberhaupt.

Wie wurde es bemerkt?

Manuell. Admin sah unbekannte User in der Gitea-Übersicht beim nĂ€chtlichen Check.

Angriffs-Muster

Merkmal Detail
Domain @topcompanygroup.com (fast alle)
IPs 183.6.47.107, 183.221.101.89, 123.57.146.97
Timing Bulk innerhalb weniger Stunden
Repos 0 erstellt, einige leere Fork-Versuche
Commits 0
Profil-Spam URLs zu externen Gitea-Instanzen auf Port 3000/30000
Ziel SEO-Backlinks (kein Schadcode)

Wie wurde es gelöst?

Runde 1: Manuell (Nacht)

  • ~30 Accounts per Hand im Gitea Admin-Panel gelöscht
  • DISABLE_REGISTRATION = true in app.ini gesetzt

Runde 2: Script mit Rate-Limit

# gitea_ninja.sh --analyze zeigt verbleibende Accounts
# Dann per Script mit sleep 2 zwischen Deletes
while read user; do
    sudo -u gitea gitea admin user delete --username "$user" --purge -c /etc/gitea/app.ini
    sleep 2
done < /tmp/spam_users.txt

Problem: "user still has ownership of repositories"

Spam-User hatten leere Repos erstellt (Fork-Versuche). Lösung: --purge Flag löscht User + alle Repos.

Problem: "user does not exist"

Usernames waren im ersten Durchlauf abgeschnitten (Copy-Paste aus Web-UI). Lösung: korrekte Usernames aus der Gitea-DB oder User-Liste.

Problem: Rate-Limiting

Gitea hat eigenes Rate-Limit bei schnellen CLI-Aufrufen. Lösung: sleep 2 zwischen jedem Delete.

HĂ€rtung (permanent)

# /etc/gitea/app.ini

[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = true
ENABLE_CAPTCHA = true
DEFAULT_ALLOW_CREATE_ORGANIZATION = false
SHOW_REGISTRATION_BUTTON = false

[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false

[other]
SHOW_FOOTER_VERSION = false

Nach Änderung:

systemctl restart gitea

Erkennung: Wie finde ich Spam-Accounts?

# 1. User ohne Repos (verdÀchtig wenn nicht Admin)
sqlite3 /var/lib/gitea/data/gitea.db "
  SELECT lower_name, email FROM user 
  WHERE type=0 AND is_admin=0 AND num_repos=0
"

# 2. Bulk-Registrierungen (>3 pro Tag)
sqlite3 /var/lib/gitea/data/gitea.db "
  SELECT date(created_unix, 'unixepoch') AS d, COUNT(*) AS c
  FROM user WHERE type=0
  GROUP BY d HAVING c > 3
"

# 3. Bekannte Spam-Domains
sqlite3 /var/lib/gitea/data/gitea.db "
  SELECT lower_name, email FROM user 
  WHERE email LIKE '%@topcompanygroup.com'
"

# 4. Spam-URLs in Profilen
sqlite3 /var/lib/gitea/data/gitea.db "
  SELECT lower_name, website FROM user 
  WHERE website LIKE '%:3000%' OR website LIKE '%:30000%'
"

Löschen: Einzel vs. Bulk

# Einzeln
sudo -u gitea gitea admin user delete --username SPAMUSER --purge -c /etc/gitea/app.ini

# Bulk (mit Rate-Limit Schutz)
cat userlist.txt | while read user; do
    sudo -u gitea gitea admin user delete --username "$user" --purge -c /etc/gitea/app.ini
    sleep 2
done

# Wichtig: --purge löscht User + Repos + Kommentare + alles
# Ohne --purge: Fehler wenn User Repos besitzt

Monitoring

# RegelmĂ€ĂŸig prĂŒfen (z.B. via cron oder manuell)
gitea_ninja.sh --analyze

# Nginx Logs: Registrierungs-Versuche
grep "user/sign_up" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

Lessons Learned

  1. 16 Monate offen → 1 Angriff. Offene Registrierung war lange kein Problem, aber irgendwann findet dich jeder Bot.
  2. Kein Schadcode. Der Angriff war SEO-Spam, keine Infiltration. Trotzdem sofort handeln.
  3. Rate-Limiting beachten. Gitea und der eigene nginx-Proxy können Bulk-Löschungen bremsen. sleep 2 ist dein Freund.
  4. --purge kennen. Ohne das Flag scheitert das Löschen wenn der User Repos hat.
  5. REQUIRE_SIGNIN_VIEW ist genauso wichtig wie DISABLE_REGISTRATION. Sonst sehen Bots weiterhin die User-Profile.
  6. Forensik → Vektor. Jeder Vorfall wird dokumentiert und geseeded. Der Wald lernt.

Tools

Tool Zweck
gitea_ninja.sh --analyze Spam-Accounts finden
gitea_ninja.sh --harden Config prĂŒfen
gitea_ninja.sh --report Markdown fĂŒr Vektor
gitea admin user delete --purge User + Repos löschen
gitea admin user list Alle User anzeigen

Der Wald schĂŒtzt sich selbst. đŸ„·đŸŒČ