Skip to content

Commit 03038ea

Browse files
committed
Obfuscate WHIP ids.
If the WHIP session is not authenticated, then the only thing preventing an attacker from DELETEing the session is the session URL. Since client ids are known, obfuscate the id before using it in the session URL.
1 parent 9f3bee8 commit 03038ea

File tree

2 files changed

+86
-4
lines changed

2 files changed

+86
-4
lines changed

webserver/webserver_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,23 @@ func TestFormatICEServer(t *testing.T) {
136136
})
137137
}
138138
}
139+
140+
func TestObfuscate(t *testing.T) {
141+
id := newId()
142+
obfuscated, err := obfuscate(id)
143+
if err != nil {
144+
t.Fatalf("obfuscate: %v", err)
145+
}
146+
id2, err := deobfuscate(obfuscated)
147+
if err != nil {
148+
t.Fatalf("deobfuscate: %v", err)
149+
}
150+
if id != id2 {
151+
t.Errorf("not equal: %v, %v", id, id2)
152+
}
153+
154+
_, err = obfuscate("toto")
155+
if err == nil {
156+
t.Errorf("obfuscate: no errror")
157+
}
158+
}

webserver/whip.go

+66-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package webserver
22

33
import (
44
"bytes"
5+
"crypto/aes"
6+
"crypto/cipher"
57
crand "crypto/rand"
68
"encoding/base64"
9+
"errors"
710
"fmt"
811
"io"
912
"log"
@@ -37,12 +40,58 @@ func parseWhip(pth string) (string, string) {
3740
return "", ""
3841
}
3942

43+
var idSecret []byte
44+
var idCipher cipher.Block
45+
46+
func init() {
47+
idSecret = make([]byte, 16)
48+
_, err := crand.Read(idSecret)
49+
if err != nil {
50+
log.Fatalf("crand.Read: %v", err)
51+
}
52+
idCipher, err = aes.NewCipher(idSecret)
53+
if err != nil {
54+
log.Fatalf("NewCipher: %v", err)
55+
}
56+
}
57+
4058
func newId() string {
41-
b := make([]byte, 16)
59+
b := make([]byte, idCipher.BlockSize())
4260
crand.Read(b)
4361
return base64.RawURLEncoding.EncodeToString(b)
4462
}
4563

64+
// we obfuscate ids to avoid exposing the WHIP session URL
65+
func obfuscate(id string) (string, error) {
66+
v, err := base64.RawURLEncoding.DecodeString(id)
67+
if err != nil {
68+
return "", err
69+
}
70+
71+
if len(v) != idCipher.BlockSize() {
72+
return "", errors.New("bad length")
73+
}
74+
75+
idCipher.Encrypt(v, v)
76+
77+
return base64.RawURLEncoding.EncodeToString(v), nil
78+
}
79+
80+
func deobfuscate(id string) (string, error) {
81+
v, err := base64.RawURLEncoding.DecodeString(id)
82+
if err != nil {
83+
return "", err
84+
}
85+
86+
if len(v) != idCipher.BlockSize() {
87+
return "", errors.New("bad length")
88+
}
89+
90+
idCipher.Decrypt(v, v)
91+
92+
return base64.RawURLEncoding.EncodeToString(v), nil
93+
}
94+
4695
func canPresent(perms []string) bool {
4796
for _, p := range perms {
4897
if p == "present" {
@@ -186,6 +235,13 @@ func whipEndpointHandler(w http.ResponseWriter, r *http.Request) {
186235
}
187236

188237
id := newId()
238+
obfuscated, err := obfuscate(id)
239+
if err != nil {
240+
http.Error(w, "Internal Server Error",
241+
http.StatusInternalServerError)
242+
return
243+
}
244+
189245
c := rtpconn.NewWhipClient(g, id, token)
190246

191247
_, err = group.AddClient(g.Name(), c, creds)
@@ -214,7 +270,7 @@ func whipEndpointHandler(w http.ResponseWriter, r *http.Request) {
214270
http.StatusInternalServerError)
215271
}
216272

217-
w.Header().Set("Location", path.Join(r.URL.Path, id))
273+
w.Header().Set("Location", path.Join(r.URL.Path, obfuscated))
218274
w.Header().Set("Access-Control-Expose-Headers",
219275
"Location, Content-Type, Link")
220276
whipICEServers(w)
@@ -226,8 +282,14 @@ func whipEndpointHandler(w http.ResponseWriter, r *http.Request) {
226282
}
227283

228284
func whipResourceHandler(w http.ResponseWriter, r *http.Request) {
229-
pth, id := parseWhip(r.URL.Path)
230-
if pth == "" || id == "" {
285+
pth, obfuscated := parseWhip(r.URL.Path)
286+
if pth == "" || obfuscated == "" {
287+
http.Error(w, "Internal server error",
288+
http.StatusInternalServerError)
289+
return
290+
}
291+
id, err := deobfuscate(obfuscated)
292+
if err != nil {
231293
http.Error(w, "Internal server error",
232294
http.StatusInternalServerError)
233295
return

0 commit comments

Comments
 (0)