chore(debug): Redirect-Test-Karte — Layer-1-Bypass reproduzieren
Neue RedirectTestCard im Debug-Screen mit zwei Buttons: - Kontrolle: tipico.de direkt öffnen - Test: httpbin-302-Redirect → tipico.de Spielt den Casino-Mail-Fall nach (erlaubter Zwischen-Host → 302 → blockierte Domain), um zu prüfen ob der DNS-Filter die Zieldomain auch nach einem Redirect noch sinkholet. Frontend-only. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
23b91a1a3e
commit
bf28d81d13
@ -7,6 +7,7 @@ import {
|
||||
TouchableOpacity,
|
||||
Alert,
|
||||
Clipboard,
|
||||
Linking,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
@ -129,6 +130,8 @@ export default function DebugScreen() {
|
||||
<RealtimeLogCard />
|
||||
{Platform.OS === 'ios' ? <ProtectionLogCard /> : null}
|
||||
|
||||
<RedirectTestCard />
|
||||
|
||||
<DebugStub
|
||||
title="LLM-Provider Toggle"
|
||||
subtitle="Phase C: aus app/urge.tsx hierher migrieren"
|
||||
@ -149,6 +152,125 @@ export default function DebugScreen() {
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Redirect-Test Card (Layer-1-Bypass-Repro) ─────────────────────────────
|
||||
|
||||
/**
|
||||
* Reproduziert den Casino-Mail-Fall: ein Klick geht erst auf einen ERLAUBTEN
|
||||
* Zwischen-Host (wie SendGrid-Click-Tracking), der dann per HTTP-302 auf eine
|
||||
* BLOCKIERTE Domain weiterleitet. Damit lässt sich gezielt prüfen, ob der
|
||||
* DNS-Filter (Layer 1) die Zieldomain auch nach einem Redirect noch sinkholet.
|
||||
*
|
||||
* Nach dem Tippen: oben im "Protection Log" prüfen, ob ein `BLOCKED:`-Eintrag
|
||||
* für tipico.de auftaucht.
|
||||
*/
|
||||
function RedirectTestCard() {
|
||||
const colors = useColors();
|
||||
|
||||
// tipico.de ist sicher in der Blocklist (gambling-domains.json + 329k-Liste).
|
||||
const BLOCKED = 'tipico.de';
|
||||
// httpbin.org/redirect-to liefert eine echte HTTP-302-Response auf das Ziel —
|
||||
// httpbin selbst ist nicht geblockt, spielt also den erlaubten Zwischen-Host.
|
||||
const redirectUrl =
|
||||
'https://httpbin.org/redirect-to?url=' +
|
||||
encodeURIComponent('https://' + BLOCKED) +
|
||||
'&status_code=302';
|
||||
|
||||
function open(url: string) {
|
||||
Linking.openURL(url).catch((e) =>
|
||||
Alert.alert('Fehler', String(e?.message ?? e)),
|
||||
);
|
||||
}
|
||||
|
||||
function Row({
|
||||
icon,
|
||||
label,
|
||||
onPress,
|
||||
}: {
|
||||
icon: keyof typeof Ionicons.glyphMap;
|
||||
label: string;
|
||||
onPress: () => void;
|
||||
}) {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={onPress}
|
||||
activeOpacity={0.7}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
paddingVertical: 11,
|
||||
paddingHorizontal: 12,
|
||||
borderRadius: 10,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.border,
|
||||
marginTop: 8,
|
||||
}}
|
||||
>
|
||||
<Ionicons name={icon} size={16} color={colors.textMuted} />
|
||||
<Text style={{ flex: 1, fontSize: 13, fontFamily: 'Nunito_600SemiBold', color: colors.text }}>
|
||||
{label}
|
||||
</Text>
|
||||
<Ionicons name="open-outline" size={15} color={colors.textMuted} />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: colors.surface,
|
||||
borderRadius: 14,
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgba(0,0,0,0.05)',
|
||||
padding: 14,
|
||||
marginBottom: 12,
|
||||
}}
|
||||
>
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 10, marginBottom: 8 }}>
|
||||
<View
|
||||
style={{
|
||||
width: 36,
|
||||
height: 36,
|
||||
borderRadius: 11,
|
||||
backgroundColor: colors.surfaceElevated,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Ionicons name="arrow-redo-outline" size={18} color={colors.textMuted} />
|
||||
</View>
|
||||
<Text style={{ fontSize: 14, color: colors.text, fontFamily: 'Nunito_700Bold', flex: 1 }}>
|
||||
Redirect-Test (Layer 1)
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontFamily: 'Nunito_400Regular',
|
||||
color: colors.textMuted,
|
||||
lineHeight: 17,
|
||||
}}
|
||||
>
|
||||
Reproduziert den Casino-Mail-Fall: erlaubter Zwischen-Host → 302-Redirect
|
||||
→ blockierte Domain (tipico.de). Beide tippen, dann oben den Protection
|
||||
Log vergleichen — kommt ein „BLOCKED: tipico.de"?
|
||||
</Text>
|
||||
|
||||
<Row
|
||||
icon="shield-checkmark-outline"
|
||||
label="Kontrolle: tipico.de direkt"
|
||||
onPress={() => open('https://' + BLOCKED)}
|
||||
/>
|
||||
<Row
|
||||
icon="git-branch-outline"
|
||||
label="Test: 302-Redirect → tipico.de"
|
||||
onPress={() => open(redirectUrl)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Realtime Status Card ──────────────────────────────────────────────────
|
||||
|
||||
function RealtimeStatusCard() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user