fix: sanitize error - #2269
Conversation
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
…nitize-error Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
…nitize-error Signed-off-by: Pawel Stepien <pawel.stepien@digitalasset.com>
| return | ||
| } | ||
|
|
||
| res.status(500).json({ error: 'Internal Server Error' }) |
There was a problem hiding this comment.
Is it not possible to tie this to the request somehow?
Or are we relying on the fact that logs should be written and tied to the request id at the place where the error happens?
There was a problem hiding this comment.
I don't think we can fully rely on logs from all potential places error can come from as a way to correlate error with request. I am inclined to add request info next to the error in logger.error at the top of that handler. But I'm reluctant to just add whole request body and even more so headers to the log, because I'm worried about persisting sensitive information in logs. I'm thinking maybe a subset of request info like:
- http method
- http url path
- json rpc method (if present)
- json rpc id (if present)
- maybe boolean hasAuthContext, without leaking authContext details like
accessToken
What do you think? It could guide us to api and method that caused the unhandled error, but unfortunately not exactly what was in the payload.
| } | ||
|
|
||
| // Catches unhandled errors and prevents internal details like stack trace from reaching end user | ||
| export function errorHandler( |
There was a problem hiding this comment.
Why is this separate from handleRpcError in jsonRpcHandler.ts?
There was a problem hiding this comment.
Because jsonRpcHandler wouldn't know about errors thrown anywhere else but controller. Issue this PR originated from reports a runtime error from sessionHandler middleware. When an error is thrown (or next(err) is called) along the journey of request through middlewares, express looks for closest next error middleware (a middleware that has four args: err, req, res, next). We didn't have one, so the error went straight to default express error handler and it responded with a verbose JS error in body.
I think it's a standard pattern to have one general error handler at the end of chain that would catch unexpected errors.
There was a problem hiding this comment.
Ok makes sense to me, thanks. I think still think it would be good for @alexmatson-da to have a look here, given that he is the author of jsonRpcHandler
Error handling fixes:
Was:
Now:
{"jsonrpc":"2.0","id":1,"error":{"code":4100,"message":"No active session found"}}sessionHandler now checks that there is accessToken attached to request and returns 401 early if not. Before it failed at store level.
Made JSON-RPC errors preserve their custom message. It was getting lost in
handleRpcError.Was:
{"jsonrpc":"2.0","id":null,"error":{"code":-32601}}Now:
{"jsonrpc":"2.0","id":null,"error":{"code":-32601,"message":"Method thisMethodDoesNotExist not found"}}Changed sessionHandler and jwtAuth to return auth failures in the JSON-RPC error shape. They previously returned
{"error": "<message>"}, which fails ErrorResponse validation in HttpTransport, so clients discarded the real reason and fell back to a generic message derived from the HTTP status.Stopped attaching the thrown error to error.data. handleRpcError put the raw error object into the response, which could leak sensitive internals. Full error still gets logged.
Verified by unit test
forwards the Error message but not the error object itselfAdditional fixes not related to issue:
Fixed middleware not applying properly to endpoints, if dapp or user api was configured to have path that doesn't start with
/api.Renamed
userPathtouserApiUrlin wallet-gateway-configuration endpoint, because it's actually full url not just path and it's consistent with dappApiUrl.