Webサイトのセキュリティ評価:作る側、攻める側両方の視点から考える

株式会社LOWWS CTOのスラヴィ・パンタレーブ(Slavi Pantaleev)と、株式会社LOWWS プログラマーのルボミル・ポポヴ(Lyubomir Popov)にインタビューし、現在携わっているプロジェクトの中で興味深い技術や最新の知見について聞いていくコーナーです。

今回はスラヴィに同席してもらい、ルボにWebサイトのセキュリティ評価する上での考え方について聞きました。

日本語の記事に続いて英語の記事があります

This is an interview with Slavi Pantaleev, CTO of LOWWS Inc., and Lyubomir Popov, programmer at LOWWS Inc., where we explore interesting technologies and the latest insights from their current projects.

This time, Slavi joined us for a discussion with Lyubo about The Mindset for Evaluating Website Security.

The English article follows the Japanese article.


さまざまな脆弱性:XXEからタイミング攻撃まで

ルボ:最近、個人的に面白いなと思っているのが、ブラックボックス型のWebサイトのセキュリティ評価、つまりペネトレーションテストの認定を受けることなんです。

スラヴィ:それは面白いですね。その認定を受ける前に、何か講座を受けたりするんですか?それとも独学で準備する感じですか?

ルボ:独学でも準備できますが、少なくともテスト用のラボ環境はあったほうがいいですね。この認定でカバーされる内容って、そこまで珍しいものではないんです。Web開発をしている人なら、クロスサイトスクリプティングとかSQLインジェクション、ディレクトリトラバーサル攻撃とか、そういう問題は見たことがあると思います。

でも、自分がこれまで見たことなかったり、あまり考えたことがなかったようなものもあります。例えばXML外部実体参照(XXE)っていうやつですね。 ざっくり言うと、XMLファイルをパースするときに、その中に他のファイルを含めることができるんです。で、その処理の仕方によっては、攻撃者が任意のファイルをシステム内から読み込めてしまう、なんてこともあり得るんですよ。それがセキュリティ上の問題につながる可能性があるんです。

スラヴィ:ああ、それってよくある話ですよね。私もそういう仕組みを使ったプロジェクトやWebサイトを作ったことありますよ。たとえば、顧客が自分でメールテンプレートを編集できるようなものです。 そういうテンプレートをもっと柔軟に使えるようにするために、TwigとかJinjaみたいなテンプレートエンジンを使うことが多いですよね。言語によって違いますけど。でもそれって、悪意のあるコードを注入されるリスクもあるってことですよね。 だから、そういうテンプレートは何かしらのサンドボックス環境で評価したほうが良さそうですね。

ルボ:そうですね。それが1つの対策です。あとは、許可するタグを安全なものに限定するのも大事です。たとえば、ファイルシステムからランダムにファイルを読み込めるようには絶対しちゃダメですね。

スラヴィ:なるほど、それは興味深いですね。

ルボ:あとよくあるのがコマンドインジェクションですね。たとえば、外部のツールを実行する仕組みを持ったツールがあるとします。たとえば、ドメインのwhois情報を調べる処理を外部のコンソールツールで実行しているような場合。 そういうときって、入力値をしっかりフィルタリングしないといけないんです。というのも、コマンドの後ろに別のコマンドをパイプでつなげて実行されちゃう可能性があるからです。 フィルタリングが甘いと、攻撃者が追加のコマンドを実行して、システムに問題を起こすかもしれません。

スラヴィ:PHPだとescapeshellarg()とか使いますよね。

ルボ:そうそう、それです。

スラヴィ:やっぱり、こういう一般的な攻撃手法とか脆弱性については、どの開発者も知っておいた方がいいですね。

ルボ:そうですね。たとえばOWASP Top 10とかをチェックするといいですよ。Webアプリにおける主要な脆弱性トップ10を常に更新してくれているリストです。 それに、わざと脆弱性のあるアプリも公開されていて、セキュリティテストのトレーニングにも使えるんです。たとえば、誰かが書いたアプリに対してSQLインジェクションを試してみる、なんてことができます。 自分で書いたアプリだと、「もうこれで完璧だろう」って思っちゃうんですけど、やっぱり誰か他の人にチェックしてもらったほうがいいんですよね。

スラヴィ:わかります。特にセキュリティの専門家だと、自分よりずっと多くの攻撃方法を知ってますし。

ルボ:そうですね。しかも最近は自動化ツールも多いです。たとえばSQLインジェクションを試すためのツールなら、入力フィールドやURLを指定して、GETかPOSTかを選んで、攻撃対象のフィールドを指定すれば、何千ものパターンを自動で試してくれます。 サーバーからのレスポンスをもとに、「このサーバーはMySQLかな、MSSQLかな」みたいに推測できるんですよ。 それに、もしサーバーがエラーの内容をそのまま返してしまうようだと、ツール側は正確に「このDBはこれだな」ってわかっちゃいます。 だから、Webアプリで例外メッセージをユーザーに表示するのって、本当に良くないんですよ。そこから漏れた情報が、次の攻撃に使われてしまうかもしれませんから。

スラヴィ:サーバーの種類とバージョンが分かれば、それに特化した攻撃を仕掛けることができますよね。特に、システムがきちんとアップデートされていないケースも多いので、古いサーバーがそのまま使われていて、脆弱なままになっていることがよくあるんです。

ルボ:そうですね。既知の脆弱性やエクスプロイトをまとめたオンラインデータベースもありますし、特定のソフトウェア名やバージョンで検索できます。 だから、使われているデータベースサーバーの種類がわかれば、それに対する具体的な攻撃手法を探して、実際にテストしたり試してみたりできるんです。Webサイトがどうやって攻撃されるのかを知るのは、すごく興味深いですよ。

スラヴィ:僕がすごく驚いた攻撃手法のひとつがタイミング攻撃ですね。ログインページなんかでパスワードを比較する処理があるじゃないですか。その比較にかかる時間から、攻撃者がどのくらい正しいかを推測して、徐々に調整して正解のパスワードにたどり着けちゃうんですよ。あれには驚きました。

ルボ:もし平文のパスワードを使ってるなら、確かにそうですね。でもハッシュ化されたパスワードを使っていれば、そういう問題は起きにくいはずです。

スラヴィ:そうですね。1文字変えるだけでハッシュ全体が変わるので、タイミングから何かを読み取るってことはできませんよね。

ルボ:でも、こういうのって普通の開発者はなかなか意識しない小さなことなんですよね。

スラヴィ:こういうのはサイドチャネル攻撃って呼ばれてますね。直接的な情報じゃなくて、タイミングみたいな間接的な要素を使って攻撃するやつです。

ルボ:パスワードを比較すること自体は問題ないんですけど、その比較にかかる時間っていうのが、実は攻撃の手がかりになってしまうことがあるんですよ。

スラヴィ:いやあ、本当に奥が深い分野ですよね。


スラヴィ:それで、これは単にスキルアップの一環としてやってるんですか?それとも、本格的にセキュリティ分野、たとえばペネトレーションテストとかを仕事にしていきたいんですか?

ルボ:どっちもですね。より良いプログラマーになるためには、ソフトウェアを作る側と攻める側の両方の視点が必要だと思っていて。コードを書くときって、たとえばタイミング攻撃みたいなことは、普通あんまり考えないじゃないですか。でも攻撃手法を学ぶようになると、「あ、こういうところ狙われるのか」って視点が得られるんですよね。 どんなツールが攻撃に使われるのかとか、どうやって攻撃を自動化できるのかとか、そういうのがわかってくると、逆に防御の方法も思いつけるようになります。

スラヴィ:うん、たしかに。それって、両方の立場を知ってるからこそ身につく視点ですよね。高パフォーマンスのシステムに関わったことがあると、コードが負荷に対してどう振る舞うかとか、最適化すべきポイントが見えてくるようになるのと似てるかも。

ルボ:そうですね。ただ、最適化っていつも必要なわけじゃなくて、場合によっては開発時間やコストを無駄にしちゃうこともあるので、そこは注意が必要ですけどね。でも、その一面を経験してるっていうのは、やっぱりプログラマーとしてはプラスになると思います。

スラヴィ:最適化も大事だけど、場合によってはもっといいハードウェアを買えば解決するってこともありますよね。

ルボ:ほんとそれです。もし1年かけて最適化しようとしてるものが、サーバーをちょっと良くするだけで解決できるなら、その方が安いし現実的です。

スラヴィ:たしかに。

ルボ:だから、いろんな視点を持つって大事だなって思うんです。 たとえば、チーム内にちょっと違う分野出身の人がいるだけでも、プロダクトを作るときにまったく違う視点が得られたりします。 誰でも盲点はあるんですよね。ソフトウェア開発でも、ネットワークセキュリティでも。だから、ひとつのものに対して複数の目で見た方がいいんです。

スラヴィ:うん、僕もそれには同意です。パフォーマンスに関してもそう。ある人が性能を追い求めすぎるあまり、コードの品質やリリースまでのスピードが犠牲になることもありますよね。そんなときに、「それは今の規模なら問題にならないからやらなくていいよ」って言える同僚がいると助かるんですよね。

ルボ:そうそう。違う立場の人からの意見って、本当に大事です。ビジネス側の視点もそうです。

スラヴィ:もちろん。完璧を目指しすぎると、実装に時間がかかりすぎることもありますしね。

ルボ:完璧ってのは確かに素晴らしいことだけど、現実の開発では「完璧は善の敵」ってこともあるんですよ。


Various Vulnerabilities: From XXE to Timing Attacks

Lyubo: Recently, the more interesting thing is being certified for black box website security assessment, or in other words, penetration testing for websites.

Slavi: Oh, that’s interesting. Before the certification, do you need to take some courses, or are you preparing by yourself? How does it work?

Lyubo: You can prepare by yourself, but it’s good to at least have the testing labs. Most of the things covered by the certification aren’t so unfamiliar. If you’re a web developer, you’ve probably seen all these problems like cross-site scripting, SQL injection, directory traversal attacks, things like that. But there were some things I hadn’t encountered or thought about—like XML External Entities. Basically, if you’re parsing an XML file, it could include other files. Depending on how you’re handling those files, an attacker might be able to include arbitrary files from your file system, which could lead to security problems.

Slavi: Oh yeah, I think that’s common. We’ve even built projects and websites that do this—like letting customers edit email templates. To make those templates more powerful, we included something like Twig or Jinja, depending on the language. And people could inject something dangerous, I guess. So you probably need to evaluate those in some kind of sandbox.

Lyubo: That’s one thing. Another is to only allow tags that are safe—for example, not allowing people to include random files from your file system.

Slavi: Yeah, that’s interesting.

Lyubo: Another common issue is command injection. For example, if you have a tool that executes external commands—say you want to do a “whois” check on a domain—and you’re calling a console tool, you need to filter your input well. Because someone could pipe in other commands after the initial one. If you don’t filter the input, an attacker could run additional commands that lead to problems.

Slavi: Yeah, in the PHP world that’s something like escapeshellarg, right?

Lyubo: Yeah.

Slavi: So it’s good for every developer to be familiar with popular attacks and vulnerabilities.

Lyubo: You can check OWASP Top 10—it’s a list that’s constantly updated for the top 10 vulnerabilities in web applications. They also provide intentionally vulnerable applications. If you’re doing security testing, you can train with those to see how to do, for example, an SQL injection on an app you didn’t write. Because usually when you write something, you think you’ve covered everything and it’s secure—but it’s better to have someone else check it.

Slavi: Yeah, especially people who specialize in this. They probably know a lot more about how to break it.

Lyubo: Yeah, there are also automated tools. For SQL injection, there are tools where you provide an input field or a URL, specify a GET or POST request and which fields to attack. Then the tool can try thousands of different SQL injection patterns. Based on the server’s responses, it can sometimes guess whether it’s MySQL, MSSQL, or something else. If the server returns specific database errors, the tool can tell you exactly what kind of database it is. That’s why it’s not good to let your web application show exceptions to users. It can leak information that could be used in future attacks.

Slavi: Knowing the type of server and version lets you target specific attacks. Especially since people often don’t keep things updated, you’ll frequently find old servers that are vulnerable.

Lyubo: Yeah, there are online databases with known exploits or at least vulnerabilities. You can look up a specific software name and version. So if you can figure out what database server is being used, you can find specific attacks for it and then test or try them. It’s really interesting to see what’s possible and how websites can be exploited.

Slavi: One type of attack that was surprising to learn about is the timing attack. When you compare passwords—say, on a login page—the time it takes for the comparison to run can give an attacker clues about how correct the password is. They can adjust and iterate until they get it right. That was surprising to me.

Lyubo: Maybe if you’re using plain text passwords, yes. But if you’re using hashed passwords, it shouldn’t be an issue.

Slavi: Yeah, a single character change would flip the entire hash, so you can’t really use timing attacks there. These are the kinds of tiny things normal developers often don’t think about.

Lyubo: They’re called side-channel attacks—using indirect information, like timing, to break security. Comparing passwords itself isn’t usually the problem—it’s the timing that can be exploited.

Slavi: It’s a very interesting field.


Slavi: Do you see this as a way to enhance your skills as a programmer, or are you thinking of getting into security or penetration testing as work?

Lyubo: Both. To be a better programmer, you need to see both sides—building software and attacking it. When writing software, you often don’t think about certain attacks, like timing comparisons. But once you start learning how to attack systems, you gain a new perspective. You learn what tools attackers use, how things can be automated, and how to defend against them.

Slavi: Yeah, it makes you a more well-rounded programmer to see both sides. It’s similar to working on high-performance systems—you start thinking about how code behaves under load and how to optimize it. Sometimes those optimizations aren’t needed, and you end up wasting time and money for the client. But having seen that side still improves your skills.

Lyubo: Optimizations are great, but sometimes it’s just cheaper to buy better hardware. If you’re going to spend a year optimizing something that could be fixed with better servers, it’s probably cheaper to go with the hardware upgrade.

Slavi: That’s true.

Lyubo: It’s good to have different perspectives. One way is to have team members from different or related fields. They bring different perspectives to building things. Everyone has blind spots, whether it’s in software development, security, or networking. It’s best to have more than one pair of eyes reviewing things.

Slavi: I agree. Even with performance discussions—some people might overfocus on speed and sacrifice code quality or delivery speed. Others can step in and say, “This won’t ever be a bottleneck.” Getting feedback from people with different perspectives helps. The business perspective is also important.

Lyubo: Absolutely. If you’re aiming for perfection, sometimes you take too long to implement something. Perfection is great, but in the real world, sometimes “perfect is the enemy of good.”


この記事はインタビューをもとにAIを使用して作成されています。 This article was created using AI based on interviews.