mirror of
https://github.com/microsoft/Web-Dev-For-Beginners.git
synced 2025-08-23 06:44:49 +02:00
Implement security improvements and add security audit report
Co-authored-by: softchris <4598064+softchris@users.noreply.github.com>
This commit is contained in:
@@ -1,28 +1,35 @@
|
|||||||
name: Azure Static Web Apps CI/CD
|
name: Azure Static Web Apps CI/CD
|
||||||
|
|
||||||
on: workflow_dispatch
|
on: workflow_dispatch
|
||||||
|
|
||||||
jobs:
|
# SECURITY NOTE: This workflow uses repository permissions to access secrets
|
||||||
build_and_deploy_job:
|
# Keep the scope of permissions to the minimum required for the workflow
|
||||||
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
|
permissions:
|
||||||
runs-on: ubuntu-latest
|
contents: read
|
||||||
name: Build and Deploy Job
|
pull-requests: write # Needed for static web app deploy comments
|
||||||
steps:
|
statuses: write # Needed for status checks
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
jobs:
|
||||||
submodules: true
|
build_and_deploy_job:
|
||||||
- name: Build And Deploy
|
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
|
||||||
id: builddeploy
|
runs-on: ubuntu-latest
|
||||||
uses: Azure/static-web-apps-deploy@v1
|
name: Build and Deploy Job
|
||||||
with:
|
steps:
|
||||||
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_RIVER_0DEBB7803 }}
|
- uses: actions/checkout@v3
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
|
with:
|
||||||
action: "upload"
|
submodules: true
|
||||||
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
|
- name: Build And Deploy
|
||||||
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
|
id: builddeploy
|
||||||
app_location: "/quiz-app" # App source code path
|
uses: Azure/static-web-apps-deploy@v1
|
||||||
api_location: "" # Api source code path - optional
|
with:
|
||||||
output_location: "dist" # Built app content directory - optional
|
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_RIVER_0DEBB7803 }}
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
|
||||||
|
action: "upload"
|
||||||
|
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
|
||||||
|
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
|
||||||
|
app_location: "/quiz-app" # App source code path
|
||||||
|
api_location: "" # Api source code path - optional
|
||||||
|
output_location: "dist" # Built app content directory - optional
|
||||||
###### End of Repository/Build Configurations ######
|
###### End of Repository/Build Configurations ######
|
||||||
|
|
||||||
close_pull_request_job:
|
close_pull_request_job:
|
||||||
|
@@ -73,6 +73,17 @@ CO2 Signal's API.
|
|||||||
|
|
||||||
✅ Learn more about package management in this [excellent Learn module](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon)
|
✅ Learn more about package management in this [excellent Learn module](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon)
|
||||||
|
|
||||||
|
### Security Best Practices
|
||||||
|
|
||||||
|
When working with browser extensions, it's important to follow security best practices:
|
||||||
|
|
||||||
|
1. **Minimize permissions**: Request only the permissions your extension needs. Use specific host permissions instead of `<all_urls>`.
|
||||||
|
2. **Secure API key storage**: Never store API keys or credentials in your source code. Use `chrome.storage.sync` API instead of `localStorage` for sensitive data.
|
||||||
|
3. **Input validation**: Always validate and sanitize user input to prevent injection attacks.
|
||||||
|
4. **Keep dependencies updated**: Regularly audit and update your dependencies to address security vulnerabilities.
|
||||||
|
|
||||||
|
For more information, see [Chrome extension security practices](https://developer.chrome.com/docs/extensions/mv3/security/).
|
||||||
|
|
||||||
Take a minute to look through the codebase:
|
Take a minute to look through the codebase:
|
||||||
|
|
||||||
dist
|
dist
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "My Carbon Trigger",
|
"name": "My Carbon Trigger",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"host_permissions": ["<all_urls>"],
|
"host_permissions": [
|
||||||
|
"https://api.co2signal.com/v1/*"
|
||||||
|
],
|
||||||
"background": {
|
"background": {
|
||||||
"service_worker": "background.js"
|
"service_worker": "background.js"
|
||||||
},
|
},
|
||||||
|
@@ -24,6 +24,6 @@
|
|||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.7.4"
|
"axios": "^1.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { storeApiKey, getApiKey, storeRegion, getRegion, clearStoredData } from './security.js';
|
||||||
|
|
||||||
// form fields
|
// form fields
|
||||||
const form = document.querySelector('.form-data');
|
const form = document.querySelector('.form-data');
|
||||||
@@ -68,8 +69,8 @@ const displayCarbonUsage = async (apiKey, region) => {
|
|||||||
|
|
||||||
// set up api key and region
|
// set up api key and region
|
||||||
const setUpUser = async (apiKey, region) => {
|
const setUpUser = async (apiKey, region) => {
|
||||||
localStorage.setItem('apiKey', apiKey);
|
storeApiKey(apiKey);
|
||||||
localStorage.setItem('region', region);
|
storeRegion(region);
|
||||||
loading.style.display = 'block';
|
loading.style.display = 'block';
|
||||||
errors.textContent = '';
|
errors.textContent = '';
|
||||||
clearBtn.style.display = 'block';
|
clearBtn.style.display = 'block';
|
||||||
@@ -86,8 +87,8 @@ const handleSubmit = async (e) => {
|
|||||||
//initial checks
|
//initial checks
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
//if anything is in localStorage, pick it up
|
//if anything is in localStorage, pick it up
|
||||||
const storedApiKey = localStorage.getItem('apiKey');
|
const storedApiKey = getApiKey();
|
||||||
const storedRegion = localStorage.getItem('region');
|
const storedRegion = getRegion();
|
||||||
|
|
||||||
//set icon to be generic green
|
//set icon to be generic green
|
||||||
chrome.runtime.sendMessage({
|
chrome.runtime.sendMessage({
|
||||||
@@ -116,7 +117,7 @@ const init = async () => {
|
|||||||
const reset = async (e) => {
|
const reset = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
//clear local storage for region only
|
//clear local storage for region only
|
||||||
localStorage.removeItem('region');
|
clearStoredData('region');
|
||||||
init();
|
init();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
79
5-browser-extension/solution/src/security.js
Normal file
79
5-browser-extension/solution/src/security.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* Security utilities for the browser extension
|
||||||
|
*
|
||||||
|
* SECURITY NOTE: In a production environment, you should use the Chrome extension's
|
||||||
|
* chrome.storage.sync API with proper encryption rather than localStorage for sensitive data.
|
||||||
|
* https://developer.chrome.com/docs/extensions/reference/storage/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Securely store an API key
|
||||||
|
* @param {string} apiKey - The API key to store
|
||||||
|
*/
|
||||||
|
export const storeApiKey = (apiKey) => {
|
||||||
|
// SECURITY NOTE: In production, implement additional protection
|
||||||
|
// such as encryption before storage
|
||||||
|
try {
|
||||||
|
// For educational purposes, we're still using localStorage
|
||||||
|
localStorage.setItem('apiKey', apiKey);
|
||||||
|
console.log('API key stored (Note: localStorage is not secure for sensitive data)');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error storing API key:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a stored API key
|
||||||
|
* @returns {string|null} The stored API key or null if not found
|
||||||
|
*/
|
||||||
|
export const getApiKey = () => {
|
||||||
|
try {
|
||||||
|
return localStorage.getItem('apiKey');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error retrieving API key:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store region information
|
||||||
|
* @param {string} region - The region to store
|
||||||
|
*/
|
||||||
|
export const storeRegion = (region) => {
|
||||||
|
try {
|
||||||
|
localStorage.setItem('region', region);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error storing region:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve stored region information
|
||||||
|
* @returns {string|null} The stored region or null if not found
|
||||||
|
*/
|
||||||
|
export const getRegion = () => {
|
||||||
|
try {
|
||||||
|
return localStorage.getItem('region');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error retrieving region:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear stored security information
|
||||||
|
* @param {string} key - The specific key to clear (optional)
|
||||||
|
*/
|
||||||
|
export const clearStoredData = (key) => {
|
||||||
|
try {
|
||||||
|
if (key) {
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
} else {
|
||||||
|
// Be careful with clear() as it removes all data
|
||||||
|
localStorage.removeItem('apiKey');
|
||||||
|
localStorage.removeItem('region');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error clearing stored data:', error);
|
||||||
|
}
|
||||||
|
};
|
@@ -24,6 +24,6 @@
|
|||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.7.4"
|
"axios": "^1.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,9 +20,9 @@
|
|||||||
"prettier": "^2.0.5"
|
"prettier": "^2.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": "^1.20.1",
|
"body-parser": "^1.20.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.19.2"
|
"express": "^4.18.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
|
@@ -27,9 +27,36 @@ const db = {
|
|||||||
const app = express();
|
const app = express();
|
||||||
app.use(bodyParser.urlencoded({ extended: true }));
|
app.use(bodyParser.urlencoded({ extended: true }));
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use(cors({ origin: /http:\/\/(127(\.\d){3}|localhost)/}));
|
|
||||||
|
// SECURITY NOTE: In a production environment, you should specify exact origins
|
||||||
|
// rather than allowing all localhost and 127.x.x.x addresses
|
||||||
|
// For more information: https://owasp.org/www-project-cheat-sheets/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
|
||||||
|
app.use(cors({
|
||||||
|
origin: /http:\/\/(127(\.\d){3}|localhost)/,
|
||||||
|
methods: ['GET', 'POST', 'DELETE'],
|
||||||
|
allowedHeaders: ['Content-Type', 'Authorization']
|
||||||
|
}));
|
||||||
app.options('*', cors());
|
app.options('*', cors());
|
||||||
|
|
||||||
|
// SECURITY NOTE: In production, you should:
|
||||||
|
// 1. Enforce HTTPS with a middleware like:
|
||||||
|
// app.use((req, res, next) => {
|
||||||
|
// if (!req.secure && req.get('x-forwarded-proto') !== 'https' && process.env.NODE_ENV === 'production') {
|
||||||
|
// return res.redirect('https://' + req.get('host') + req.url);
|
||||||
|
// }
|
||||||
|
// next();
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// 2. Implement proper authentication with JWT, OAuth, etc.
|
||||||
|
// For more information: https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
|
||||||
|
//
|
||||||
|
// 3. Add rate limiting to prevent abuse:
|
||||||
|
// const rateLimit = require('express-rate-limit');
|
||||||
|
// app.use(rateLimit({
|
||||||
|
// windowMs: 15 * 60 * 1000, // 15 minutes
|
||||||
|
// max: 100 // limit each IP to 100 requests per windowMs
|
||||||
|
// }));
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
// Configure routes
|
// Configure routes
|
||||||
@@ -123,6 +150,19 @@ router.post('/accounts/:user/transactions', (req, res) => {
|
|||||||
return res.status(400).json({ error: 'Missing parameters' });
|
return res.status(400).json({ error: 'Missing parameters' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SECURITY NOTE: In production, validate date format to prevent injection attacks
|
||||||
|
// Example: use a library like date-fns to validate proper date format
|
||||||
|
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
|
||||||
|
if (!dateRegex.test(req.body.date)) {
|
||||||
|
return res.status(400).json({ error: 'Invalid date format. Use YYYY-MM-DD' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// SECURITY NOTE: In production, sanitize object field to prevent XSS
|
||||||
|
// Example: use a library like DOMPurify
|
||||||
|
if (typeof req.body.object !== 'string' || req.body.object.length > 100) {
|
||||||
|
return res.status(400).json({ error: 'Object must be a string with max length of 100' });
|
||||||
|
}
|
||||||
|
|
||||||
// Convert amount to number if needed
|
// Convert amount to number if needed
|
||||||
let amount = req.body.amount;
|
let amount = req.body.amount;
|
||||||
if (amount && typeof amount !== 'number') {
|
if (amount && typeof amount !== 'number') {
|
||||||
|
17
README.md
17
README.md
@@ -190,6 +190,23 @@ Our team produces other courses! Check out:
|
|||||||
- [Mastering GitHub Copilot for C#/.NET Developers](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
|
- [Mastering GitHub Copilot for C#/.NET Developers](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
|
||||||
- [Choose Your Own Copilot Adventure](https://github.com/microsoft/CopilotAdventures)
|
- [Choose Your Own Copilot Adventure](https://github.com/microsoft/CopilotAdventures)
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
This repository contains educational code examples which are not intended for production use. When adapting these examples for real-world applications, please follow security best practices:
|
||||||
|
|
||||||
|
1. **Input Validation**: Always validate and sanitize user inputs to prevent injection attacks.
|
||||||
|
2. **API Security**: Protect API keys and credentials using environment variables or secure storage.
|
||||||
|
3. **HTTPS**: Enforce HTTPS for all production applications.
|
||||||
|
4. **Authentication**: Implement proper authentication and authorization mechanisms.
|
||||||
|
5. **Dependencies**: Regularly update and audit dependencies for vulnerabilities using tools like npm audit.
|
||||||
|
|
||||||
|
For more information about security practices:
|
||||||
|
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
|
||||||
|
- [MDN Web Security](https://developer.mozilla.org/en-US/docs/Web/Security)
|
||||||
|
- [Microsoft Security Development Lifecycle](https://www.microsoft.com/en-us/securityengineering/sdl/)
|
||||||
|
|
||||||
|
See our [SECURITY.md](SECURITY.md) file for information about reporting security vulnerabilities.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This repository is licensed under the MIT license. See the [LICENSE](LICENSE) file for more information.
|
This repository is licensed under the MIT license. See the [LICENSE](LICENSE) file for more information.
|
||||||
|
148
SECURITY-AUDIT.md
Normal file
148
SECURITY-AUDIT.md
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
# Security Audit Report
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
This security audit was performed on the Web-Dev-For-Beginners repository, which contains various code examples and projects for learning web development. The repository includes JavaScript, HTML, and CSS code across multiple small projects including a quiz application, a browser extension, and a banking application API.
|
||||||
|
|
||||||
|
**Methodology**: The audit was conducted using static code analysis, dependency scanning, and manual review. Security best practices from OWASP, NIST, and Azure Well-Architected Framework were used as reference.
|
||||||
|
|
||||||
|
## Detailed Findings
|
||||||
|
|
||||||
|
### 1. Source-code Vulnerabilities
|
||||||
|
|
||||||
|
#### 1.1 CORS Misconfiguration
|
||||||
|
|
||||||
|
- **Description**: Overly permissive CORS configuration in the bank API project allowing any localhost or 127.x.x.x connection.
|
||||||
|
- **Severity**: Medium
|
||||||
|
- **File/Location**: `/7-bank-project/api/server.js` (line 30)
|
||||||
|
- **Code snippet**:
|
||||||
|
```javascript
|
||||||
|
app.use(cors({ origin: /http:\/\/(127(\.\d){3}|localhost)/}));
|
||||||
|
app.options('*', cors());
|
||||||
|
```
|
||||||
|
- **Recommendation**: Restrict CORS to specific origins needed for the application. For a learning environment, clearly document that this configuration is not suitable for production. See [OWASP CORS Guidelines](https://owasp.org/www-project-cheat-sheets/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html).
|
||||||
|
|
||||||
|
#### 1.2 Insecure Data Storage
|
||||||
|
|
||||||
|
- **Description**: Browser extension stores API keys in localStorage, which is not secure for sensitive information.
|
||||||
|
- **Severity**: Medium
|
||||||
|
- **File/Location**: `/5-browser-extension/solution/src/index.js` (lines 71-72)
|
||||||
|
- **Code snippet**:
|
||||||
|
```javascript
|
||||||
|
localStorage.setItem('apiKey', apiKey);
|
||||||
|
localStorage.setItem('region', region);
|
||||||
|
```
|
||||||
|
- **Recommendation**: For educational purposes, include a comment highlighting the security implications of storing sensitive data in localStorage. For production extensions, suggest using the Chrome extension secure storage API. Reference: [MDN Web Storage Security](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#security).
|
||||||
|
|
||||||
|
#### 1.3 Overly Permissive Host Permissions
|
||||||
|
|
||||||
|
- **Description**: Browser extension requests permissions to all URLs, which violates the principle of least privilege.
|
||||||
|
- **Severity**: High
|
||||||
|
- **File/Location**: `/5-browser-extension/solution/dist/manifest.json` (line 5)
|
||||||
|
- **Code snippet**:
|
||||||
|
```json
|
||||||
|
"host_permissions": ["<all_urls>"],
|
||||||
|
```
|
||||||
|
- **Recommendation**: Restrict permissions to only the API domain needed for functionality (e.g., "https://api.co2signal.com/*"). See [Google's extension permission best practices](https://developer.chrome.com/docs/extensions/mv3/security/).
|
||||||
|
|
||||||
|
#### 1.4 Lack of Input Validation
|
||||||
|
|
||||||
|
- **Description**: Insufficient input validation in the bank API project for user-provided data in transaction creation.
|
||||||
|
- **Severity**: Medium
|
||||||
|
- **File/Location**: `/7-bank-project/api/server.js` (lines 121-135)
|
||||||
|
- **Code snippet**:
|
||||||
|
```javascript
|
||||||
|
// Check mandatory requests parameters
|
||||||
|
if (!req.body.date || !req.body.object || !req.body.amount) {
|
||||||
|
return res.status(400).json({ error: 'Missing parameters' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert amount to number if needed
|
||||||
|
let amount = req.body.amount;
|
||||||
|
if (amount && typeof amount !== 'number') {
|
||||||
|
amount = parseFloat(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that amount is a valid number
|
||||||
|
if (amount && isNaN(amount)) {
|
||||||
|
return res.status(400).json({ error: 'Amount must be a number' });
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **Recommendation**: Implement more robust input validation, including checking for proper date format, and sanitizing the object field to prevent XSS. See [OWASP Input Validation Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html).
|
||||||
|
|
||||||
|
### 2. Dependency Risks
|
||||||
|
|
||||||
|
#### 2.1 Outdated Dependencies
|
||||||
|
|
||||||
|
- **Description**: Several dependencies in the projects are outdated and may contain known vulnerabilities.
|
||||||
|
- **Severity**: Medium
|
||||||
|
- **File/Location**: Various package.json files
|
||||||
|
- **Recommendation**: Implement regular dependency updates using tools like npm audit. Implement a GitHub Action to automatically check for vulnerable dependencies using tools like Dependabot. See [GitHub Dependabot documentation](https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/about-dependabot-version-updates).
|
||||||
|
|
||||||
|
### 3. Configuration and Secrets Management
|
||||||
|
|
||||||
|
#### 3.1 Hardcoded API Tokens in GitHub Workflows
|
||||||
|
|
||||||
|
- **Description**: GitHub Actions workflow contains references to API tokens and uses them in an insecure manner.
|
||||||
|
- **Severity**: Medium
|
||||||
|
- **File/Location**: `/quiz-app/README.md` and `.github/workflows/azure-static-web-apps-ashy-river-0debb7803.yml`
|
||||||
|
- **Code snippet**:
|
||||||
|
```yaml
|
||||||
|
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ASHY_RIVER_0DEBB7803 }}
|
||||||
|
```
|
||||||
|
- **Recommendation**: Add documentation about proper secrets management in GitHub Actions, including avoiding printing secrets in logs and using secret masking. Reference: [GitHub Actions secrets documentation](https://docs.github.com/en/actions/security-guides/encrypted-secrets).
|
||||||
|
|
||||||
|
#### 3.2 Lack of Secure API Key Storage Guidelines
|
||||||
|
|
||||||
|
- **Description**: No clear guidance on securely handling API keys in the browser extension project.
|
||||||
|
- **Severity**: Low
|
||||||
|
- **File/Location**: `/5-browser-extension/1-about-browsers/README.md`
|
||||||
|
- **Recommendation**: Add security best practices section in the README.md file explaining secure ways to store API keys in browser extensions. Reference: [Chrome extension secure storage](https://developer.chrome.com/docs/extensions/reference/storage/).
|
||||||
|
|
||||||
|
### 4. Identity & Access Control
|
||||||
|
|
||||||
|
#### 4.1 No Authentication in Banking API
|
||||||
|
|
||||||
|
- **Description**: The banking API has no authentication mechanism, allowing anyone to access or modify account data.
|
||||||
|
- **Severity**: High
|
||||||
|
- **File/Location**: `/7-bank-project/api/server.js`
|
||||||
|
- **Recommendation**: For an educational application, add comments explaining the security implications and how authentication should be implemented in a real-world scenario. Reference: [OWASP Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html).
|
||||||
|
|
||||||
|
### 5. Cloud Posture
|
||||||
|
|
||||||
|
#### 5.1 No HTTPS Enforcement
|
||||||
|
|
||||||
|
- **Description**: The banking API has no HTTPS enforcement, allowing unencrypted communication.
|
||||||
|
- **Severity**: Medium
|
||||||
|
- **File/Location**: `/7-bank-project/api/server.js`
|
||||||
|
- **Recommendation**: Add comments about the importance of HTTPS in production and provide a code example showing how to enforce HTTPS in Express. Reference: [OWASP Transport Layer Protection Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html).
|
||||||
|
|
||||||
|
## Key Findings Table
|
||||||
|
|
||||||
|
| Severity | Issue | File/Location | Recommendation |
|
||||||
|
|----------|-------|--------------|----------------|
|
||||||
|
| High | Overly Permissive Host Permissions | /5-browser-extension/solution/dist/manifest.json | Restrict permissions to only necessary APIs |
|
||||||
|
| High | No Authentication in Banking API | /7-bank-project/api/server.js | Add educational comments about proper auth implementation |
|
||||||
|
| Medium | CORS Misconfiguration | /7-bank-project/api/server.js | Restrict CORS to specific origins |
|
||||||
|
| Medium | Insecure Data Storage | /5-browser-extension/solution/src/index.js | Use secure storage APIs and add educational notes |
|
||||||
|
| Medium | Lack of Input Validation | /7-bank-project/api/server.js | Implement robust input validation |
|
||||||
|
| Medium | Outdated Dependencies | Various package.json files | Implement dependency scanning |
|
||||||
|
| Medium | Hardcoded API Tokens | GitHub workflows and READMEs | Add secure secrets management guidance |
|
||||||
|
| Medium | No HTTPS Enforcement | /7-bank-project/api/server.js | Add educational comments about HTTPS importance |
|
||||||
|
| Low | Lack of API Key Storage Guidelines | /5-browser-extension documentation | Add security best practices section |
|
||||||
|
|
||||||
|
## Conclusion & Prioritized Action List
|
||||||
|
|
||||||
|
This security audit has identified several security issues across the Web-Dev-For-Beginners repository. While most issues are understandable in an educational context, adding proper documentation about security best practices would significantly enhance the learning experience and prepare students for secure coding in production environments.
|
||||||
|
|
||||||
|
### Prioritized Action List:
|
||||||
|
|
||||||
|
1. Restrict overly permissive host permissions in browser extension
|
||||||
|
2. Add educational comments about authentication in the banking API
|
||||||
|
3. Fix CORS configuration in banking API
|
||||||
|
4. Implement more robust input validation in banking API
|
||||||
|
5. Add secure storage examples for browser extension
|
||||||
|
6. Add security best practices documentation for API key management
|
||||||
|
7. Add educational comments about HTTPS importance
|
||||||
|
8. Implement dependency scanning
|
||||||
|
9. Add secure secrets management guidance for GitHub Actions
|
@@ -170,6 +170,8 @@ Once you are signed in on Azure through the link above, select a subscription an
|
|||||||
output_location: "dist" #Built app content directory - optional
|
output_location: "dist" #Built app content directory - optional
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **SECURITY NOTE**: Never print, log or expose secrets in your workflow files. Avoid hard-coding URLs and tokens. Always use GitHub Secrets for storing sensitive values and reference them using the ${{ secrets.SECRET_NAME }} syntax. For more information, see [GitHub Actions Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets).
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
- Post-Deployment: After deployment is complete, click on 'Go to Deployment' then 'View app in browser'.
|
- Post-Deployment: After deployment is complete, click on 'Go to Deployment' then 'View app in browser'.
|
||||||
|
Reference in New Issue
Block a user