목차
回复内容:
백엔드 개발 PHP 튜토리얼 入侵 - PHP的防御XSS注入的终极解决方案【信息安全】【Hack】

入侵 - PHP的防御XSS注入的终极解决方案【信息安全】【Hack】

Jun 06, 2016 pm 08:23 PM
hack php 정보 보안 침입 주입

Update20151202:
感谢大家的关注和回答,目前我从各种方式了解到的防御方法,整理如下:

  1. PHP直接输出html的,可以采用以下的方法进行过滤

    <code>1.htmlspecialchars函数
    2.htmlentities函数
    3.HTMLPurifier.auto.php插件
    4.RemoveXss函数(百度可以查到)</code>
    로그인 후 복사
    로그인 후 복사
  2. PHP输出到JS代码中,或者开发Json API的,则需要前端在JS中进行过滤

    <code>1.尽量使用innerText(IE)和textContent(Firefox),也就是jQuery的text()来输出文本内容
    2.必须要用innerHTML等等函数,则需要做类似php的htmlspecialchars的过滤(参照@eechen的答案)</code>
    로그인 후 복사
    로그인 후 복사
  3. 其它的通用的补充性防御手段

    <code>1.在输出html时,加上Content Security Policy的Http Header
    (作用:可以防止页面被XSS攻击时,嵌入第三方的脚本文件等)
    (缺陷:IE或低版本的浏览器可能不支持)
    2.在设置Cookie时,加上HttpOnly参数
    (作用:可以防止页面被XSS攻击时,Cookie信息被盗取,可兼容至IE6)
    (缺陷:网站本身的JS代码也无法操作Cookie,而且作用有限,只能保证Cookie的安全)
    3.在开发API时,检验请求的Referer参数
    (作用:可以在一定程度上防止CSRF攻击)
    (缺陷:IE或低版本的浏览器中,Referer参数可以被伪造)
    </code>
    로그인 후 복사
    로그인 후 복사

大概就是这些了,大家还有什么别的思路,欢迎补充!

——————————————————————————————————————————————————

原问题如下:

1.PHP如何完美(或者尽可能完美地)防御XSS攻击(比htmlspecialchars更完善的)?
2.我在想是不是防御XSS最好在前端做(毕竟JS在前端解析字符串都有坑啊)?
3.有木有什么解决方案或者思路啊,什么都行?

最近都在研究XSS防御的问题。

毕竟,比如用户注册的API,可能被Hacker利用,强行提交了"<script>alert('注入成功!')</script>"这样的用户名。

然后WEB前端怎么都要有显示用户名的地方吧。。。
于是。。。Boom。。。

直入重点:
我看到很多应对XSS的防御方案都是PHP的htmlentities函数或者htmlspecialchars。
随意百度了下,貌似ThinkPHP3.x默认就是用的htmlspecialchars。
比如:$str = htmlspecialchars($str, ENT_QUOTES);//替换掉&'"这5个字符
但是,只替换掉那几个字符真的够吗?

然后我发现了这个文章:
http://tieba.baidu.com/p/3003719171
使用\u003c\u003e在JS字符串中会被解释成的特性进行XSS攻击。。。
卧槽。。。

然后我想到了JS里的eval等等函数简直是无底洞。。。
然后我发现了这个文章:
http://www.2cto.com/Article/201310/251830.html
使用各种编码,各种手段执行JS,简直丧心病狂。
比如:入侵 - PHP的防御XSS注入的终极解决方案【信息安全】【Hack】

啊!CAO。
我开始怀疑整个世界了。。。
所以,
我的问题是:

1.PHP如何完美(或者尽可能完美地)防御XSS攻击(比htmlspecialchars更完善的)?
2.我在想是不是防御XSS最好在前端做(毕竟JS在前端解析字符串都有坑啊)?
3.有木有什么解决方案或者思路啊,什么都行?

Update20151201:
能不要再复制粘贴答案,or迷信htmlspecialchars是无敌的了好嘛?
\u003cimg src=1 onerror=alert(/xss/)\u003e里的任何一个字符都是不会被htmlspecialchars处理的。
自己看图,对,就是你!

入侵 - PHP的防御XSS注入的终极解决方案【信息安全】【Hack】

回复内容:

Update20151202:
感谢大家的关注和回答,目前我从各种方式了解到的防御方法,整理如下:

  1. PHP直接输出html的,可以采用以下的方法进行过滤

    <code>1.htmlspecialchars函数
    2.htmlentities函数
    3.HTMLPurifier.auto.php插件
    4.RemoveXss函数(百度可以查到)</code>
    로그인 후 복사
    로그인 후 복사
  2. PHP输出到JS代码中,或者开发Json API的,则需要前端在JS中进行过滤

    <code>1.尽量使用innerText(IE)和textContent(Firefox),也就是jQuery的text()来输出文本内容
    2.必须要用innerHTML等等函数,则需要做类似php的htmlspecialchars的过滤(参照@eechen的答案)</code>
    로그인 후 복사
    로그인 후 복사
  3. 其它的通用的补充性防御手段

    <code>1.在输出html时,加上Content Security Policy的Http Header
    (作用:可以防止页面被XSS攻击时,嵌入第三方的脚本文件等)
    (缺陷:IE或低版本的浏览器可能不支持)
    2.在设置Cookie时,加上HttpOnly参数
    (作用:可以防止页面被XSS攻击时,Cookie信息被盗取,可兼容至IE6)
    (缺陷:网站本身的JS代码也无法操作Cookie,而且作用有限,只能保证Cookie的安全)
    3.在开发API时,检验请求的Referer参数
    (作用:可以在一定程度上防止CSRF攻击)
    (缺陷:IE或低版本的浏览器中,Referer参数可以被伪造)
    </code>
    로그인 후 복사
    로그인 후 복사

大概就是这些了,大家还有什么别的思路,欢迎补充!

——————————————————————————————————————————————————

原问题如下:

1.PHP如何完美(或者尽可能完美地)防御XSS攻击(比htmlspecialchars更完善的)?
2.我在想是不是防御XSS最好在前端做(毕竟JS在前端解析字符串都有坑啊)?
3.有木有什么解决方案或者思路啊,什么都行?

最近都在研究XSS防御的问题。

毕竟,比如用户注册的API,可能被Hacker利用,强行提交了"<script>alert('注入成功!')</script>"这样的用户名。

然后WEB前端怎么都要有显示用户名的地方吧。。。
于是。。。Boom。。。

直入重点:
我看到很多应对XSS的防御方案都是PHP的htmlentities函数或者htmlspecialchars。
随意百度了下,貌似ThinkPHP3.x默认就是用的htmlspecialchars。
比如:$str = htmlspecialchars($str, ENT_QUOTES);//替换掉&'"这5个字符
但是,只替换掉那几个字符真的够吗?

然后我发现了这个文章:
http://tieba.baidu.com/p/3003719171
使用\u003c\u003e在JS字符串中会被解释成的特性进行XSS攻击。。。
卧槽。。。

然后我想到了JS里的eval等等函数简直是无底洞。。。
然后我发现了这个文章:
http://www.2cto.com/Article/201310/251830.html
使用各种编码,各种手段执行JS,简直丧心病狂。
比如:入侵 - PHP的防御XSS注入的终极解决方案【信息安全】【Hack】

啊!CAO。
我开始怀疑整个世界了。。。
所以,
我的问题是:

1.PHP如何完美(或者尽可能完美地)防御XSS攻击(比htmlspecialchars更完善的)?
2.我在想是不是防御XSS最好在前端做(毕竟JS在前端解析字符串都有坑啊)?
3.有木有什么解决方案或者思路啊,什么都行?

Update20151201:
能不要再复制粘贴答案,or迷信htmlspecialchars是无敌的了好嘛?
\u003cimg src=1 onerror=alert(/xss/)\u003e里的任何一个字符都是不会被htmlspecialchars处理的。
自己看图,对,就是你!

入侵 - PHP的防御XSS注入的终极解决方案【信息安全】【Hack】

这个问题我们还是先来请教一下砖家……

现在马上为我们连线场外的砖家……

嘟嘟嘟……

砖家您好,请问这位同学的问题您怎么看?

砖家:我趴在窗户上看……

……@#%&*!~~(@$%……

好了,原来砖家是说最近雾霾严重,所以他只能趴在窗户上看这个问题……

现在请听专家解读:

魔亦有道。

有专门的研究这些东西的,任何事只有专业领域的人做才会更有效率。

使用HTMLPurifier才是终极理想。

  1. http://www.xcoder.cn/index.php/archives/971

  2. http://willko.iteye.com/blog/475493

  3. http://www.piaoyi.org/php/HTML-Purifier-PHP-xss.html

  4. http://www.edu.cn/ji_shu_ju_le_bu_1640/20080717/t20080717_310285.shtml

  5. http://www.111cn.net/phper/phpanqn/78018.htm

  6. http://security.ctocio.com.cn/securitycomment/54/8222554.shtml

其实我还想说,我不希望防XSS这种事情交给前端,模板语言来做,对于前端,给她用什么就用什么,用的不爽自己适当的做变量调节就可以了。给她们用,让她们用的爽,用的简单,这是我们好男人的责任和义务,大家说对不对啊,嘻嘻。

首先,我想说,不要用你的无知来挑战大家

这是道高一尺魔高一丈的东西

html中的编码:

<code></code>
로그인 후 복사
로그인 후 복사

javascript中的编码:

<code></code>
로그인 후 복사
로그인 후 복사

当然 htmlspecialchars 肯定是不行的,只能进行简单的处理,要不然还讨论什么xss了

<code>The translations performed are:

'&' (ampersand) becomes '&'
'"' (double quote) becomes '"' when ENT_NOQUOTES is not set.
"'" (single quote) becomes ''' (or ') only when ENT_QUOTES is set.
'</code>
로그인 후 복사

上面代码还可以这样写

<code><div id="a">test</div>
<div id="b">test</div>
<div id="c">test</div>
<a href="javasc&NewLine;ript&colon;alert(/xss/)">click</a> 
<a href="data:text/html;base64,%20PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==">test</a>
<script>
var a="\u003cimg src=1 onerror=alert(/xss/)\u003e";
var b="\74\151\155\147\40\163\162\143\75\170\40\157\156\145\162\162\157\162\75\141\154\145\162\164\50\61\51\76";
var c="\u003c\u0069\u006d\u0067\u0020\u0073\u0072\u0063\u003d\u0031\u0020\u006f\u006e\u0065\u0072\u0072\u006f\u0072\u003d\u0061\u006c\u0065\u0072\u0074\u0028\u002f\u0078\u0073\u0073\u002f\u0029\u003e";
document.getElementById("a").innerHTML=a;
document.getElementById("b").innerHTML=a;
document.getElementById("c").innerHTML=a;
</script></code>
로그인 후 복사

但关键是,你确定你的那些代码可以提交吗?你要确定了再拿出来说

比如最简单的href加入以下代码基本上歇菜了

<code><base href="http://bbs.wdzj.com/"></code>
로그인 후 복사

你到底有没有测试过,就说你提到的那些场景能够绕过htmlspecialchars呀,实践出真知.

<code><?php $nowdoc = <<<'nowdoc'
xss
nowdoc;
header('Content-Type: text/html;charset=utf-8');
echo htmlspecialchars($nowdoc, ENT_QUOTES, 'UTF-8');
</code></code>
로그인 후 복사

补充:
你说的对,毕竟很多时候要把AJAX加载的数据用innerHTML添加到页面.
值得注意的是,innerHTML本质也是输出HTML,
所以我们可以在输出前用JS像PHP的htmlspecialchars那样
把特殊字符(&,",',)替换为HTML实体(&"'<>).
或者干脆直接用innerText(IE)和textContent(Firefox),也就是jQuery的text()来输出文本内容.
StackOverflow上找的两个实现:

<code>function escapeHtml(text) {
    return text
        .replace(/&/g, "&")
        .replace(/, "<")
        .replace(/>/g, ">")
        .replace(/"/g, """)
        .replace(/'/g, "'");
}
function escapeHtml(text) {
    var map = {
        '&': '&',
        '"']/g, function(m) { return map[m]; });
}</code>
로그인 후 복사

方法一,利用php htmlentities函数

php防止XSS跨站脚本攻击的方法:是针对非法的HTML代码包括单双引号等,使用htmlspecialchars()函数 。

在使用htmlspecialchars()函数的时候注意第二个参数, 直接用htmlspecialchars($string) 的话,第二个参数默认是ENT_COMPAT,函数默认只是转化双引号(“), 不对单引号(‘)做转义。

所以,htmlspecialchars函数更多的时候要加上第二个参数, 应该这样用: htmlspecialchars($string,ENT_QUOTES).当然,如果需要不转化如何的引号,用htmlspecialchars($string,ENT_NOQUOTES)。

另外, 尽量少用htmlentities, 在全部英文的时候htmlentities和htmlspecialchars没有区别,都可以达到目的.但是,中文情况下, htmlentities却会转化所有的html代码,连同里面的它无法识别的中文字符也给转化了。

htmlentities和htmlspecialchars这两个函数对 '之类的字符串支持不好,都不能转化, 所以用htmlentities和htmlspecialchars转化的字符串只能防止XSS攻击,不能防止SQL注入攻击.

所有有打印的语句如echo,print等 在打印前都要使用htmlentities() 进行过滤,这样可以防止Xss,注意中文要写出htmlentities($name,ENT_NOQUOTES,GB2312) 。

方法二,给一个函数

<code>function xss_clean($data){
 // Fix &entity\n;
 $data=str_replace(array('&','<','>'),array('&amp;','&lt;','&gt;'),$data);
 $data=preg_replace('/(*\w+)[\x00-\x20]+;/u','$1;',$data);
 $data=preg_replace('/(*[0-9A-F]+);*/iu','$1;',$data);
 $data=html_entity_decode($data,ENT_COMPAT,'UTF-8');
 // Remove any attribute starting with "on" or xmlns
 $data=preg_replace('#(]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu','$1>',$data);
 // Remove javascript: and vbscript: protocols
 $data=preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu','$1=$2nojavascript...',$data);
 $data=preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu','$1=$2novbscript...',$data);
 $data=preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u','$1=$2nomozbinding...',$data);
 // Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
 $data=preg_replace('#(]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i','$1>',$data);
 $data=preg_replace('#(]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i','$1>',$data);
 $data=preg_replace('#(]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu','$1>',$data);
 // Remove namespaced elements (we do not need them)
 $data=preg_replace('#*\w+:\w[^>]*+>#i','',$data);
 // http://www.111cn.net/
 do{// Remove really unwanted tags
  $old_data=$data;
  $data=preg_replace('#*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i','',$data);
 }while($old_data!==$data);
 // we are done...
 return $data;
}</code>
로그인 후 복사

想要“完美”防御XSS,就要每个开发都完全了解XSS的知识,在合适的场景用合适的方案来编码

推荐参考:
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

任何用一个函数/一个库来解决这个问题的努力都是白日做梦。

重新再贴一边:
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

永远不可能完美防御,但至少可以挡住99%(剩下的1%才是最凶猛的~~~),目前的统一做法是,做好输入检查,良好的编程意识,安全转义,借助第三方安全库。不要信任输入。也不要信任输出。

为什么不用 CSP 直接一了百了呢?

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? Feb 07, 2025 am 11:57 AM

이 튜토리얼은 PHP를 사용하여 XML 문서를 효율적으로 처리하는 방법을 보여줍니다. XML (Extensible Markup Language)은 인간의 가독성과 기계 구문 분석을 위해 설계된 다목적 텍스트 기반 마크 업 언어입니다. 일반적으로 데이터 저장 AN에 사용됩니다

이전에 몰랐던 후회되는 PHP 함수 7가지 이전에 몰랐던 후회되는 PHP 함수 7가지 Nov 13, 2024 am 09:42 AM

숙련된 PHP 개발자라면 이미 그런 일을 해왔다는 느낌을 받을 것입니다. 귀하는 상당한 수의 애플리케이션을 개발하고, 수백만 줄의 코드를 디버깅하고, 여러 스크립트를 수정하여 작업을 수행했습니다.

JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. Apr 05, 2025 am 12:04 AM

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

문자열로 모음을 계산하는 PHP 프로그램 문자열로 모음을 계산하는 PHP 프로그램 Feb 07, 2025 pm 12:12 PM

문자열은 문자, 숫자 및 기호를 포함하여 일련의 문자입니다. 이 튜토리얼은 다른 방법을 사용하여 PHP의 주어진 문자열의 모음 수를 계산하는 방법을 배웁니다. 영어의 모음은 A, E, I, O, U이며 대문자 또는 소문자 일 수 있습니다. 모음이란 무엇입니까? 모음은 특정 발음을 나타내는 알파벳 문자입니다. 대문자와 소문자를 포함하여 영어에는 5 개의 모음이 있습니다. a, e, i, o, u 예 1 입력 : String = "Tutorialspoint" 출력 : 6 설명하다 문자열의 "Tutorialspoint"의 모음은 u, o, i, a, o, i입니다. 총 6 개의 위안이 있습니다

PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). Apr 03, 2025 am 12:04 AM

정적 바인딩 (정적 : :)는 PHP에서 늦은 정적 바인딩 (LSB)을 구현하여 클래스를 정의하는 대신 정적 컨텍스트에서 호출 클래스를 참조 할 수 있습니다. 1) 구문 분석 프로세스는 런타임에 수행됩니다. 2) 상속 관계에서 통화 클래스를 찾아보십시오. 3) 성능 오버 헤드를 가져올 수 있습니다.

php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? Apr 03, 2025 am 12:03 AM

PHP의 마법 방법은 무엇입니까? PHP의 마법 방법은 다음과 같습니다. 1. \ _ \ _ Construct, 객체를 초기화하는 데 사용됩니다. 2. \ _ \ _ 파괴, 자원을 정리하는 데 사용됩니다. 3. \ _ \ _ 호출, 존재하지 않는 메소드 호출을 처리하십시오. 4. \ _ \ _ get, 동적 속성 액세스를 구현하십시오. 5. \ _ \ _ Set, 동적 속성 설정을 구현하십시오. 이러한 방법은 특정 상황에서 자동으로 호출되어 코드 유연성과 효율성을 향상시킵니다.

See all articles