summaryrefslogtreecommitdiff
path: root/internal/transport
diff options
context:
space:
mode:
Diffstat (limited to 'internal/transport')
-rw-r--r--internal/transport/dereference.go7
-rw-r--r--internal/transport/derefinstance.go33
-rw-r--r--internal/transport/finger.go14
3 files changed, 48 insertions, 6 deletions
diff --git a/internal/transport/dereference.go b/internal/transport/dereference.go
index e1702f9f4..3a33a81ad 100644
--- a/internal/transport/dereference.go
+++ b/internal/transport/dereference.go
@@ -64,9 +64,16 @@ func (t *transport) Dereference(ctx context.Context, iri *url.URL) ([]byte, erro
}
defer rsp.Body.Close()
+ // Ensure a non-error status response.
if rsp.StatusCode != http.StatusOK {
return nil, gtserror.NewFromResponse(rsp)
}
+ // Ensure that the incoming request content-type is expected.
+ if ct := rsp.Header.Get("Content-Type"); !apiutil.ASContentType(ct) {
+ err := gtserror.Newf("non activity streams response: %s", ct)
+ return nil, gtserror.SetMalformed(err)
+ }
+
return io.ReadAll(rsp.Body)
}
diff --git a/internal/transport/derefinstance.go b/internal/transport/derefinstance.go
index c6572b727..439c5ae23 100644
--- a/internal/transport/derefinstance.go
+++ b/internal/transport/derefinstance.go
@@ -101,10 +101,17 @@ func dereferenceByAPIV1Instance(ctx context.Context, t *transport, iri *url.URL)
}
defer resp.Body.Close()
+ // Ensure a non-error status response.
if resp.StatusCode != http.StatusOK {
return nil, gtserror.NewFromResponse(resp)
}
+ // Ensure that the incoming request content-type is expected.
+ if ct := resp.Header.Get("Content-Type"); !apiutil.JSONContentType(ct) {
+ err := gtserror.Newf("non json response type: %s", ct)
+ return nil, gtserror.SetMalformed(err)
+ }
+
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
@@ -251,20 +258,27 @@ func callNodeInfoWellKnown(ctx context.Context, t *transport, iri *url.URL) (*ur
}
defer resp.Body.Close()
+ // Ensure a non-error status response.
if resp.StatusCode != http.StatusOK {
return nil, gtserror.NewFromResponse(resp)
}
+ // Ensure that the incoming request content-type is expected.
+ if ct := resp.Header.Get("Content-Type"); !apiutil.JSONContentType(ct) {
+ err := gtserror.Newf("non json response type: %s", ct)
+ return nil, gtserror.SetMalformed(err)
+ }
+
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
} else if len(b) == 0 {
- return nil, errors.New("callNodeInfoWellKnown: response bytes was len 0")
+ return nil, gtserror.New("response bytes was len 0")
}
wellKnownResp := &apimodel.WellKnownResponse{}
if err := json.Unmarshal(b, wellKnownResp); err != nil {
- return nil, fmt.Errorf("callNodeInfoWellKnown: could not unmarshal server response as WellKnownResponse: %s", err)
+ return nil, gtserror.Newf("could not unmarshal server response as WellKnownResponse: %w", err)
}
// look through the links for the first one that matches the nodeinfo schema, this is what we need
@@ -275,11 +289,11 @@ func callNodeInfoWellKnown(ctx context.Context, t *transport, iri *url.URL) (*ur
}
nodeinfoHref, err = url.Parse(l.Href)
if err != nil {
- return nil, fmt.Errorf("callNodeInfoWellKnown: couldn't parse url %s: %s", l.Href, err)
+ return nil, gtserror.Newf("couldn't parse url %s: %w", l.Href, err)
}
}
if nodeinfoHref == nil {
- return nil, errors.New("callNodeInfoWellKnown: could not find nodeinfo rel in well known response")
+ return nil, gtserror.New("could not find nodeinfo rel in well known response")
}
return nodeinfoHref, nil
@@ -302,20 +316,27 @@ func callNodeInfo(ctx context.Context, t *transport, iri *url.URL) (*apimodel.No
}
defer resp.Body.Close()
+ // Ensure a non-error status response.
if resp.StatusCode != http.StatusOK {
return nil, gtserror.NewFromResponse(resp)
}
+ // Ensure that the incoming request content-type is expected.
+ if ct := resp.Header.Get("Content-Type"); !apiutil.NodeInfo2ContentType(ct) {
+ err := gtserror.Newf("non nodeinfo schema 2.0 response: %s", ct)
+ return nil, gtserror.SetMalformed(err)
+ }
+
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
} else if len(b) == 0 {
- return nil, errors.New("callNodeInfo: response bytes was len 0")
+ return nil, gtserror.New("response bytes was len 0")
}
niResp := &apimodel.Nodeinfo{}
if err := json.Unmarshal(b, niResp); err != nil {
- return nil, fmt.Errorf("callNodeInfo: could not unmarshal server response as Nodeinfo: %s", err)
+ return nil, gtserror.Newf("could not unmarshal server response as Nodeinfo: %w", err)
}
return niResp, nil
diff --git a/internal/transport/finger.go b/internal/transport/finger.go
index 385af5e1c..9bcb0fa7e 100644
--- a/internal/transport/finger.go
+++ b/internal/transport/finger.go
@@ -98,9 +98,17 @@ func (t *transport) Finger(ctx context.Context, targetUsername string, targetDom
// again here to renew the TTL
t.controller.state.Caches.GTS.Webfinger.Set(targetDomain, url)
}
+
if rsp.StatusCode == http.StatusGone {
return nil, fmt.Errorf("account has been deleted/is gone")
}
+
+ // Ensure that the incoming request content-type is expected.
+ if ct := rsp.Header.Get("Content-Type"); !apiutil.JSONJRDContentType(ct) {
+ err := gtserror.Newf("non webfinger type response: %s", ct)
+ return nil, gtserror.SetMalformed(err)
+ }
+
return io.ReadAll(rsp.Body)
}
@@ -193,6 +201,12 @@ func (t *transport) webfingerFromHostMeta(ctx context.Context, targetDomain stri
return "", fmt.Errorf("GET request for %s failed: %s", req.URL.String(), rsp.Status)
}
+ // Ensure that the incoming request content-type is expected.
+ if ct := rsp.Header.Get("Content-Type"); !apiutil.XMLXRDContentType(ct) {
+ err := gtserror.Newf("non host-meta type response: %s", ct)
+ return "", gtserror.SetMalformed(err)
+ }
+
e := xml.NewDecoder(rsp.Body)
var hm apimodel.HostMeta
if err := e.Decode(&hm); err != nil {