Skip to content

sakshi-js-fetch-security-debugging-assignments#529

Open
sakshibhosale4 wants to merge 1 commit intoaptyInc:mainfrom
sakshibhosale4:sakshi-js-fetch-security-debugging-assignments
Open

sakshi-js-fetch-security-debugging-assignments#529
sakshibhosale4 wants to merge 1 commit intoaptyInc:mainfrom
sakshibhosale4:sakshi-js-fetch-security-debugging-assignments

Conversation

@sakshibhosale4
Copy link
Copy Markdown

@sakshibhosale4 sakshibhosale4 commented Oct 1, 2025

Terms and Conditions

  • I Accept losing points if my PR does not follow the best practices mentioned below, which will impact my overall performance in training

HTML Best Practices

  • File Naming Convention:

  • Follow consistent and descriptive naming (e.g., dashboard.html, user-profile.html).

  • Use lowercase letters and hyphens instead of spaces.

  • Page Title:

  • Ensure the <title> tag is descriptive and aligns with the page content.

  • Include meaningful keywords for SEO if applicable.

  • Semantic Markup:

  • Use appropriate tags like <header>, <footer>, <section>, <article> for better readability and accessibility.

  • Accessibility Standards:

  • Ensure the use of alt attributes for images and proper labels for form elements.

  • Use ARIA roles where necessary.

  • Validation:

  • Ensure the code passes HTML validation tools without errors or warnings.

  • Structure and Indentation:

  • Maintain consistent indentation and proper nesting of tags.

  • Attributes:

  • Ensure all required attributes (e.g., src, href, type, etc.) are correctly used and not left empty.

CSS Best Practices

  • File Organization:

  • Use modular CSS files if applicable (e.g., base.css, layout.css, theme.css).

  • Avoid inline styles unless absolutely necessary.

  • Naming Conventions:

  • Use meaningful class names following BEM or other conventions (e.g., block__element--modifier).

  • Code Reusability:

  • Avoid duplicate code; use classes or mixins for shared styles.

  • Responsive Design:

  • Ensure proper usage of media queries for mobile, tablet, and desktop views.

  • Performance Optimization:

  • Minimize the use of unnecessary CSS selectors.

  • Avoid overly specific selectors and ensure selectors are not overly deep (e.g., avoid #id .class1 .class2 p).

  • Consistency:

  • Follow consistent spacing, indentation, and use of units (rem/em vs. px).

  • Maintain a single coding style (e.g., always use double or single quotes consistently).

Javascript Best Practices

  • File Organization:

  • Ensure scripts are modular and logically separated into files if needed.

  • Avoid mixing inline JavaScript with HTML.

  • Logic Optimization:

  • Check for redundancy and ensure the code is optimized for performance.

  • Avoid unnecessary API calls or DOM manipulations.

  • Solution Approach:

  • Confirm that the code solves the given problem efficiently.

  • Consider scalability for future enhancements.

  • Readability:

  • Use clear variable and function names.

  • Add comments for complex logic or algorithms.

  • Error Handling:

  • Ensure proper error handling for API calls or user input validation.

  • Code Quality:

  • Check for potential bugs (e.g., missing await, mishandling of null/undefined values).

  • Avoid unnecessary console.log statements in production code.

  • Security:

  • Avoid hardcoding sensitive data.

  • Sanitize user input to prevent XSS and other vulnerabilities.

  • Best Practices:

  • Use const and let instead of var.

  • Follow ES6+ standards where applicable.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @sakshibhosale4, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request delivers a new assignment focused on JavaScript's Fetch API, security, and debugging within an e-commerce context. It establishes a functional web application capable of searching, listing, and displaying product details by integrating with an external API. The changes include the creation of multiple HTML pages, a dedicated JavaScript file for API interactions and DOM manipulation, and a CSS file for styling, all encapsulated within a new assignment directory.

Highlights

  • New Assignment Structure: Introduced a new directory structure for 'assignment-1' under 'javascript/10-fetch-security-debugging/sakshi/', containing all necessary files for a basic e-commerce application.
  • E-commerce Product Pages: Added three core HTML pages: 'index.html' for product search, 'list.html' for displaying all products, and 'view.html' for viewing individual product details.
  • JavaScript API Integration: Implemented 'script.js' with asynchronous functions ('searchProducts', 'loadProducts', 'viewProduct') that utilize the JavaScript Fetch API to interact with the 'dummyjson.com' API for product data, including basic error handling.
  • Styling: Included 'styles.css' to provide a clean and responsive design for the e-commerce application's various components, such as headers, navigation, and product cards.
  • Main Entry Point: Created a top-level 'index.html' file at 'javascript/10-fetch-security-debugging/sakshi/' which embeds the 'assignment-1/index.html' within an iframe, serving as the primary access point for the assignment.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds three pages for an e-commerce shop: product search, all products list, and view product details. The implementation uses fetch to get data from a public API. My review focuses on critical security vulnerabilities, performance improvements, and best practices for modern web development. The most critical issue is a Cross-Site Scripting (XSS) vulnerability caused by using innerHTML with un-sanitized API data. I've also provided suggestions to improve code maintainability by separating concerns (HTML and JS) and avoiding code duplication. Please address the security issues with high priority.

Comment on lines +9 to +17
resultsDiv.innerHTML = ""
data.products.forEach(p => {
resultsDiv.innerHTML += `
<div class="product-card">
<img src="${p.thumbnail}" alt="${p.title}">
<h3>${p.title}</h3>
<p>$${p.price}</p>
</div>`
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Using innerHTML += inside a loop to build the UI has two major issues:

  1. Security Risk (XSS): You are injecting raw data from the API (p.thumbnail, p.title, p.price) directly into the HTML. If the API response contains malicious scripts (e.g., in the product title), they will be executed in the user's browser. This is a critical Cross-Site Scripting (XSS) vulnerability.
  2. Performance: Modifying innerHTML in a loop forces the browser to re-parse and re-render the DOM on each iteration, which is very inefficient for large lists.

A much safer and more performant approach is to create DOM elements programmatically and set their content using textContent, which automatically sanitizes the input. You can build all elements and append them to the DOM in a single operation using a DocumentFragment.

Suggested change
resultsDiv.innerHTML = ""
data.products.forEach(p => {
resultsDiv.innerHTML += `
<div class="product-card">
<img src="${p.thumbnail}" alt="${p.title}">
<h3>${p.title}</h3>
<p>$${p.price}</p>
</div>`
})
resultsDiv.innerHTML = "";
const fragment = document.createDocumentFragment();
data.products.forEach(p => {
const card = document.createElement('div');
card.className = 'product-card';
const img = document.createElement('img');
img.src = p.thumbnail;
img.alt = p.title;
const title = document.createElement('h3');
title.textContent = p.title;
const price = document.createElement('p');
price.textContent = `$${p.price}`;
card.append(img, title, price);
fragment.appendChild(card);
});
resultsDiv.appendChild(fragment);

Comment on lines +30 to +38
productsDiv.innerHTML = ""
data.products.forEach(p => {
productsDiv.innerHTML += `
<div class="product-card">
<img src="${p.thumbnail}" alt="${p.title}">
<h3>${p.title}</h3>
<p>$${p.price}</p>
</div>`
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Similar to searchProducts, using innerHTML += here introduces a critical Cross-Site Scripting (XSS) vulnerability and is inefficient. Data from the API should never be trusted and inserted directly into innerHTML. Please create DOM elements dynamically to prevent this. This logic is also duplicated from searchProducts; consider creating a helper function to generate product cards to follow the DRY principle.

Suggested change
productsDiv.innerHTML = ""
data.products.forEach(p => {
productsDiv.innerHTML += `
<div class="product-card">
<img src="${p.thumbnail}" alt="${p.title}">
<h3>${p.title}</h3>
<p>$${p.price}</p>
</div>`
})
productsDiv.innerHTML = "";
const fragment = document.createDocumentFragment();
data.products.forEach(p => {
const card = document.createElement('div');
card.className = 'product-card';
const img = document.createElement('img');
img.src = p.thumbnail;
img.alt = p.title;
const title = document.createElement('h3');
title.textContent = p.title;
const price = document.createElement('p');
price.textContent = `$${p.price}`;
card.append(img, title, price);
fragment.appendChild(card);
});
productsDiv.appendChild(fragment);

Comment on lines +52 to +56
detailsDiv.innerHTML = `
<img src="${p.thumbnail}" alt="${p.title}">
<h3>${p.title}</h3>
<p><strong>Price:</strong> $${p.price}</p>
<p>${p.description}</p>`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Directly setting innerHTML with API response data (p.thumbnail, p.title, p.description, etc.) is a major security risk, as it can lead to Cross-Site Scripting (XSS) attacks. Any malicious script in the product data would be executed. You should create DOM elements and use textContent to safely display the data.

    detailsDivinnerHTML = '';

    const img = document.createElement('img');
    img.src = p.thumbnail;
    img.alt = p.title;

    const title = document.createElement('h3');
    title.textContent = p.title;

    const price = document.createElement('p');
    const priceLabel = document.createElement('strong');
    priceLabel.textContent = 'Price:';
    price.append(priceLabel, ` $${p.price}`);

    const description = document.createElement('p');
    description.textContent = p.description;

    detailsDiv.append(img, title, price, description);

</div>`
})
} catch (err) {
resultsDiv.innerHTML = `<p style="color:red">${err.message}</p>`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Displaying raw error messages via innerHTML is risky. It can leak internal application details and create a Cross-Site Scripting (XSS) vulnerability if the error message contains malicious HTML. It's safer to show a generic, user-friendly message and use textContent to prevent script execution. Also, using inline styles is not a good practice; styles should be in your CSS file.

Suggested change
resultsDiv.innerHTML = `<p style="color:red">${err.message}</p>`
resultsDiv.textContent = `An error occurred while fetching products.`;

</div>`
})
} catch (err) {
productsDiv.innerHTML = `<p style="color:red">${err.message}</p>`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Displaying raw error messages via innerHTML is risky. It can leak internal application details and create a Cross-Site Scripting (XSS) vulnerability if the error message contains malicious HTML. It's safer to show a generic, user-friendly message and use textContent to prevent script execution. Also, using inline styles is not a good practice; styles should be in your CSS file.

Suggested change
productsDiv.innerHTML = `<p style="color:red">${err.message}</p>`
productsDiv.textContent = `An error occurred while fetching products.`;


<main>
<h2>All Products</h2>
<button onclick="loadProducts()">Load Products</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's a best practice to avoid inline event handlers like onclick. Instead, you should add event listeners in your JavaScript file. This helps to separate your HTML structure from your JavaScript logic, making the code cleaner and easier to maintain. You can add an id to the button to select it in your script.

In your script.js, you would then add something like this:

const loadButton = document.getElementById('loadProductsButton');
if (loadButton) {
  loadButton.addEventListener('click', loadProducts);
}
Suggested change
<button onclick="loadProducts()">Load Products</button>
<button id="loadProductsButton">Load Products</button>

const resultsDiv = document.getElementById("results")
resultsDiv.innerHTML = "Loading..."
try {
const res = await fetch(`https://dummyjson.com/products/search?q=${query}`)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When including user input in a URL, it's important to properly encode it to handle special characters (e.g., &, ?, /). While fetch does some encoding, it's best practice to be explicit by using encodeURIComponent to prevent potential request errors or injection vulnerabilities.

Suggested change
const res = await fetch(`https://dummyjson.com/products/search?q=${query}`)
const res = await fetch(`https://dummyjson.com/products/search?q=${encodeURIComponent(query)}`)

<main>
<h2>View Product by ID</h2>
<input type="number" id="productId" placeholder="Enter product ID">
<button onclick="viewProduct()">View Product</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's a best practice to avoid inline event handlers like onclick. Instead, you should add event listeners in your JavaScript file. This helps to separate your HTML structure from your JavaScript logic, making the code cleaner and easier to maintain. You can add an id to the button to select it in your script.

In your script.js, you would then add something like this:

const viewButton = document.getElementById('viewProductButton');
if (viewButton) {
  viewButton.addEventListener('click', viewProduct);
}
Suggested change
<button onclick="viewProduct()">View Product</button>
<button id="viewProductButton">View Product</button>

<body>
<details>
<summary>Assignment 1</summary>
<iframe src="./assignment-1/index.html" frameborder="0" width="100%"></iframe>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The frameborder attribute is obsolete in HTML5 and should not be used. Instead, you should use CSS to control the iframe's border. You can apply border: none; via a style attribute or a CSS class.

Suggested change
<iframe src="./assignment-1/index.html" frameborder="0" width="100%"></iframe>
<iframe src="./assignment-1/index.html" width="100%" style="border: none;"></iframe>

<iframe src="./assignment-1/index.html" frameborder="0" width="100%"></iframe>
</details>
</body>
</html>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's a standard convention to have a single newline character at the end of every text file. This file is missing one, which can cause issues with some tools and version control systems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant