Skip to content

Commit c533126

Browse files
authored
fix: Vulnerability in backend's handleRequest function (kyma-project#3788)
* fix: dont both pipe and end request * revert some previous changes
1 parent 018e75d commit c533126

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

backend/common.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const makeHandleRequest = () => {
6464
headersData = extractHeadersData(req);
6565
} catch (e) {
6666
req.log.error('Headers error:' + e.message);
67-
res.contentType('text/plain');
67+
res.contentType('text/plain; charset=utf-8');
6868
res.status(400).send('Headers are missing or in a wrong format.');
6969
return;
7070
}
@@ -73,7 +73,7 @@ export const makeHandleRequest = () => {
7373
filters.forEach(filter => filter(req, headersData));
7474
} catch (e) {
7575
req.log.error('Filters rejected the request: ' + e.message);
76-
res.contentType('text/plain');
76+
res.contentType('text/plain; charset=utf-8');
7777
res.status(400).send('Request ID: ' + escape(req.id));
7878
return;
7979
}
@@ -88,7 +88,6 @@ export const makeHandleRequest = () => {
8888
hostname: targetApiServer.hostname,
8989
path: req.originalUrl.replace(/^\/backend/, ''),
9090
headers,
91-
body: req.body,
9291
method: req.method,
9392
port: targetApiServer.port || 443,
9493
ca,
@@ -111,19 +110,31 @@ export const makeHandleRequest = () => {
111110
const statusCode =
112111
k8sResponse.statusCode === 503 ? 502 : k8sResponse.statusCode;
113112

113+
// Ensure charset is specified in content type
114+
let contentType = k8sResponse.headers['Content-Type'] || 'text/json';
115+
if (!contentType.includes('charset=')) {
116+
contentType += '; charset=utf-8';
117+
}
118+
114119
res.writeHead(statusCode, {
115-
'Content-Type': k8sResponse.headers['Content-Type'] || 'text/json',
120+
'Content-Type': contentType,
116121
'Content-Encoding': k8sResponse.headers['content-encoding'] || '',
122+
'X-Content-Type-Options': 'nosniff',
117123
});
118124
k8sResponse.pipe(res);
119125
});
120126
k8sRequest.on('error', throwInternalServerError); // no need to sanitize the error here as the http.request() will never throw a vulnerable error
121-
k8sRequest.end(Buffer.isBuffer(req.body) ? req.body : undefined);
122-
req.pipe(k8sRequest);
127+
128+
if (Buffer.isBuffer(req.body)) {
129+
k8sRequest.end(req.body);
130+
} else {
131+
// If there's no body, pipe the request (for streaming)
132+
req.pipe(k8sRequest);
133+
}
123134

124135
function throwInternalServerError(originalError) {
125136
req.log.warn(originalError);
126-
res.contentType('text/plain');
137+
res.contentType('text/plain; charset=utf-8');
127138
res
128139
.status(502)
129140
.send('Internal server error. Request ID: ' + escape(req.id));

0 commit comments

Comments
 (0)