dimhold.by
← Артыкулы

codecard адмаўляецца маляваць сніпет, які выдае кодавую базу. Усе 569 радкоў пакета Kotlin, якія я яму даў, ён прапусціў

У жніўні я адкрыў codecard. Ён малюе сніпет кода або лога як картку для стужкі. Перш чым маляваць, ён чытае тэкст і адмаўляецца, калі тэкст выдае кодавую базу. Гэта радок пакета, імпарт вашага ўласнага кода, шлях зборкі з імем карыстальніка, унутраны хост або нешта падобнае на ўліковыя даныя. Адмова ў яго жорсткая: код вяртання 2 і ніякага файла. Я зрабіў так таму, што папярэджанне ў гадзіну ночы пракруцяць міма, а карцінка застанецца ў чужой стужцы.

У гарда 11 правілаў і 171 тэст і ўсе яны праходзяць. Але кожны выпадак у гэтых тэстах напісаны для гэтых тэстаў. Прыклад у README гэта файл на Java, які я прыдумаў так, каб у ім было роўна 5 уцечак. Гард ні разу не бачыў кода, які пісаў не я, таму я запусціў яго на чужым кодзе.

Я ўзяў codecard з GitHub на апошнім каміце, f10a09e, на Python 3.12. Побач паклаў 9 публічных рэпазіторыяў на іх апошнім каміце да 1 кастрычніка. Гэта 8 моў ад Java да Rust, сярод іх spring-petclinic і vite. З кожнага рэпазіторыя я ўзяў да 300 файлаў. З кожнага файла ўзяў 2 вокны па 15 радкоў: пачатак файла і адно выпадковае акно з астатняга. Другое акно прыкладна тое, што я капіюю, калі хачу паказаць функцыю.

Як часта ён адмаўляе публічнаму коду

Усё ў гэтым корпусе ўжо апублікавана, таму кожная адмова тут гэта адмова коду, які не сакрэт. На выпадковых вокнах з сярэдзіны файла ён адмовіў у 17 выпадках з 790, гэта 2,2%. На пачатку файла ён адмовіў у 138 з 1200. 132 з іх гэта файлы C# у MediatR, дзе namespace стаіць у першых 15 радках. Паводле яго ж азначэння гард тут мае рацыю: namespace сапраўды называе кодавую базу. Гэтая база публічная і для такога выпадку ёсць --guard off.

Частка з 17 гэта шум. У express ён адмовіў тэсту з URL /users/0-2. Сярод іншых папак правіла шляхоў шукае /Users/ на macOS і /home/ на Linux. Але codecard кампілюе ўсе правілы па змаўчанні з re.I, таму маршрут у ніжнім рэгістры таксама падыходзіць. Па ўсіх файлах корпуса правіла шляхоў спрацоўвае на 107 радках і 23 з іх толькі праз гэты сцяжок. У okhttp ён адмовіў імпартам org.robolectric і org.bouncycastle. У правіла прыватных імпартаў ёсць белы спіс з 26 імёнаў груп, а любое іншае імя яно лічыць вашым уласным кодам.

2,2% гэта цана, якую я прыняў у жніўні, не ведаючы лічбы. Цяпер я яе ведаю. Адмова каштуе мне аднаго --guard off. Са сцяжком рэгістра іншая справа, яго трэба правіць.

Радок, які ён абяцаў лавіць

Потым я прагнаў гард па радку аб’явы кожнага файла, без выбаркі і па адным радку. Java дала 106 злоўленых са 106, C# дала 133 са 133. Kotlin даў 0 з 569.

правіла: ^[ \t]*package\s+[\w.]+\s* ; Java package com.acmebank.ledger.settlement ; злоўлена ў 106 са 106 файлаў Kotlin package com.acmebank.ledger.settlement гэтага чакае правіла злоўлена ў 0 з 569 файлаў
Радок пакета кожнага файла корпуса, правераны асобна. Правіла для namespace у C# дапускае радок без кропкі з коскай і злавіла 133 са 133.

Правілу патрэбна кропка з коскай у канцы радка пакета, а Kotlin яе там не ставіць. Калі правіла спрацоўвае, яно друкуе прычыну “a Java or Kotlin package name is your company and product, spelled out”, гэта значыць імя пакета Java або Kotlin гэта назва вашай кампаніі і прадукту, прапісаная поўнасцю. Гэтую фразу і рэгулярку я пісаў, гледзячы на файл Java. Тэсты да іх таксама на Java.

Гэта горш, чым адзін прапушчаны радок. Я ўзяў прыклад з уцечкамі з README і перапісаў яго на Kotlin. Гард усё роўна адмаўляе, з 4 знаходкамі: імпарт, ключ, хост і шлях. Пакета ў спісе няма. Калі я выпраўляю 4 рэчы, пра якія ён сказаў, картка малюецца з package com.acmebank.ledger.settlement у першым радку і кодам вяртання 0. Той жа файл з кропкай з коскай атрымлівае код 2. У гадзіну ночы спіс выглядае поўным, так што я б выправіў гэтыя 4 і апублікаваў.

Побач са сканерам сакрэтаў

Потым я захацеў даведацца, што гард прапускае. Сапраўдныя ўцечкі я палічыць не магу, таму склаў спіс з 31 формы, якія трапляюць у картку пры ўстаўцы з рэдактара або з лога. Я прагнаў іх праз codecard і праз gitleaks 8.30.1, сканер, які я б паставіў на рэпазіторый. Сакрэты ў спісе гэта выпадковыя радкі патрэбнага фармату, яны генеруюцца пры запуску.

codecard gitleaks выдае кодавую базу (18) 10 0 пакет Java пакет Kotlin namespace C# імпарт Java імпарт Kotlin імпарт Python імпарт Go імпарт TypeScript C:\Users\ у трасе .NET шлях /home/ у памылцы шлях /Users/ у стэку шлях у трасе Python шлях з ~ URL https://*.internal *.internal:5432 без схемы *.svc.cluster.local хост на дамене кампаніі адрас 10.x сакрэты (13) 6 12 API_KEY = "..." радок .env без двукоссяў пароль у YAML без двукоссяў Authorization: Bearer загаловак token у curl ключ AWS AKIA... сакрэтны ключ AWS блок прыватнага ключа JWT postgres://user:pass@ JDBC ?password= вэбхук Slack api_key="sk-proj-..."
31 форма ўцечкі, па радку на кожную. Зафарбаваная кропка азначае, што інструмент радок злавіў, сіні подпіс азначае, што не злавіў ніводзін. Сакрэты гэта выпадковыя радкі патрэбнага фармату.

Гэтыя 2 інструменты амаль не перасякаюцца. З 18 формаў, якія выдаюць кодавую базу, codecard злавіў 10, а gitleaks ніводнай. Гэта справядліва, бо gitleaks зроблены для сакрэтаў. З 13 сакрэтаў gitleaks злавіў 12, а codecard 6. Яго правіла для ўліковых даных бачыць значэнне толькі ў двукоссі пасля імя накшталт api_key або password. Радок з файла .env малюецца. Малююцца і пароль у YAML без двукоссяў і загаловак Authorization: Bearer у логу і URL вэбхука Slack. Вось гэта крыху крыўдна. Тэму ember я зрабіў для логаў з памылкамі, а ў логу токен Bearer якраз стаіць без двукоссяў.

Разам яны злавілі 23 з 31. Усе 8, якія не злавіў ніводзін, выдаюць кодавую базу. Сярод іх пакет Kotlin і ўнутраны хост без https:// наперадзе. Найцяжэй з хостам на ўласным дамене кампаніі і як яго лавіць, не ведаючы кампаніі, я не ведаю. У README ужо напісана, што гард не ведае, як называецца ваша кампанія.

Першы радок README

Усталёўка ў README пачынаецца з pip install codecard. Я запусціў яе ў чыстым virtualenv і pip не знайшоў ніводнага дыстрыбутыва. Імя на PyPI наогул не зарэгістравана. Выходзіць, README інструмента, які існуе дзеля абароны ад уцечак, прапануе ставіць імя, якое можа зарэгістраваць хто заўгодна. Так ёсць з сярэдзіны жніўня, а я гэтага не заўважыў.

Чаго я не правяраў

31 форма гэта мой уласны спіс, таму ён кажа, якія формы праходзяць, а не як часта людзі іх устаўляюць. Корпус гэта 9 рэпазіторыяў і 1 выпадковае зерне. Іншы памер акна мог бы зрушыць 2,2%. trufflehog я не запускаў. І я яшчэ нічога не паправіў. Кропка з коскай, сцяжок рэгістра, сакрэты без двукоссяў і імя на PyPI так і застаюцца адкрытымі ў codecard на f10a09e.