Сообщаю. была найдена в блочном редакторе XXS уязвимость. У нас работает Wallarm https://wallarm.com/ и мы платим им постоянно за его работу.
Произошла SQL инъекция, и Wallarm ее не заметил.
Злоумышленник смог добавить в свой аккаунт через нее подтвержденные адреса ( и на вашем домене в том числе) и поставить себе большой кредитный лимит, а так же изменил уровень попадания на модерацию до full trust ( то есть мы не проверяем никогда, кроме spam trap адресов ).
В ночь, когда работает только один сотрудник ( так как больше не требуется ) злоумышленник зарегистрировал аккаунт на сервисе esputnik , там разместил html файл с редиректом на сайт vsegdaplus.ru . Потом он зашел в свой аккаунт с не его подтвержденными адресами и включенным огромным кредитным лимитом и малыми партиями всю ночь до утра слал письма, всего ушло 1,9 млн трафика от 5ти разных доменов. Все одной тематики.
Как мы "залатали": уязвимость найдена и закрыта.
В перечне действий по такому ручному внесению адреса в подтвержденные не для staff аккаунтов установлен блокиратор + уведомление аларм на группу админов.
В Wallarm открыт кейс на расследование по инциденту, так как это их работа выявлять и закрывать нас от таких взломов.
Полученные данные по IP адресам взлома, по домену, на котором располагался вредоносный код и который был использован для инъекции, и другие данные - все поданы в юридический отдел для соответствующей подачи заявления в киберполицию.
body * {
transition: all .2s
}
await Promise.all(
items.map(async (item) => {
let doOne = await somethingFn(item);
let doTwo = await somethingFn2(item);
});
);
for (const item of items) {
let doOne = await somethingFn(item);
let doTwo = await somethingFn2(item);
)
class foo {
method1() {
return 'hello' // return вы и сами написали
}
method2() {
let x = this.method1() // а вот результат никуда не присвоили
console.log(x)
}
}
arr = arr.filter(n => n.id !== ID);
arr.splice(arr.findIndex(n => n.id === ID), 1);
const index = arr.findIndex(n => n.id === ID);
if (index !== -1) {
arr.splice(index, 1);
}
function toggleClass(selector, className, delay) {
let index = -1;
return setInterval($items => {
$items.eq(index).removeClass(className);
index = (index + 1) % $items.length;
$items.eq(index).addClass(className);
}, delay, $(selector));
}
const intervalId = toggleClass('.wrap div', 'active', 300);
function toggleClass(selector, className, delay) {
const items = document.querySelectorAll(selector);
let index = ~-items.length;
return items.length
? setInterval(() => {
items[index].classList.remove(className);
index = -~index % items.length;
items[index].classList.add(className);
}, delay)
: null;
}
<div class="block">
<img class="image">
</div>
.block {
position: relative;
overflow: visible;
}
.block .image {
position: absolute;
top: -100px;
right: 200px;
}
<div class="block">
<img class="image">
</div>
.block {
overflow: visible;
}
.block .image {
display: inline-block;
margin-top: -100px;
margin-bottom: -100px;
}
.block .image {
position: absolute;
width: 300px;
top: -100px;
right: 200px;
}
@media (max-width: 800px) {
.block .image {
width: 200px;
top: -50px;
right: 50px;
}
}