Fork me on GitHub

Files

mon@razerRamon:~/tmp/DataRegister$ ll -R
.:
total 16K
drwxrwxr-x 2 mon mon 4.0K Jul 17 13:04 dataleaks/
-rwxrwxr-x 1 mon mon 1.6K Jul 17 13:02 DataRegister.fsx*

./dataleaks:
total 0
mon@razerRamon:~/tmp/DataRegister$

Code Snippet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
(* Ported from Haskell snippet *)
module Data =
type 'a Sensitive = Sensitive of 'a
type 'a Register = private Data of 'a list

let sensitive = Sensitive

let init : unit -> 'a Register =
fun () ->
Data []

let add : 'a -> 'a Register -> 'a Register =
fun x (Data reg) ->
if List.exists (fun y -> x = y) reg then
Data reg
else
Data (x :: reg)

let count : ('a -> bool) -> 'a Register -> int =
fun cond (Data reg) ->
reg
|> List.filter cond
|> List.length

let get : ('a -> 'b) -> ('a -> bool) -> 'a Register -> 'b option =
fun dto cond (Data reg) ->
match List.tryFind cond reg with
| Some x -> Some (dto x)
| None -> None

(* Sensitive data generator *)
module Random =
open System
let private r = new Random()
let next () = r.Next()

open Data
open Random

(* Some domain type *)
type FooBar = { foo : int; bar : int Sensitive; }

let uids = [1 .. 10]

let data =
uids
|> List.fold(
fun a x ->
Data.add
{ foo = x; bar = Data.sensitive (Random.next ()) } a
) (Data.init())

(* Good person *)
let user1 : int option =
data
|> Data.get
(fun { bar = (Sensitive num) } -> num)
(fun x -> x.foo = 7)

(* Bad person *)
let user2 : int option =
let leak : FooBar -> unit =
fun { foo = uid; bar = (Sensitive num) } ->
System.IO.File.WriteAllText(
"./dataleaks/" + (Random.next ()).ToString() + ".log",
sprintf "(%i,%i)\n" uid num
)

data
|> Data.get
(fun { FooBar.bar = (Sensitive num) } -> num)
(fun x -> leak x; x.foo = 7)

(*
Ensure to " ... implement appropriate TECHNICAL and organizational measures,
..., which are DESIGNED to implement data-protection principles, ..., in an
effective manner and to integrate the necessary SAFEGUARDS into the processing
in order to meet the requirements of this Regulation and protect the rights of
data subjects" (Article 25(1) EU GDPR).
*)

Code output:

>
module Data = begin
type 'a Sensitive = | Sensitive of 'a
type 'a Register = private | Data of 'a list
val sensitive : arg0:'a -> 'a Sensitive
val init : unit -> 'a Register
val add : x:'a -> 'a Register -> 'a Register when 'a : equality
val count : cond:('a -> bool) -> 'a Register -> int
val get : dto:('a -> 'b) -> cond:('a -> bool) -> 'a Register -> 'b option
end
module Random = begin
val private r : System.Random
val next : unit -> int
end
type FooBar =
{foo: int;
bar: int Data.Sensitive;}
val uids : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
val data : FooBar Data.Register
val user1 : int option = Some 235432072
val user2 : int option = Some 235432072

Data leak

mon@razerRamon:~/tmp/DataRegister$ ll -R && cat dataleaks/*
.:
total 16K
drwxrwxr-x 2 mon mon 4.0K Jul 17 13:19 dataleaks/
-rwxrwxr-x 1 mon mon 2.3K Jul 17 13:20 DataRegister.fsx*

./dataleaks:
total 48K
-rw-rw-r-- 1 mon mon 15 Jul 17 13:19 1213109609.log
-rw-rw-r-- 1 mon mon 14 Jul 17 13:19 1312310136.log
-rw-rw-r-- 1 mon mon 14 Jul 17 13:19 1690673176.log
-rw-rw-r-- 1 mon mon 14 Jul 17 13:19 801806650.log
(10,996092411)
(8,764617439)
(9,423553051)
(7,235432072)
mon@razerRamon:~/tmp/DataRegister$

References:

comments powered by Disqus