-
Notifications
You must be signed in to change notification settings - Fork 535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug][devLake config UI] secure PAT is exposed in network tab #7821
Comments
@yurii-chikh-vitech Hello there! I'm here to help you with any bugs, questions, or contributions you may have. Let's work together to resolve the issue you've encountered. To prevent the secure Personal Access Token (PAT) from being exposed in the network tab for the request to the URL One common approach is to use a backend service to handle the token securely. The frontend can make a request to the backend, which then adds the token and forwards the request to the GitLab API. This way, the token is never exposed to the client-side code or network tab. Here is a simplified example of how you might implement this:
// backend-service.js
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/api/gitlab/scopes', async (req, res) => {
const { page, pageSize, blueprints } = req.query;
const token = process.env.GITLAB_PAT; // Securely stored token
try {
const response = await axios.get(`https://gitlab.com/api/v4/projects`, {
params: { page, pageSize, blueprints },
headers: {
'Authorization': `Bearer ${token}`
}
});
res.json(response.data);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(4000, () => {
console.log('Backend service running on port 4000');
});
// config.tsx
import axios from 'axios';
const fetchGitLabScopes = async (page, pageSize, blueprints) => {
try {
const response = await axios.get(`http://localhost:4000/api/gitlab/scopes`, {
params: { page, pageSize, blueprints }
});
return response.data;
} catch (error) {
console.error('Error fetching GitLab scopes:', error);
throw error;
}
};
// Usage example
fetchGitLabScopes(1, 10, true).then(data => {
console.log('GitLab Scopes:', data);
}); Additionally, in the DevLake configuration UI, you can use the import { useState, useContext, useEffect, useMemo } from 'react';
import { Flex, Button, Tooltip } from 'antd';
import API from '@/api';
import { Markdown } from '@/components';
import { getPluginConfig } from '@/plugins';
import { ConnectionToken } from '@/plugins/components/connection-form/fields/token';
import { operator } from '@/utils';
import { Context } from './context';
import * as S from './styled';
const paramsMap: Record<string, any> = {
github: {
authMethod: 'AccessToken',
endpoint: 'https://api.github.com/',
},
gitlab: {
endpoint: 'https://gitlab.com/api/v4/',
},
bitbucket: {
endpoint: 'https://api.bitbucket.org/2.0/',
},
azuredevops: {},
};
export const Step2 = () => {
const [QA, setQA] = useState('');
const [operating, setOperating] = useState(false);
const [testing, setTesting] = useState(false);
const [testStaus, setTestStatus] = useState(false);
const [payload, setPayload] = useState<any>({});
const { step, records, done, projectName, plugin, setStep, setRecords } = useContext(Context);
const config = useMemo(() => getPluginConfig(plugin as string), [plugin]);
useEffect(() => {
fetch(`/onboard/step-2/${plugin}.md`)
.then((res) => res.text())
.then((text) => setQA(text));
}, [plugin]);
const handleTest = async () => {
if (!plugin) {
return;
}
const [success] = await operator(
async () =>
await API.connection.testOld(plugin, {
...paramsMap[plugin],
...payload,
}),
{
setOperating: setTesting,
formatMessage: () => 'Connection success.',
formatReason: () => 'Connection failed. Please check your token or network.',
},
);
if (success) {
setTestStatus(true);
}
};
const handleSubmit = async () => {
if (!plugin) {
return;
}
const [success] = await operator(
async () => {
const connection = await API.connection.create(plugin, {
name: `${plugin}-${Date.now()}`,
...paramsMap[plugin],
...payload,
});
const newRecords = [
...records,
{ plugin, connectionId: connection.id, blueprintId: '', pipelineId: '', scopeName: '' },
];
setRecords(newRecords);
await API.store.set('onboard', {
step: 3,
records: newRecords,
done,
projectName,
plugin,
});
},
{
setOperating,
hideToast: true,
},
);
if (success) {
setStep(step + 1);
}
};
if (!plugin) {
return null;
}
return (
<>
<S.StepContent>
{['github', 'gitlab', 'azuredevops'].includes(plugin) && (
<div className="content">
<ConnectionToken
type="create"
label="Personal Access Token"
subLabel={`Create a personal access token in ${config.name}`}
initialValue=""
value={payload.token}
setValue={(token) => {
setPayload({ ...payload, token });
setTestStatus(false);
}}
error=""
setError={() => {}}
/>
<Tooltip title="Test Connection">
<Button
style={{ marginTop: 16 }}
type="primary"
disabled={!payload.token}
loading={testing}
onClick={handleTest}
>
Connect
</Button>
</Tooltip>
</div>
)}
<Markdown className="qa">{QA}</Markdown>
</S.StepContent>
<Flex style={{ marginTop: 36 }} justify="space-between">
<Button ghost type="primary" loading={operating} onClick={() => setStep(step - 1)}>
Previous Step
</Button>
<Button type="primary" loading={operating} disabled={!testStaus} onClick={handleSubmit}>
Next Step
</Button>
</Flex>
</>
);
}; By using this approach, the Personal Access Token (PAT) is kept secure on the server side and is not exposed in the network tab of the browser's developer tools [1][2]. |
Aah.. I agree.... |
@yurii-chikh-vitech I just removed the screenshot, please revoke the token ASAP if it was not revoked already. |
@klesh Token is old and revoked. |
@yurii-chikh-vitech I think it was fixed in #7767, all codes are cherry picked to v1.0. which version are you using? I can help to check. |
@d4x1 v1.0 |
|
@d4x1 v1.0.0 |
@yurii-chikh-vitech You can try the latest version(https://github.com/apache/incubator-devlake/releases/tag/v1.0.1-beta9). It has been fixed. |
#2800 was similar in the past. |
Search before asking
What happened
Secure PAT token exposed in network tab for request http://localhost:4000/api/plugins/gitlab/connections/1/scopes?page=1&pageSize=10&blueprints=true
What do you expect to happen
PAT should not be exposed
How to reproduce
Explore network tab on connection settings page.
http://localhost:4000/api/plugins/gitlab/connections/1/scopes?page=1&pageSize=10&blueprints=true
Anything else
No response
Version
v1.0
Are you willing to submit PR?
Code of Conduct
The text was updated successfully, but these errors were encountered: