Pull to refresh
0
0
Send message

Бывают строки, присваивание создает копию

Нет, присваивание всегда задаёт ссылку на значение. В моём примере новую строку создаёт str.replace, а d = только меняет ссылку у d со строки, на которую также смотрит c, на новую созданную

Что такое "элементарный тип" для питона? Относится ли к таковым, например, int?

Он иммутабельный с точки зрения самого языка. Но, допустим, если сделать расширение booster, которое реализует функцию incr, принимающую PyLongObject* и меняющую напрямую переданное значение, что выведет следующий код?

import booster

a = 100500
b = a

booster.incr(b)
print(a)  # ???
Ответ

Выведет 100501, т.к. в строке b = a идёт присваивание по ссылке. Не важно, какой там тип, присваивание всегда работает одинаково

Сильно упрощённый пример модуля booster (честно, пытался под спойлер засунуть, но судя по предпросмотру, там всё разваливается):

#include <Python.h>
#include "longobject.h"

static PyObject *
booster_incr(PyObject *self, PyObject *arg)
{
	PyLongObject *p = (PyLongObject *)arg;
	p->long_value.ob_digit[0]++;

	Py_RETURN_NONE;
}

static PyMethodDef BoosterMethods[] = {
    {"incr", (PyCFunction)booster_incr, METH_O, "Increment a PyLongObject"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef boostermodule = {
    PyModuleDef_HEAD_INIT,
    "booster",
    "Module that increments PyLongObject",
    -1,
    BoosterMethods
};

PyMODINIT_FUNC
PyInit_booster(void)
{
    return PyModule_Create(&boostermodule);
}

Для некоторых типов присваивание работает вот так, а для некоторых иначе

Оно для всех типов работает одинаково. Другой вопрос, что не у всех типов есть методы, модифицирующие внутреннее состояние, поэтому с некоторыми такого поведения не добиться стандартными способами. Например, для str заменить символ в существующей строке нельзя, можно только создать новое значение и присвоить его:

a = [1, 2, 3]
b = a  # b ссылается на то же значение, что и a

c = 'Hello, world!'
d = c  # d ссылается на то же значение, что и c

b.append(4)  # модифицируем значение, на которое ссылаются и a, и b
print(a)  # [1, 2, 3, 4]
print(b)  # [1, 2, 3, 4]

d = d.replace('world', 'randomsimplenumber')  # создаём новую строку и в d присваиваем ссылку на неё, в c остаётся ссылка какая была
print(c)  # Hello, world!
print(d)  # Hello, randomsimplenumber!

Понять нельзя, нужно запомнить

Понять переменные в питоне не сложнее, чем указатели в сишке. Там значения существуют отдельно, а переменные могут только ссылаться на них. В том числе несколько переменных на одно значение, как в примере выше

Всё верно, я лишь ответил на вопрос про цитату.

Предлагаю сойтись на том, что выше писал @novoselov:

Тут речь уже не про скорость подбора, а про дополнительные факторы защиты

Хотя возможно это я её изначально понял неправильно, т.к. "дополнительные факторы защиты" прочитал как "защита от массового перебора всех слитых хэшей сразу".

Нет, я этого не говорю. Более того, "более подходящие алгоритмы", такие как argon2id, scrypt, bcrypt и PBKDF2, подразумевают использование соли в обязательном порядке. Так что оно не может мешать в принципе.

Мой коммент о том, что одной только соли недостаточно для противодействия перебору.

На примере SHA-1

Без соли:

Hash-Mode 100 (SHA1)
Speed.#1.........: 70245.1 MH/s

Соль после пароля:

Hash-Mode 110 (sha1($pass.$salt))
Speed.#1.........: 69693.4 MH/s

Соль перед паролем:

Hash-Mode 120 (sha1($salt.$pass))
Speed.#1.........: 53587.0 MH/s

Разница есть, но несущественная.

"Разработчики, кто имеет минимальный кругозор", наверняка слышали про рекомендации OWASP и вместо SHA используют более подходящие алгоритмы.

По сравнению с вышеуказанными 6389.5 MH/s для SHA3-512, у того же scrypt 7760 H/s. Обращаю внимание на отсутствие M у значения scrypt.

От pandas довольно легко. Для csv есть одноимённый модуль в стандартной библиотеке. Для xlsx тоже есть различные библиотеки. Т.е. я знаю про само существование pandas, даже какие-то примеры с ним видел, в статьях различных часто встречал, но на практике никогда с ним не работал (у меня питон как правило для веба и скриптов)

Это же вроде ограничение на размер загружаемого файла. Речь о том, что при превышении получим 413 в ответ.

Как 5 получить?

Вариант 1 — затолкать в качестве комментариев собрание произведений Льва Толстого (насколько знаю, количество COM в JPEG не ограничено)

Вариант 2 — rarjpg

Для начала, не надо юлить. Жду ответа на свой вопрос: в чём Питон, Руби, Нода с жсом и АСП с шарпом «на десять лет отставали от пыхи в осознании SQL инъекций, XSS и прочих тонкостей»?

Просто интересно, как безопасность этого элемента реализуется в django? Там по умолчанию уродуется строка, путём отрывания у неё javascript: спереди?

Если говорить именно о href, то в проектах на джанге не припомню, чтобы в подобных случаях туда могли дойти данные с javascript: в начале.

Стандартный способ получения данных подразумевает использование URLValidator. Как правило, не напрямую, а в models.URLField, forms.URLField, serializers.URLField у DRF и т.п. Он по умолчанию пропускает только ссылки со схемами http, https, ftp и ftps.

Вне шаблонов такие ссылки могут формироваться в админке. Например, в последнем проекте на джанге, над которым работал, есть такой код (почистил от лишнего):

models.py

from django.conf import settings
from django.db.models import Model, URLField, SlugField

class RedirectLink(Model):
    slug = SlugField(verbose_name='Слаг', unique=True)
    url = URLField(verbose_name='URL')

    def get_absolute_url(self):
        return f'https://{settings.PUBLIC_HOST}/redirect/{self.slug}'

admin.py

import html
from django.contrib import admin
from django.utils.safestring import mark_safe
from t0links.models import RedirectLink

@admin.register(RedirectLink)
class RedirectLinkAdmin(admin.ModelAdmin):
    list_display = ['id', 'slug', 'url_link', 'copy_link']

    @admin.display(description='URL', ordering='url')
    def url_link(self, obj: RedirectLink):
        if obj.url:
            url = html.escape(obj.url)
            return mark_safe(f'<a href="{url}" target="_blank">🗗 {url}</a>')

    @admin.display(description='Ссылка', ordering='slug')
    def copy_link(self, obj: RedirectLink):
        if obj.slug:
            url = html.escape(obj.get_absolute_url())
            return mark_safe(f'''
                <button type="button" class="button" title="Скопировать с буфер обмена" style="line-height: 14px; width: 24px;" data-text="{url}"
                    onclick="navigator.clipboard.writeText(this.dataset.text);this.innerHTML='&nbsp;✓&nbsp;';setTimeout(() => this.innerHTML='&nbsp;⎘&nbsp;', 500);"
                >&nbsp;⎘&nbsp;</button>&nbsp;&nbsp;<a href="{url}" target="_blank">{url}</a>
            ''')

Тут данные для href формируются двумя способами - получение от пользователя (поле URLField, которое ссылку на javascript: просто не пропустит) и генерация (которая тоже никак не начнёт с неё начинаться). Пробежался по всем проектам, для которых у меня ещё остались исходники, везде только эти 2 случая.

При этом https://site.ru/#"tom's_dinner" спокойно проходит и сохраняется, поэтому перед выводом в html нужно экранировать. В python3 можно использовать html.escape из стандартной библиотеки, либо использовать одну из функций django.

Также в джанге значения из кода как правило по умолчанию экранируются, поэтому строку с html нужно явно обернуть в mark_safe.

Если так триггерит href, могу поменять пример на такой:

$albumNameRaw = "Tom's dinner onload='alert(`XSS!`)";
$albumName = htmlspecialchars($albumNameRaw);
$thumb = "<img src='$thumbURL' alt='Превью альбома $albumName'>"; // в php ниже 8.1: "<img src='/path/to/preview.webp' alt='Превью альбома Tom's dinner onload='alert(`XSS!`)'>"

Не надо кликушествовать

И не собирался.

Нигде там не написано, что это "рекомендация".

Верно, равно как и не написано, что это bad practice. Я просто больше не нашёл, в чём ещё разница в "осознании SQL-инъекций" между php и остальным миром.

Все эти языки/платформы, так же как и пыха, ГОДАМИ нарабатывали навыки работы с веб

Тут полностью согласен

правда, на десять лет оставая от пыхи в осознании SQL инъекций, XSS и прочих тонкостей

А вот тут можно тут поподробнее?

Мой путь в вебе протекал через php/yii и js, затем python/django плюс эпизодически другие фреймворки для питона, нода (js и ts) и го, теперь снова в основном php, но symfony, плюс эпизодически питон, го и ts.

И мой опыт говорит о прямо противоположном. Львиная доля попадавшихся мне XSS приходится на php-проекты. Это либо напрямую вывод данных от пользователя в представлении yii (там шаблонизатор по умолчанию — сам php), либо код вида:

$url = htmlspecialchars($unsafe);
$link = "<a href='$url'>Link</a>";

в php ниже 8.1 (который вышел в 2021 году). У остальных же, "отстающих в осознании", стандарт де-факто — использование шаблонизаторов, в которых экранирование включено по умолчанию, и для появления XSS нужно делать дополнительные телодвижения.

С SQL инъекциями тоже интересно. Если отойти от мира ORM, то только в php я видел в документации рекомендации пихать внешние данные прямо в строку запроса, "экранировать только не забывай правильно". А кто забудет, получит уязвимость. У остальных стандартная практика — биндинги.

По "прочим тонкостям". Из указанного списка только в php возможна ситуация, когда при кривой настройке сервера пользователь может через форму на сайте залить файл скрипта (shell, adminer и т.п.) в какую-нибудь директорию upload и выполнить его, просто запросив /upload/adminer.php.

В общем, по моим наблюдениям, это именно с пыхой нужно специально сильно пыхтеть для обеспечения мало-мальской безопасности.

Вот уж где-где, а с камерами - это не врите

ipu6 передаёт привет. В ядре 6.10 какие-то драйвера для них добавили, но моя OVTI02C1 туда не попала. Распознаётся, что есть, но данные с неё не идут

Со встроенными динамиками похожая ситуация - они определяются, всё выглядит рабочим, но звука от них нет

Samsung Book4 и debian trixie. В bookworm также wi-fi и тачпад не завелись (примечательно, что тачскрин работал)

Information

Rating
Does not participate
Registered
Activity

Specialization

Бэкенд разработчик, Фулстек разработчик