JavaScript 없이 CSS 사용자 정의 속성에 신뢰할 수 없는 입력을 안전하게 할당: 가이드
P粉356361722
P粉356361722 2023-09-06 22:32:52
0
1
713

문자열 키와 문자열 값으로 구성된 객체가 있고 이를 서버에서 생성된 HTML에 CSS 사용자 정의 속성으로 쓰고 싶다고 가정해 보겠습니다. 어떻게 하면 안전하게 할 수 있나요?

안전이란 무엇을 의미하나요

  • 가능한 경우 사용자 정의 속성 선언으로 인해 CSS 구문 오류가 발생하지 않아야 하며, 이로 인해 브라우저가 다른 스타일 선언이나 HTML 문서의 일부를 올바르게 구문 분석하지 못하게 됩니다. 어떤 이유로 이것이 가능하지 않은 경우 키-값 쌍을 생략해야 합니다.
  • 더 중요한 것은 이로 인해 크로스 사이트 스크립팅이 불가능해진다는 것입니다.

단순화를 위해 [a-zA-Z0-9_-] 클래스의 문자만 허용하도록 키를 제한하겠습니다.

CSS 사양과 일부 개인 테스트를 읽고 다음 단계에 따라 가치를 얻는 데 많은 진전을 이룰 수 있다고 생각합니다.

  • 문자열 찾기
  • 각 따옴표 뒤에는 동일한 유형(" 또는 ')의 다른(이스케이프 처리되지 않은) 따옴표가 와야 합니다. 그렇지 않은 경우 이 키/값 쌍을 삭제하세요.
  • 문자열 외부의 모든 여는 중괄호 {([字符串外部的 에 일치하는 닫는 중괄호가 있는지 확인하세요. 그렇지 않은 경우 이 키-값 쌍을 삭제합니다.
  • 3C 转义 < 的所有实例,以及使用 3E 转义 >의 모든 인스턴스를 사용하세요.
  • 탈출하려면 3B;의 모든 인스턴스를 사용하세요.

이 CSS 구문 사양을 기반으로 위의 단계를 생각해냈습니다

컨텍스트의 경우 이러한 속성은 다른 곳에 삽입하는 사용자 정의 스타일에서 사용할 수 있지만 동일한 개체가 템플릿의 템플릿 데이터로도 사용되므로 콘텐츠로 의도된 문자열과 CSS 변수로 예상되는 문자열이 혼합되어 포함될 수 있습니다. . 위의 알고리즘은 CSS에서 유용할 수 있는 너무 많은 키-값 쌍을 버릴 위험 없이 매우 단순하다는 균형을 잘 유지하고 있다고 생각합니다. 아무것도 놓치지 마세요


여기에 내가 달성하고 싶은 것을 보여주는 JS 코드가 있습니다. obj 是有问题的对象,而 preprocessPairs는 객체를 가져와서 전처리하여 위 단계에 설명된 대로 값을 제거/재형식화하는 함수입니다.

으아악

이런 물건이 주어지면

으아악

나는 CSS를 다음과 같이 만들고 싶습니다:

으아악

--theme-title은 CSS에서 사용될 때 매우 쓸모없는 맞춤 변수이지만 CSS는 이해하지 못하는 속성을 무시하기 때문에 실제로 스타일시트를 손상시키지 않습니다.

P粉356361722
P粉356361722

모든 응답(1)
P粉898107874

실제로는 특정 언어에 의존하지 않고 정규식과 다른 알고리즘을 사용할 수도 있습니다. 그것이 바로 여러분에게 필요한 것입니다.

객체 키가 내부에 있다고 선언하여 [a-zA-Z0-9_-] 어떻게든 값을 구문 분석해야 합니다.

가치 모델

그래서 우리는 그것을 카테고리로 분류하고 우리가 무엇을 보게 되는지 볼 수 있습니다(명확성을 위해 약간 단순화될 수 있습니다):

  1. '.*'(어포스트로피로 둘러싸인 문자열, 탐욕)
  2. ".*"(큰따옴표로 묶인 문자열, 탐욕)
  3. [+-]?d+(.d+)?(%|[A-z]+)?(정수 및 소수, 선택적 백분율 또는 단위 포함)
  4. #[0-9A-f]{3,6}(색상)
  5. [A-z0-9_-]+ (키워드, 색상 이름 지정, "ease in" 등)
  6. ([w-]+)([^)]+) (类似 url()calc() 기능 > 등)

첫 번째 필터

이러한 패턴을 식별하기 전에 필터링을 수행할 수 있을 것 같습니다. 어쩌면 값 문자열을 먼저 다듬을 수도 있습니다. 언급한 대로 > 可以在 preprocessPairs()는 위에 있는 패턴으로 나타나지 않기 때문에 함수 시작 부분에서 이스케이프됩니다. 이스케이프되지 않은 세미콜론이 어디에도 나타나지 않게 하려면 이를 이스케이프할 수도 있습니다.

인식 패턴

그런 다음 에서 이러한 패턴을 식별할 수 있으며 각 패턴에 대해 다시 필터링을 실행해야 할 수도 있습니다. 이러한 패턴은 일부(또는 두 개의) 공백 문자로 구분될 것으로 예상됩니다.

이스케이프된 줄바꿈인 여러 줄 문자열에 대한 지원을 포함해도 괜찮습니다.

로케일

필터링할 컨텍스트가 HTML과 CSS 두 개 이상 있다는 점을 인식해야 합니다. 元素中包含样式时,输入必须是安全的,同时它必须是有效的 CSS。幸运的是,您没有将 CSS 包含在元素的 style 속성에 있으면 조금 더 쉽습니다.

값 패턴 기반 필터링

  1. 아포스트로피로 둘러싸인 문자열 - 아포스트로피와 세미콜론 외에는 아무 것도 신경 쓰지 않으므로 문자열에서 이러한 문자의 이스케이프되지 않은 인스턴스를 찾아 이스케이프해야 합니다.
  2. 위와 동일합니다. 큰따옴표만 사용하세요
  3. 문제없어요
  4. 문제없어요
  5. 기본적으로 문제 없습니다
  6. 이게 재미있는 부분이에요

그러므로 포인트 1~5는 매우 간단하며 대부분의 값은 앞에서부터 간단한 필터링과 트리밍으로 처리됩니다. 일부 추가 사항(성능에 어떤 영향을 미치는지 알 수 없음)을 사용하면 올바른 단위, 키워드 등에 대해 추가 검사를 수행할 수도 있습니다.

하지만 다른 포인트에 비해 상대적으로 더 큰 난관은 포인트 6인 것 같아요. 이 사용자 정의 스타일에서 url() ,让您检查函数的输入,因此例如您可能想要转义分号,甚至可能通过微小的调整再次检查函数内的模式例如对于calc()를 비활성화하기로 결정할 수도 있습니다.

결론

전반적으로 이것은 내 의견입니다. 이러한 정규식을 몇 가지 조정하면 이미 수행 중인 작업을 보완하고 CSS를 입력할 때 최대한 많은 유연성을 제공하는 동시에 CSS 기능을 조정할 때마다 코드를 조정할 필요가 없게 됩니다.

으아악

댓글, 토론, 비판을 해주시고, 특별히 관심 있는 주제를 언급하는 것을 잊었다면 알려주시기 바랍니다.

출처

면책조항: 저는 아래 언급된 출처의 저자, ​​소유자, 투자자 또는 기여자가 아닙니다. 나는 단지 정보를 얻기 위해 그것들을 사용했습니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿