Compare commits
No commits in common. "e2922b0342526e4ac0797dbd8176411a0fdeced0" and "399b5eca9d0c1d3584b8c730b28d2f9545f02397" have entirely different histories.
e2922b0342
...
399b5eca9d
@ -1,42 +1,25 @@
|
|||||||
import { StolenDataEntry } from "./stolen-data-entry";
|
import { StolenDataEntry } from "./stolen-data-entry";
|
||||||
import { getshorthost, parseCookie, Request } from "./util";
|
import { getshorthost, parseCookie, Request } from "./util";
|
||||||
|
|
||||||
type NameValue = { name: string; value: string };
|
|
||||||
|
|
||||||
export type HAREntry = {
|
export type HAREntry = {
|
||||||
pageref: string;
|
pageref: string;
|
||||||
startedDateTime: string;
|
startedDateTime: string;
|
||||||
request: {
|
request: {
|
||||||
bodySize: number;
|
bodySize: number;
|
||||||
cookies: NameValue[];
|
cookies: {}[];
|
||||||
headers: NameValue[];
|
headers: {}[];
|
||||||
headersSize: number;
|
headersSize: number;
|
||||||
httpVersion: string;
|
httpVersion: string;
|
||||||
method: string;
|
method: string;
|
||||||
postData?: {
|
postData: {
|
||||||
mimeType: string;
|
mimeType: string;
|
||||||
params: NameValue[];
|
params: { name: string; value: string }[];
|
||||||
text: string;
|
text: string;
|
||||||
};
|
};
|
||||||
queryString: NameValue[];
|
queryString: { name: string; value: string }[];
|
||||||
url: string;
|
url: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {}; // not relevant
|
||||||
status: number;
|
|
||||||
statusText: string;
|
|
||||||
httpVersion: string;
|
|
||||||
headers: NameValue[];
|
|
||||||
cookies: NameValue[];
|
|
||||||
content: {
|
|
||||||
mimeType: string;
|
|
||||||
size: number;
|
|
||||||
encoding: "base64";
|
|
||||||
text: string;
|
|
||||||
};
|
|
||||||
redirectURL: "";
|
|
||||||
headersSize: number;
|
|
||||||
bodySize: number;
|
|
||||||
}; // not relevant
|
|
||||||
cache: {};
|
cache: {};
|
||||||
timings: {};
|
timings: {};
|
||||||
time: number;
|
time: number;
|
||||||
@ -65,13 +48,6 @@ export default class ExtendedRequest {
|
|||||||
public initialized = false;
|
public initialized = false;
|
||||||
public stolenData: StolenDataEntry[];
|
public stolenData: StolenDataEntry[];
|
||||||
|
|
||||||
constructor(public data: Request) {
|
|
||||||
this.tabId = data.tabId;
|
|
||||||
this.url = data.url;
|
|
||||||
this.requestHeaders = data.requestHeaders;
|
|
||||||
this.shorthost = getshorthost(data.url);
|
|
||||||
}
|
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
await this.cacheOrigin();
|
await this.cacheOrigin();
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
@ -91,8 +67,6 @@ export default class ExtendedRequest {
|
|||||||
);
|
);
|
||||||
if (headers.Referer) {
|
if (headers.Referer) {
|
||||||
url = headers.Referer;
|
url = headers.Referer;
|
||||||
} else {
|
|
||||||
url = this.data.url;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,24 +90,18 @@ export default class ExtendedRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getReferer() {
|
getReferer() {
|
||||||
return (
|
return this.data.requestHeaders.filter((h) => h.name === "Referer")[0]
|
||||||
this.data.requestHeaders.filter((h) => h.name === "Referer")[0]?.value ||
|
.value;
|
||||||
"missing-referrer"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exposesOrigin() {
|
exposesOrigin() {
|
||||||
const url = new URL(this.origin);
|
const url = new URL(this.origin);
|
||||||
const host = url.host;
|
const host = url.host;
|
||||||
const path = url.pathname;
|
const path = url.pathname;
|
||||||
const shorthost = getshorthost(host);
|
|
||||||
return (
|
return (
|
||||||
this.getReferer().includes(host) ||
|
this.getReferer().includes(host) ||
|
||||||
this.stolenData.filter(
|
this.stolenData.filter(
|
||||||
(entry) =>
|
(entry) => entry.value.includes(host) || entry.value.includes(path)
|
||||||
entry.value.includes(host) ||
|
|
||||||
entry.value.includes(path) ||
|
|
||||||
entry.value.includes(shorthost)
|
|
||||||
).length > 0
|
).length > 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -212,6 +180,13 @@ export default class ExtendedRequest {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(public data: Request) {
|
||||||
|
this.tabId = data.tabId;
|
||||||
|
this.url = data.url;
|
||||||
|
this.requestHeaders = data.requestHeaders;
|
||||||
|
this.shorthost = getshorthost(data.url);
|
||||||
|
}
|
||||||
|
|
||||||
hasMark() {
|
hasMark() {
|
||||||
return this.stolenData.some((data) => data.hasMark());
|
return this.stolenData.some((data) => data.hasMark());
|
||||||
}
|
}
|
||||||
@ -229,57 +204,4 @@ export default class ExtendedRequest {
|
|||||||
const hrq = har.request;
|
const hrq = har.request;
|
||||||
return rq.url == hrq.url;
|
return rq.url == hrq.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
toHAR(): HAREntry {
|
|
||||||
return {
|
|
||||||
pageref: "page_1",
|
|
||||||
startedDateTime: `${new Date().toJSON().replace("Z", "+01:00")}`,
|
|
||||||
request: {
|
|
||||||
bodySize: 0,
|
|
||||||
method: this.data.method,
|
|
||||||
url: this.data.url,
|
|
||||||
headersSize: 100,
|
|
||||||
httpVersion: "HTTP/2",
|
|
||||||
headers: this.data.requestHeaders as NameValue[],
|
|
||||||
cookies: this.getCookieData().map((cookie) => ({
|
|
||||||
name: cookie.name,
|
|
||||||
value: cookie.value,
|
|
||||||
})),
|
|
||||||
queryString: this.getQueryParams().map((param) => ({
|
|
||||||
name: param.name,
|
|
||||||
value: param.value,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
status: 200,
|
|
||||||
statusText: "OK",
|
|
||||||
httpVersion: "HTTP/2",
|
|
||||||
headers: [],
|
|
||||||
cookies: [],
|
|
||||||
content: {
|
|
||||||
mimeType: "text/plain",
|
|
||||||
size: 15,
|
|
||||||
encoding: "base64",
|
|
||||||
text: "ZG9lc24ndCBtYXR0ZXIK",
|
|
||||||
},
|
|
||||||
redirectURL: "",
|
|
||||||
headersSize: 15,
|
|
||||||
bodySize: 15,
|
|
||||||
},
|
|
||||||
cache: {},
|
|
||||||
timings: {
|
|
||||||
blocked: -1,
|
|
||||||
dns: 0,
|
|
||||||
connect: 0,
|
|
||||||
ssl: 0,
|
|
||||||
send: 0,
|
|
||||||
wait: 79,
|
|
||||||
receive: 0,
|
|
||||||
},
|
|
||||||
time: 79,
|
|
||||||
_securityState: "secure",
|
|
||||||
serverIPAddress: "31.13.92.36",
|
|
||||||
connection: "443",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ export default function DomainSummary({
|
|||||||
<li>
|
<li>
|
||||||
Właściciel domeny <strong>{cluster.id}</strong> otrzymał:{" "}
|
Właściciel domeny <strong>{cluster.id}</strong> otrzymał:{" "}
|
||||||
<ul>
|
<ul>
|
||||||
<li>Mój adres IP</li>
|
|
||||||
{cluster
|
{cluster
|
||||||
.getMarkedEntries()
|
.getMarkedEntries()
|
||||||
.sort((entryA, entryB) => (entryA.value > entryB.value ? -1 : 1))
|
.sort((entryA, entryB) => (entryA.value > entryB.value ? -1 : 1))
|
||||||
|
@ -14,9 +14,6 @@ export default function EmailTemplate({
|
|||||||
clusters: Record<string, RequestCluster>;
|
clusters: Record<string, RequestCluster>;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [popupState, setPopupState] = useState<PopupState>("not_clicked");
|
const [popupState, setPopupState] = useState<PopupState>("not_clicked");
|
||||||
const [acceptAllName, setAcceptAllName] = useState<string>(
|
|
||||||
"Zaakceptuj wszystkie"
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -29,20 +26,6 @@ export default function EmailTemplate({
|
|||||||
<option value="not_clicked">Nic nie kliknięte</option>
|
<option value="not_clicked">Nic nie kliknięte</option>
|
||||||
<option value="clicked_but_invalid">Kliknięte, ale nieważne</option>
|
<option value="clicked_but_invalid">Kliknięte, ale nieważne</option>
|
||||||
</select>
|
</select>
|
||||||
{popupState === "clicked_but_invalid" ? (
|
|
||||||
<div>
|
|
||||||
<label htmlFor="acceptAllName">
|
|
||||||
Tekst na przycisku do zatwierdzania wszystkich zgód:
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
{...{
|
|
||||||
type: "text",
|
|
||||||
value: acceptAllName,
|
|
||||||
onChange: (e) => setAcceptAllName(e.target.value),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
<p>
|
<p>
|
||||||
Dzień dobry, w dniu {getDate()} odwiedziłem stronę{" "}
|
Dzień dobry, w dniu {getDate()} odwiedziłem stronę{" "}
|
||||||
{marked_entries[0].request.originalURL}. Strona ta wysłała moje dane
|
{marked_entries[0].request.originalURL}. Strona ta wysłała moje dane
|
||||||
@ -61,23 +44,6 @@ export default function EmailTemplate({
|
|||||||
przeczytać treść wyskakującego okienka ze zgodami.
|
przeczytać treść wyskakującego okienka ze zgodami.
|
||||||
</p>
|
</p>
|
||||||
) : null}
|
) : null}
|
||||||
{popupState === "clicked_but_invalid" ? (
|
|
||||||
<p>
|
|
||||||
O ile po wejściu na stronę wcisnąłem w wyskakującym okienku przycisk „
|
|
||||||
{acceptAllName}”, o tyle nie stanowi to według mnie ważnej w świetle
|
|
||||||
RODO zgody, gdyż brakowało w tym okienku równie łatwo osiągalnego
|
|
||||||
przycisku, którego kliknięcie skutkowałoby zasygnalizowaniem braku
|
|
||||||
mojej zgody na takie przetwarzanie moich danych. Mówiąc wprost -
|
|
||||||
wyrażenie „zgody” było łatwiejsze niż jej niewyrażenie. Zatem tak
|
|
||||||
otrzymana przez Państwo moja „zgoda” nie jest poprawną podstawą prawną
|
|
||||||
do przetwarzania moich danych osobowych (
|
|
||||||
<em>
|
|
||||||
art. 7 ust. 3 Rozporządzenia Parlamentu Europejskiego i Rady (UE)
|
|
||||||
2016/679 z dnia 27 kwietnia 2016
|
|
||||||
</em>
|
|
||||||
).
|
|
||||||
</p>
|
|
||||||
) : null}
|
|
||||||
<p>
|
<p>
|
||||||
Udokumentowałem to na zrzutach ekranu z mojej przeglądarki internetowej,
|
Udokumentowałem to na zrzutach ekranu z mojej przeglądarki internetowej,
|
||||||
które to zrzuty przesyłam w załączeniu.
|
które to zrzuty przesyłam w załączeniu.
|
||||||
@ -87,11 +53,7 @@ export default function EmailTemplate({
|
|||||||
danych osobowych (na pewno nie jest to przetwarzanie konieczne do
|
danych osobowych (na pewno nie jest to przetwarzanie konieczne do
|
||||||
wyświetlenia strony z technicznego punktu widzenia). Jeżeli takie
|
wyświetlenia strony z technicznego punktu widzenia). Jeżeli takie
|
||||||
przesłanki legalizujące jednak występują, proszę o ich wskazanie,
|
przesłanki legalizujące jednak występują, proszę o ich wskazanie,
|
||||||
<strong>
|
<strong> dla każdego z celów i podmiotów z osobna</strong>.
|
||||||
{" "}
|
|
||||||
dla każdego z celów i podmiotów z <em>osobna</em>
|
|
||||||
</strong>
|
|
||||||
.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Jeżeli wskazaną przez Państwa przesłanką legalizującą dany element
|
Jeżeli wskazaną przez Państwa przesłanką legalizującą dany element
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { HAREntry } from "../extended-request";
|
import { HAREntry } from "../extended-request";
|
||||||
import { StolenDataEntry } from "../stolen-data-entry";
|
import { StolenDataEntry } from "../stolen-data-entry";
|
||||||
import { getshorthost, unique } from "../util";
|
|
||||||
|
|
||||||
function handleNewFile(
|
function handleNewFile(
|
||||||
element: HTMLInputElement,
|
element: HTMLInputElement,
|
||||||
marked_entries: StolenDataEntry[],
|
marked_entries: StolenDataEntry[],
|
||||||
setFiltered: (Blob) => void
|
setFiltered: (Blob) => void
|
||||||
): void {
|
) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.addEventListener("load", () => {
|
reader.addEventListener("load", () => {
|
||||||
const content = JSON.parse(reader.result as string);
|
const content = JSON.parse(reader.result as string);
|
||||||
@ -23,35 +22,6 @@ function handleNewFile(
|
|||||||
reader.readAsText(element.files[0]);
|
reader.readAsText(element.files[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateFakeHAR(marked_entries: StolenDataEntry[]) {
|
|
||||||
const requests = marked_entries.map((entry) => entry.request);
|
|
||||||
return {
|
|
||||||
log: {
|
|
||||||
version: "1.2",
|
|
||||||
creator: {
|
|
||||||
name: "Firefox",
|
|
||||||
version: "94.0",
|
|
||||||
},
|
|
||||||
browser: {
|
|
||||||
name: "Firefox",
|
|
||||||
version: "94.0",
|
|
||||||
},
|
|
||||||
pages: [
|
|
||||||
{
|
|
||||||
startedDateTime: "2021-11-08T20:27:23.195+01:00",
|
|
||||||
id: "page_1",
|
|
||||||
title: "HAR DUmp",
|
|
||||||
pageTimings: {
|
|
||||||
onContentLoad: 467,
|
|
||||||
onLoad: 4226,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
entries: unique(requests).map((r) => r.toHAR()),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function HARConverter({
|
export default function HARConverter({
|
||||||
marked_entries,
|
marked_entries,
|
||||||
}: {
|
}: {
|
||||||
@ -59,7 +29,6 @@ export default function HARConverter({
|
|||||||
}) {
|
}) {
|
||||||
const [filtered, setFiltered] = useState<Blob | null>(null);
|
const [filtered, setFiltered] = useState<Blob | null>(null);
|
||||||
const [filename, setFilename] = useState("");
|
const [filename, setFilename] = useState("");
|
||||||
const fakeHAR = generateFakeHAR(marked_entries);
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
@ -79,16 +48,6 @@ export default function HARConverter({
|
|||||||
</a>
|
</a>
|
||||||
)) ||
|
)) ||
|
||||||
null}
|
null}
|
||||||
<a
|
|
||||||
href={URL.createObjectURL(
|
|
||||||
new Blob([JSON.stringify(fakeHAR)], { type: "application/json" })
|
|
||||||
)}
|
|
||||||
download={`${getshorthost(
|
|
||||||
marked_entries[0].request.originalURL
|
|
||||||
)}-${new Date().toJSON()}-trimmed.har`}
|
|
||||||
>
|
|
||||||
Pobierz "zfałszowany" HAR
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
32
util.ts
32
util.ts
@ -6,31 +6,9 @@ export type Unpromisify<T> = T extends Promise<infer R> ? R : T;
|
|||||||
export type Unarray<T> = T extends Array<infer R> ? R : T;
|
export type Unarray<T> = T extends Array<infer R> ? R : T;
|
||||||
|
|
||||||
export type Tab = Unarray<Unpromisify<ReturnType<typeof browser.tabs.query>>>;
|
export type Tab = Unarray<Unpromisify<ReturnType<typeof browser.tabs.query>>>;
|
||||||
export type Request = {
|
export type Request = Parameters<
|
||||||
cookieStoreId?: string;
|
Parameters<typeof browser.webRequest.onBeforeSendHeaders.addListener>[0]
|
||||||
documentUrl?: string; // RL of the document in which the resource will be loaded. For example, if the web page at "https://example.com" contains an image or an iframe, then the documentUrl for the image or iframe will be "https://example.com". For a top-level document, documentUrl is undefined.
|
>[0];
|
||||||
frameId: number;
|
|
||||||
incognito?: boolean;
|
|
||||||
method: string;
|
|
||||||
originUrl: string;
|
|
||||||
parentFrameId: number;
|
|
||||||
proxyInfo?: {
|
|
||||||
host: string;
|
|
||||||
port: number;
|
|
||||||
type: string;
|
|
||||||
username: string;
|
|
||||||
proxyDNS: boolean;
|
|
||||||
failoverTimeout: number;
|
|
||||||
};
|
|
||||||
requestHeaders?: { name: string; value?: string; binaryValue?: number[] }[];
|
|
||||||
requestId: string;
|
|
||||||
tabId: number;
|
|
||||||
thirdParty?: boolean;
|
|
||||||
timeStamp: number;
|
|
||||||
type: string;
|
|
||||||
url: string; // the target of the request;
|
|
||||||
urlClassification?: { firstParty: string[]; thirdParty: string[] };
|
|
||||||
};
|
|
||||||
|
|
||||||
export function getshorthost(host: string) {
|
export function getshorthost(host: string) {
|
||||||
return host
|
return host
|
||||||
@ -105,8 +83,8 @@ export function hyphenate(str: string): string {
|
|||||||
return str.replace(/[_\[A-Z]/g, `${String.fromCharCode(173)}$&`);
|
return str.replace(/[_\[A-Z]/g, `${String.fromCharCode(173)}$&`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function unique<T>(array: T[]): Array<T> {
|
export function unique(array: string[]) {
|
||||||
return Array.from(new Set<T>(array));
|
return Array.from(new Set(array));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function allSubhosts(host: string) {
|
export function allSubhosts(host: string) {
|
||||||
|
Loading…
Reference in New Issue
Block a user