Skip to content

Harden chart lab as experiment#12

Merged
robertoecf merged 1 commit into
mainfrom
codex/charts-labs-hardening
May 5, 2026
Merged

Harden chart lab as experiment#12
robertoecf merged 1 commit into
mainfrom
codex/charts-labs-hardening

Conversation

@robertoecf
Copy link
Copy Markdown
Owner

Summary

  • Repositions /charts as an experimental chart lab instead of a primary product CTA.
  • Removes Yahoo/yfinance presets from the public chart lab and keeps only official/auditable source presets for BCB, IBGE and IPEA.
  • Adds public-site guardrails: allowed endpoint prefixes, request timeout, point-count cap, JSON audit link, SRI on the pinned CDN script, and explicit TradingView Lightweight Charts™ attribution.
  • Updates the official chart standard doc to encode the Labs positioning and source policy.

Root cause

The first /charts version was technically working, but it over-positioned the feature as a main site capability and mixed experimental/indirect sources with official presets. This follow-up keeps the visualizer useful while making the public surface match the project identity: data infrastructure first, charting as a beta visualization layer.

Validation

  • node --check src/findata/web/static/chart-explorer.js
  • .venv/bin/ruff format --check src/ tests/ scripts/
  • .venv/bin/ruff check src/ tests/ scripts/
  • .venv/bin/python -m mypy src/findata
  • .venv/bin/python -m pytest tests/ -q
  • git diff --check
  • Browser check on http://127.0.0.1:8765/charts: beta copy visible, initial Selic series loaded as Série plotada., JSON audit link present, only BCB/IBGE/IPEA presets visible, no console errors.

UI evidence

  • Local screenshot: /Users/macbook/Documents/Codex/2026-05-05/findata_chart_lab_hardening.png

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Warning

Rate limit exceeded

@robertoecf has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 36 minutes and 47 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 34063ba4-9f71-4581-b01e-9965083dde17

📥 Commits

Reviewing files that changed from the base of the PR and between b0b4d70 and 607a298.

📒 Files selected for processing (6)
  • docs/CHART_STANDARDS.md
  • src/findata/web/static/chart-explorer.js
  • src/findata/web/templates/charts.html
  • src/findata/web/templates/docs.html
  • src/findata/web/templates/index.html
  • tests/test_api.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/charts-labs-hardening

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@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 rebrands the charting feature as an experimental 'Labs' section, introducing stricter standards for public visualization surfaces. Key changes include the removal of experimental data sources like Yahoo Finance, the implementation of endpoint allow-listing, request timeouts, and data point limits to ensure stability. Additionally, security is improved by adding Subresource Integrity (SRI) to external scripts and introducing HTML escaping for dynamic content. A security-related feedback was provided to ensure that all API-derived keys are properly escaped before being injected into the DOM to prevent potential XSS vulnerabilities.

nodes.summary.textContent = `${normalized.data.length} pontos · ${first} a ${last} · data=${normalized.dateKey} · valor=${normalized.valueKey || "OHLC"}`;
const auditUrl = new URL(endpoint, window.location.origin);
const auditPath = `${auditUrl.pathname}${auditUrl.search}`;
nodes.summary.innerHTML = `<a href="${escapeHtml(auditPath)}">JSON auditável</a> · ${normalized.data.length} pontos · ${first} a ${last} · data=${normalized.dateKey} · valor=${normalized.valueKey || "OHLC"}`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

security-medium medium

Os campos dateKey e valueKey são extraídos das chaves do objeto JSON retornado pela API e inseridos no innerHTML sem escape. Embora os endpoints sejam restritos a fontes internas, é uma boa prática escapar qualquer dado vindo da API ao usar innerHTML para evitar potenciais ataques de XSS caso uma fonte retorne chaves maliciosas.

Suggested change
nodes.summary.innerHTML = `<a href="${escapeHtml(auditPath)}">JSON auditável</a> · ${normalized.data.length} pontos · ${first} a ${last} · data=${normalized.dateKey} · valor=${normalized.valueKey || "OHLC"}`;
nodes.summary.innerHTML = `<a href="${escapeHtml(auditPath)}">JSON auditável</a> · ${normalized.data.length} pontos · ${first} a ${last} · data=${escapeHtml(normalized.dateKey)} · valor=${escapeHtml(normalized.valueKey || "OHLC")}`;

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a03e48cad0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +194 to +195
const endpoint = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
assertAllowedEndpoint(endpoint);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Normalize endpoint path before applying allowlist

The new guardrail can be bypassed because assertAllowedEndpoint runs on the raw input path, not a canonicalized URL path. Inputs like /bcb/series/../../openapi.json still pass startsWith("/bcb/series/"), but the browser normalizes dot segments before the request, so fetch actually hits /openapi.json (or other non-lab endpoints). This undermines the stated restriction to light temporal endpoints and can re-enable heavy/unintended requests.

Useful? React with 👍 / 👎.

@guardrails
Copy link
Copy Markdown

guardrails Bot commented May 5, 2026

All previously detected findings have been fixed. Good job! 👍🎉

We will keep this comment up-to-date as you go along and notify you of any security issues that we identify.


👉 Go to the dashboard for detailed results.

📥 Happy? Share your feedback with us.

@robertoecf robertoecf force-pushed the codex/charts-labs-hardening branch from a03e48c to 1c65e56 Compare May 5, 2026 17:01
@robertoecf robertoecf force-pushed the codex/charts-labs-hardening branch from 1c65e56 to 607a298 Compare May 5, 2026 17:04
@robertoecf robertoecf merged commit 79177ec into main May 5, 2026
7 checks passed
@robertoecf robertoecf deleted the codex/charts-labs-hardening branch May 5, 2026 17:06
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 607a298ded

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"/bcb/series/",
"/ibge/indicators/",
"/ipea/series/",
"/tesouro/bonds/history",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Drop unsupported Tesouro endpoint from allowed prefixes

/tesouro/bonds/history is now explicitly allowlisted, but responses from that route use fields like dt_base/dt_vencimento while normalizeData only recognizes date keys in DATE_KEYS (e.g. date, data, periodo). In practice, Tesouro requests pass the new guardrail and then fail with Não encontrei campo de data conhecido., so one of the few permitted endpoint families is unusable until either the parser supports Tesouro date fields or this prefix is removed.

Useful? React with 👍 / 👎.

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